- Вопрос или проблема
- ffmpeg пример
- Расширенные опции
- Пример ImageMagick convert
- Установка частоты кадров
- Linux/Unix/macOS
- macOS
- Команды ffmpeg:
- Создание простой функции псевдонима
- Как добавить запись контекстного меню “правый клик” в Windows 7/10, чтобы конвертировать ваш видео файл в gif
- Простая функция Bash
- Использование
- Ответ или решение
- Шаги для конвертации видео в GIF при помощи ffmpeg
- Простой метод с использованием двух команд
- Оптимизированный метод с использованием одного вызова
- Объяснение параметров
- Дополнительные параметры для улучшения качества
- Пример скрипта для автоматизации
- Заключение
Вопрос или проблема
Я конвертирую видео в GIF файл с помощью ffmpeg
:
ffmpeg \
-i input.flv \
-ss 00:00:00.000 \
-pix_fmt rgb24 \
-r 10 \
-s 320x240 \
-t 00:00:10.000 \
output.gif
Все работает отлично, но выходной gif файл имеет очень низкое качество.
Есть идеи, как я могу улучшить качество конвертированного gif?
ffmpeg
пример
ffmpeg
может выводить GIF высокого качества. Перед тем, как начать, всегда рекомендуется использовать последнюю версию: скачать или собрать.
ffmpeg -ss 30 -t 3 -i input.mp4 \
-vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
-loop 0 output.gif
- Этот пример пропустит первые 30 секунд (
-ss 30
) входного файла и создаст выходной файл длиной 3 секунды (-t 3
). - фильтр fps устанавливает частоту кадров. В примере используется скорость 10 кадров в секунду.
- фильтр scale изменит размер выходного файла до 320 пикселей в ширину и автоматически определит высоту, сохраняя соотношение сторон. В этом примере используется алгоритм масштабирования lanczos scaling algorithm.
- palettegen и paletteuse фильтры сгенерируют и используют пользовательскую палитру, созданную из вашего входного файла. У этих фильтров много опций, так что обратитесь к ссылкам для получения списка всех доступных опций и значений. Также смотрите раздел Расширенные опции ниже.
- фильтр split позволит сделать все в одной команде и избегает необходимости создавать временный PNG файл палитры.
- Управляйте зацикливанием с помощью опции
-loop
, но значения могут быть запутанными. Значение0
означает бесконечное зацикливание,-1
означает отсутствие зацикливания, а1
обратно зациклит один раз, что означает, что он будет воспроизводиться дважды. Поэтому значение 10 приведет к воспроизведению GIF 11 раз.
Расширенные опции
Фильтры palettegen и paletteuse имеют много дополнительных опций. Наиболее важные из них:
-
stats_mode
(palettegen). Вы можете заставить фильтры сосредоточить палитру на общем изображении (full
, что является значением по умолчанию), только на подвижных частях (diff
) или на каждом отдельном кадре (single
). Например, чтобы сгенерировать палитру для каждого отдельного кадра, используйтеpalettegen=stats_mode=single
&paletteuse=new=1
. -
dither
(paletteuse). Выберите алгоритм дотеризации. Есть три основных типа: детерминированный (bayer
), диффузия ошибок (все остальные, включая значение по умолчаниюsierra2_4a
) и без дотеризации. Ваш GIF может выглядеть лучше, используя определенный алгоритм дотеризации или вообще без дотеризации. Если вы хотите попробоватьbayer
, обязательно протестируйте и опциюbayer_scale
.
Смотрите Высококачественный GIF с FFmpeg для объяснений, примеры изображений и более подробной информации для продвинутого использования.
Также смотрите документацию palettegen и paletteuse для всех доступных опций и значений.
Пример ImageMagick convert
Другой способ командной строки – это передать данные из ffmpeg
в convert
(или magick
) из ImageMagick.
ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos" -c:v pam \
-f image2pipe - | \
convert -delay 10 - -loop 0 -layers optimize output.gif
Опции ffmpeg
:
-
-vf "fps=10,scale=320:-1:flags=lanczos"
это filtergraph, использующий fps и scale фильтры. fps устанавливает частоту кадров в 10, а scale устанавливает размер на 320 пикселей вширь, высота автоматически определяется и использует значение, которое сохраняет соотношение сторон. В этом примере используется алгоритм масштабирования lanczos scaling algorithm. -
-c:v pam
выбирает кодировщик изображений pam. В примере выводится формат изображения PAM (Portable AnyMap), который является простым, безвредным RGB форматом, поддерживающим прозрачность (alpha) и поддерживаемымconvert
. Он быстрее для кодирования, чем PNG. -
-f image2pipe
выбирает мультиплексор image2pipe, потому что при выводе в системный каналffmpeg
должен сообщить, какой мультиплексор использовать.
Опции convert
:
-
-delay
См. раздел Установка частоты кадров ниже. -
-loop 0
создает бесконечный цикл. -
-layers optimize
включит общий оптимизатор GIF. См. Оптимизация анимаций ImageMagick для получения более подробной информации. Не гарантируется, что он создаст меньший выходной файл, поэтому стоит попробовать и без-layers optimize
и сравнить результаты.
Установка частоты кадров
Установите частоту кадров с помощью комбинации фильтра fps в ffmpeg
и -delay
в convert
. Это может быть сложно, потому что convert
просто получает необработанный поток изображений, поэтому никакая частота кадров не сохраняется. Во-вторых, значение -delay
в convert
выражается в тика (в одном секунде 100 тиков), а не в кадрах в секунду. Например, с fps=12.5
= 100/12.5 = 8 = -delay 8
.
convert
округляет значение -delay
до целого числа, поэтому 8.4 дает 8, а 8.5 дает 9. Это фактически означает, что поддерживается только несколько частот кадров, когда устанавливается унифицированная задержка для всех кадров (можно установить конкретную задержку для каждого кадра, но это выходит за рамки данного ответа).
-delay
игнорируется, если используется как выходная опция, поэтому он должен использоваться перед -
, как показано в примере.
Наконец, браузеры и просмотрщики изображений могут реализовать минимальную задержку, поэтому ваша -delay
также может быть проигнорирована.
Видео предоставлено Службой рыбы и дикой природы США, Национальный тренировочный центр сохранения.
Если вы бы предпочли избежать промежуточных файлов изображений, команды, предоставленные LordNeckBeard, могут быть переданы между ffmpeg
и convert
от ImageMagick, так что промежуточные файлы не потребуются:
ffmpeg -i input.flv -vf scale=320:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 10 -loop 0 - output.gif
Опция -f image2pipe
говорит ffmpeg разбивать видео на изображения и делать его подходящим для потоковой передачи данных, а -vcodec ppm
указывает выходной формат как ppm (по какой-то причине, если формат png, либо convert
не читает все изображения из канала, либо ffmpeg не выводит их все). Знак -
в обеих командах указывает, что будет использован канал для вывода и ввода соответственно.
Чтобы оптимизировать результат без сохранения файла, вы можете передать выходные данные из convert
во вторую команду convert
:
ffmpeg -i input.flv -vf scale=320:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 10 -loop 0 - gif:- | convert -layers Optimize - output.gif
Знак gif:-
говорит convert
, чтобы передать свои выходные данные как данные формата gif, а -layers Optimize
указывает второй convert
, чтобы выполнить методы optimize-frame
и optimize-transparancy
(см. Введение в оптимизацию анимации). Обратите внимание, что выходные данные от -layers Optimize
могут не всегда обеспечивать меньший размер файла, поэтому вы можете сначала попробовать конвертировать в gif без оптимизации, чтобы быть уверенным.
Имейте в виду, что в течение всего этого процесса все находится в памяти, поэтому вам может понадобиться достаточно памяти, если изображения достаточно большие.
Начиная с версии ffmpeg 2.6, мы можем даже добиться лучших результатов. Основываясь на Высококачественный GIF с FFmpeg:
palette="/tmp/palette.png"
filters="fps=15,scale=320:-1:flags=lanczos"
ffmpeg -i input.flv -vf "$filters,palettegen" -y $palette
ffmpeg -i input.flv -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y output.gif
Ответ @Stephane очень хороший. Но он получит предупреждение, например Buffer queue overflow, dropping.
для некоторых видео, и сгенерированный gif
имеет некоторые пропущенные кадры.
Вот улучшенная версия с fifo
фильтром, чтобы избежать Buffer queue overflow
при использовании фильтра paletteuse
. Использует фильтр split
, чтобы избежать создания промежуточного файла палитры PNG.
ffmpeg -i input.mp4 -filter_complex 'fps=10,scale=320:-1:flags=lanczos,split [o1] [o2];[o1] palettegen [p]; [o2] fifo [o3];[o3] [p] paletteuse' out.gif
Я сделал свою версию этого скрипта, который параметризует разрешение выхода и частоту кадров.
Запуск ./gifenc.sh input.mov output.gif 720 10
создаст GIF шириной 720p и 10 fps из фильма, который вы предоставили. Возможно, вам нужно выполнить chmod +x gifenc.sh
для файла.
#!/bin/sh
palette="/tmp/palette.png"
filters="fps=$4,scale=$3:-1:flags=lanczos"
ffmpeg -v warning -i "$1" -vf "$filters,palettegen" -y "$palette"
ffmpeg -v warning -i "$1" -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y "$2"
Вы можете прочитать детали на моем Github
Предположения: ffmpeg установлен,
и скрипт находится в той же папке, что и другие файлы.
Linux/Unix/macOS
Следуя @LordNeckbeard подходу с командой ffmpeg
, пожалуйста, найдите полезную Bash функцию, которую можно добавить в ваш файл ~/.bash_profile
:
# Конвертировать видео в gif файл.
# Использование: video2gif video_file (масштаб) (fps)
video2gif() {
ffmpeg -y -i "${1}" -vf fps=${3:-10},scale=${2:-320}:-1:flags=lanczos,palettegen "${1}.png"
ffmpeg -i "${1}" -i "${1}.png" -filter_complex "fps=${3:-10},scale=${2:-320}:-1:flags=lanczos[x];[x][1:v]paletteuse" "${1}".gif
rm "${1}.png"
}
После того, как функция загружена (вручную или с помощью . ~/.bash_profile
), у вас будет новая команда video2gif
.
Пример использования:
video2gif input.flv
или:
video2gif input.flv 320 10
Масштабировать до 320 в ширину с 10 кадрами в секунду.
Вы также можете указать другой видеоформат (например, mp4).
macOS
Вы можете попробовать приложение GIF Brewery, которое может создавать GIF из видео файлов.
Кроме того, есть несколько веб-сайтов, которые делают конвертацию онлайн бесплатно.
Выбранный ответ предполагает, что вы хотите изменить масштаб исходного видео и изменить его fps в полученном gif. Если вам не нужно это делать, следующая команда работает:
src="https://superuser.com/questions/556029/input.flv"
dest="output.gif"
palette="/tmp/palette.png"
ffmpeg -i $src -vf palettegen -y $palette
ffmpeg -i $src -i $palette -lavfi paletteuse -y $dest
Это было полезно, когда я хотел gif, который точно воспроизводит исходное видео, которое я использовал.
Метод ffmpeg
с палитрой можно выполнить в одной команде, без промежуточного .png
файла.
ffmpeg -y -ss 30 -t 3 -i input.flv -filter_complex \
"fps=10,scale=320:-1:flags=lanczos[x];[x]split[x1][x2]; \
[x1]palettegen[p];[x2][p]paletteuse" output.gif
Это сделано благодаря фильтру split
.
я создал скрипт, протестировал и он работает.
использование:
./avi2gif.sh ./vokoscreen-2015-05-28_12-41-56.avi
ПОЛУЧИТЕ УДОВОЛЬСТВИЕ 🙂
vim avi2gif.sh
#!/bin/sh
INPUT=$1
# настройки по умолчанию, измените если хотите.
START_AT_SECOND=0; # в секундах, если хотите пропустить первые 30 секунд, поставьте 30 здесь
LENGTH_OF_GIF_VIDEO=9999999; # в секундах, как долго должна быть анимация gif
echo "Генерация палитры:"
ffmpeg -y -ss $START_AT_SECOND -t $LENGTH_OF_GIF_VIDEO -i $INPUT -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
echo "Вывод GIF, используя палитру:"
ffmpeg -ss $START_AT_SECOND -t $LENGTH_OF_GIF_VIDEO -i $INPUT -i palette.png -filter_complex "fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" $INPUT.gif
кстати: vokoscreen это ОТЛИЧНЫЙ инструмент для захвата экрана для Linux 🙂
ОГРОМНОЕ СПАСИБО Михаилу Кохаупту 🙂 Успехов.
некоторые статистические данные о размере файлов:
5.3M = vokoscreen-2015-04-28_15-43-17.avi
->
vokoscreen-2015-05-28_12-41-56.avi.gif = 1013K
Для пользователей Windows: создайте файл \Windows\video2gif.bat
с этим содержимым:
@echo off
set arg1=%1
set arg2=%arg1:~0,-4%
ffmpeg -y -i %arg1% -vf fps=10,scale=-1:-1:flags=lanczos,palettegen %TEMP%\palette.png
ffmpeg -i %arg1% -i %TEMP%\palette.png -filter_complex "fps=10,scale=-1:-1:flags=lanczos[x];[x][1:v]paletteuse" %arg2%.gif
del /f %TEMP%\palette.png
И затем вы можете использовать это где угодно вот так:
video2gif myvideo.mp4
Тогда у вас будет myvideo.gif
рядом с вашим исходным входным файлом. Если myvideo.gif
уже существует, вам будет предложено его перезаписать.
Я предлагаю использовать этот универсальный пакетный скрипт.
Команды ffmpeg:
-
Запустите эту команду, чтобы ffmpeg мог вычислить хорошую палитру:
ffmpeg -y -i foo.mp4 -vf fps=30,scale=320:-1:flags=lanczos,palettegen palette.png
-
Запустите эту команду, чтобы конвертировать mp4 файл в gif:
ffmpeg -y -i foo.mp4 -i palette.png -filter_complex "fps=30,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" foo.gif
Возможно, вам стоит настроить fps и scale. Меньший размер каждого приведет к лучшему размеру файла.
Создание простой функции псевдонима
Вы также можете создать функцию псевдонима следующим образом. Я добавил это в свой .bashrc
или .bash_profile
:
function makegif {
ffmpeg -y -i $1 -vf fps=30,scale=320:-1:flags=lanczos,palettegen palette.png
ffmpeg -y -i $1 -i palette.png -filter_complex "fps=30,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" $1.gif
}
И затем просто makegif foo
Примечание: Вам, конечно, потребуется ffmpeg. Получить его можно здесь https://www.ffmpeg.org/download.html или brew install ffmpeg
Как добавить запись контекстного меню “правый клик” в Windows 7/10, чтобы конвертировать ваш видео файл в gif
Некоторые другие ответы упоминали скрипт video2gif, который я использовал. Но вы можете использовать любой скрипт.
Чтобы создать опцию контекстного меню, вам нужно отредактировать реестр. Откройте командную строку PowerShell с правами администратора. Выполните следующие команды:
$key = "Registry::HKEY_CLASSES_ROOT\`*\shell\Run Video2Gif"
New-Item -Path $key"\Command" -Value "C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin\video2gif.bat `"%1`"" -Force
Теперь, когда вы щелкнете правой кнопкой мыши на файле, у вас будет опция “Запуск Video2Gif”!
кстати, я установил ffmpeg в C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\
и поместил скрипт video2gif.bat
в директорию bin рядом с ffmpeg.exe
. Я также добавил C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin
в мой PATH
Windows, но я не думаю, что это обязательно.
Если вы хотите иметь возможность передавать дополнительные флаги / аргументы командной строки в скрипт, создайте новый файл с именем video2gif-prompt.bat
и дайте реестру ссылаться на него вместо video2gif.bat
:
@echo off
set /p inp=Введите дополнительные аргументы, если хотите:
C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin\video2gif.bat %* %inp%
Вы все равно можете просто нажать Enter, чтобы быстро получить значения по умолчанию.
Ниже приведен пакетный файл для пользователей Windows:
gifenc.bat:
set start_time=0
set duration=60
set palette="c:\temp\palette.png"
set filters="fps=15,scale=-1:-1:flags=lanczos"
ffmpeg -v warning -ss %start_time% -t %duration% -i %1 -vf "%filters%,palettegen" -y %palette%
ffmpeg -v warning -ss %start_time% -t %duration% -i %1 -i %palette% -lavfi "%filters% [x]; [x][1:v] paletteuse" -y %2
Источник: Высококачественный GIF с FFmpeg: Извлечение только примера
Если вам нужно всего лишь одно входное переменное значение и вы хотите, чтобы имя вывода имело только расширение GIF (произносится как JIF), то используйте это:
set start_time=0
set duration=60
set palette="c:\temp\palette.png"
set filters="fps=15,scale=-1:-1:flags=lanczos"
ffmpeg -v warning -ss %start_time% -t %duration% -i %1 -vf "%filters%,palettegen" -y %palette%
set var1=%1
set var2=%var1:~0,-4%
ffmpeg -v warning -ss %start_time% -t %duration% -i %1 -i %palette% -lavfi "%filters% [x]; [x][1:v] paletteuse" -y %var2%.gif
ImageMagick может сделать это просто:
convert in.mp4 out.gif
Мой простой трюк для конвертации в GIF – это фильтр NLmeans HandBrake/ffmpeg. В HandBrake просто отметьте опции NLMeans в вкладке конфигурации видео.
Это сглаживает грубое изображение GIF, делая его более сжимаемым. Выход выглядит лучше И имеет меньший размер.
Вы можете сделать:
ffmpeg -i input.mp4 output.gif
Простая функция Bash
Моя наиболее часто используемая командная оболочка в настоящее время
Использование
makeGif inputVideo.mp4
#DESC создать высококачественный gif из видео (особенно .mp4 или .mov)
makeGif () {
if [ -z "$1" ]
then
echo "makeGif inputVideo [outputGif]"
return 244
fi
vid="$1"
if [ -z "$2" ]
then
# удалить расширение
outputVideo="${vid%.*}.gif"
else
outputVideo="$2"
fi
ffmpeg -i "$vid" -vf "scale=1920:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=256[p];[s1][p]paletteuse=dither=floyd_steinberg" -loop 0 "$outputVideo"
echo "GIF создан: $outputVideo"
}
Используя немного ответов каждого, вот bash скрипт с параметрами и только одной командой ffmpeg:
#!/bin/bash
# Значения по умолчанию
fps=15
scale=720
# Функция для отображения usage
usage() {
echo "Использование: $0 [--fps <fps_value>] [--scale <scale_value>] <input_video.mp4>"
echo " --fps: Возможный. Установите кадры в секунду (по умолчанию: 15)"
echo " --scale: Возможный. Установите ширину вывода в пикселях (по умолчанию: 720)"
exit 1
}
# Парсинг опциональных аргументов
while [[ "$#" -gt 0 ]]; do
case "$1" in
--fps)
fps="$2"
shift 2
;;
--scale)
scale="$2"
shift 2
;;
-*)
echo "Неизвестный параметр: $1"
usage
;;
*)
input_video="$1"
shift
;;
esac
done
# Проверьте, была ли предоставлена входная часть и оканчивается ли она на .mp4
if [[ -z "$input_video" || ! "$input_video" =~ \.mp4$ ]]; then
echo "Ошибка: файл ввода должен быть указан и иметь расширение .mp4"
usage
fi
# Имя выходного GIF файла
output_gif="${input_video%.mp4}.gif"
# Создаем GIF в одной команде с использованием split для палитры
echo "Создание GIF с fps=$fps и scale=$scale"
ffmpeg -i "$input_video" -vf "fps=$fps,scale=${scale}:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" "$output_gif"
echo "Конвертация завершена: $output_gif (fps=$fps, scale=$scale)"
Пример использования:
mp4togif --fps 10 --scale 720 myvideo.mp4
–fps: Возможный. Установите кадры в секунду (по умолчанию: 15)
–scale: Возможный. Установите ширину вывода в пикселях (по умолчанию: 720)
Ответ или решение
Для конвертации видео в GIF с помощью ffmpeg с высоким качеством, существует несколько методов, оптимизирующих конечный результат. Основная цель состоит в том, чтобы минимизировать потери качества при преобразовании, и в этом помогут фильтры для генерации палитры.
Шаги для конвертации видео в GIF при помощи ffmpeg
-
Подготовка: Убедитесь, что у вас установлена последняя версия ffmpeg. Это важно, так как в новых версиях исправлены ошибки и улучшены алгоритмы.
-
Формат команд: Используем команду, которая включает фильтры для генерации палитры и применения её к выходному GIF.
Простой метод с использованием двух команд
Создайте палитру и примените её к видео. Например, если у вас есть файл input.mp4
, вы можете использовать следующие команды:
# Генерация палитры
ffmpeg -i input.mp4 -vf "fps=15,scale=320:-1:flags=lanczos,palettegen" -y palette.png
# Применение палитры для создания GIF
ffmpeg -i input.mp4 -i palette.png -lavfi "fps=15,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif
Оптимизированный метод с использованием одного вызова
Вы также можете подсоединить оба процесса в одну команду, чтобы избежать создания временных файлов:
ffmpeg -i input.mp4 -filter_complex "fps=15,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -y output.gif
Объяснение параметров
- fps=15: Устанавливает частоту кадров GIF в 15 кадров в секунду. Вы можете увеличить это значение для более плавного GIF, но и размер файла вырастет.
- scale=320:-1: Устанавливает ширину в 320 пикселей, а высоту автоматически. Это позволяет сохранить соотношение сторон.
- flags=lanczos: Указывает, что следует использовать метод Lanczos для изменения размера изображения. Этот алгоритм обеспечивает повышенное качество при интерполяции.
- palettegen и paletteuse: Создают и используют палитру, что улучшает качество по сравнению с использованием стандартных параметров.
Дополнительные параметры для улучшения качества
- Вы можете регулировать количество цветов в палитре с помощью параметра
max_colors=256
(по умолчанию стоит 256), чем меньше цветов — тем меньше размер файла, но это может снизить качество. - Используйте алгоритмы дибинга при применении палитры, например,
dither=floyd_steinberg
, чтобы улучшить визуальное восприятие GIF.
Пример скрипта для автоматизации
Вы также можете создать Bash-скрипт для более удобного использования:
#!/bin/bash
input=$1
output="${input%.*}.gif"
ffmpeg -i "$input" -vf "fps=15,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" "$output"
echo "GIF создан: $output"
Сохраните этот код как convert_to_gif.sh
, дайте ему права на выполнение и запускайте, указывая имя видео в качестве аргумента.
Заключение
Используя метод генерации палитры, вы сможете создать GIF с высоким качеством без значительных потерь. Экспериментируйте с настройками частоты кадров и разрешения для достижения наилучших результатов. Не забывайте, что размер конечного файла будет зависеть от выбранных вами параметров, так что выбирайте с умом.