Как мне конвертировать видео в GIF с использованием ffmpeg с приемлемым качеством?
Я конвертирую FLV фильм в 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 -i input.flv -ss 00:00:00.000 -pix_fmt rgb24 -r 10 -s 320x240 -t 00:00:10.000 output.gif
ffmpeg version 0.8.5-6:0.8.5-0ubuntu0.12.10.1, Copyright (c) 2000-2012 the Libav developers
built on Jan 24 2013 14:52:53 with gcc 4.7.2
*** THIS PROGRAM IS DEPRECATED ***
This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.flv':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
creation_time : 2013-02-14 04:00:07
Duration: 00:00:18.85, start: 0.000000, bitrate: 3098 kb/s
Stream #0.0(und): Video: h264 (High), yuv420p, 1280x720, 2905 kb/s, 25 fps, 25 tbr, 50 tbn, 50 tbc
Metadata:
creation_time : 1970-01-01 00:00:00
Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16, 192 kb/s
Metadata:
creation_time : 2013-02-14 04:00:07
[buffer @ 0x92a8ea0] w:1280 h:720 pixfmt:yuv420p
[scale @ 0x9215100] w:1280 h:720 fmt:yuv420p -> w:320 h:240 fmt:rgb24 flags:0x4
Output #0, gif, to 'output.gif':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
creation_time : 2013-02-14 04:00:07
encoder : Lavf53.21.1
Stream #0.0(und): Video: rawvideo, rgb24, 320x240, q=2-31, 200 kb/s, 90k tbn, 10 tbc
Metadata:
creation_time : 1970-01-01 00:00:00
Stream mapping:
Stream #0.0 -> #0.0
Press ctrl-c to stop encoding
frame= 101 fps= 32 q=0.0 Lsize= 8686kB time=10.10 bitrate=7045.0kbits/s dup=0 drop=149
video:22725kB audio:0kB global headers:0kB muxing overhead -61.778676%
Благодарю.
15 ответов
ffmpeg Теперь можно выводить более качественный GIF. Если вы используете более старую сборку, рассмотрите возможность загрузки последней статической сборки или компиляции ffmpeg,
ffmpeg пример

203K
Этот пример пропустит первые 30 секунд ввода и создаст 3 секунды вывода. Он масштабирует выходные данные до 320 пикселей в ширину и автоматически определяет высоту, сохраняя соотношение сторон. palettegen а также paletteuse фильтры будут генерировать и использовать пользовательскую палитру, созданную из вашего источника.
Создайте палитру:
ffmpeg -y -ss 30 -t 3 -i input.flv \ -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.pngВыведите GIF, используя палитру:
ffmpeg -ss 30 -t 3 -i input.flv -i palette.png -filter_complex \ "fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif
Посмотрите Высокое качество GIF с FFmpeg для многих других примеров и опций.
convert пример
Другой метод командной строки - экспортировать фильм в кадры, используя ffmpeg затем сделайте GIF с convert из ImageMagick (или GraphicsMagick).

246k
Экспорт кадров:
mkdir frames ffmpeg -i input -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.pngТогда используйте
convert(или жеgm convertесли вы предпочитаете GraphicsMagick), чтобы сделать анимированный GIF:convert -loop 0 frames/ffout*.png output.gif
С convert Вы можете контролировать задержку между кадрами с -delay при желании
Если вы предпочитаете избегать промежуточных файлов изображений, команды, предоставляемые LordNeckBeard, могут передаваться между ffmpeg и ImageMagick's convert так что никаких промежуточных файлов не требуется:
ffmpeg -i input.flv -vf scale=320:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 5 -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 5 -loop 0 - gif:- | convert -layers Optimize - output.gif
gif:- говорит convert передать свой вывод в виде данных в формате GIF и -layers Optimize говорит второй convert выполнять optimize-frame а также optimize-transparancy методы (см. Введение в ImageMagick по оптимизации анимации). Обратите внимание, что выход из -layers Optimize может не всегда обеспечивать меньший размер файла, поэтому вы можете попробовать сначала преобразовать его в gif без оптимизации, чтобы быть уверенным.
Помните, что в течение всего этого процесса все находится в памяти, поэтому вам может понадобиться достаточно памяти, если изображения достаточно велики.
Начиная с ffmpeg 2.6, мы можем сделать еще лучше:
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 будет выводить 720p шириной 10 GPS GIF из фильма, который вы дали. Возможно, вам придется сделать 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 файл:
# Convert video to gif file.
# Usage: video2gif video_file (scale) (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="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
Это пригодилось, когда я хотел подарить подарок, который точно воссоздает исходное видео, которое я использовал.
ffmpeg с помощью метода palette можно запустить в одной команде, без посредников .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
# default settings, modify if you want.
START_AT_SECOND=0; # in seconds, if you want to skip the first 30 seconds put 30 here
LENGTH_OF_GIF_VIDEO=9999999; # in seconds, how long the gif animation should be
echo "Generate a palette:"
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 "Output the GIF using the palette:"
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:
Создайте video2gif.bat файл в каталоге Windows с этим содержанием:
@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 существует, вопрос от вас, чтобы перезаписать его.
РЕДАКТИРОВАТЬ:
Я предлагаю использовать этот пакетный скрипт: https://github.com/NabiKAZ/video2gif
Команды 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
Возможно, вы захотите настроить частоту кадров и масштаб. Чем меньше размер, тем лучше размер файла.
Создание простой функции псевдонима
Вы также можете создать подобную функцию псевдонима. Я добавил это в свой
.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, запустив w / admin privs. Выполните эти команды:
$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 Сценарий в мусорном ведре прямо рядом с ffmpeg.exe, Я также добавил C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin к моим окнам PATH, но я не думаю, что вам нужно.
Если вы хотите иметь возможность предоставлять некоторые дополнительные флаги / аргументы командной строки для скрипта, то создайте новый файл с именем video2gif-prompt.batи сделать так, чтобы реестр ссылался на него вместо video2gif.bat:
@echo off
set /p inp=Enter extrta args, if desired:
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