Вопрос Как преобразовать видео в 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%

Благодарю.


247
2018-02-22 20:06


происхождения




ответы:


ffmpeg теперь может выводить GIF с более высоким качеством. Если вы используете более старое построение, подумайте загрузка недавней статической сборки или составление ffmpeg,

ffmpeg пример

gif with ffmpeg
203K

Этот пример пропустит первые 30 секунд ввода и создаст 3-секундный выход. Он масштабирует выход до 320 пикселей в ширину и автоматически определяет высоту, сохраняя соотношение сторон. palettegen а также paletteuse фильтры будут генерировать и использовать пользовательскую палитру, созданную из вашего источника.

  1. Создайте палитру:

    ffmpeg -y -ss 30 -t 3 -i input.flv \
    -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
    
  2. Выведите 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).

ffmpeg and convert
246k

  1. Экспортные рамки:

     mkdir frames
     ffmpeg -i input -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.png
    
  2. Затем используйте convert (или gm convert если вы предпочитаете GraphicsMagick), чтобы сделать ваш анимированный GIF:

     convert -loop 0 frames/ffout*.png output.gif
    

С convert вы можете контролировать задержку между кадрами с помощью -delay если это необходимо.


374
2018-02-22 21:31



Добавлены некоторые примеры результатов (только неподвижные кадры). Здесь первый файл - 4,1 МБ, второй - около 8 МБ. - slhck
@LordNeckbeard, ты потрясающий! большое спасибо за -vf scale=320:-1,format=rgb8,format=rgb24 - Kamil Hismatullin
Кстати, для convert команда для преобразования из кадров PNG. Я закончил использование convert -delay 5 -loop 0 -dither None -colors 80 "frames/ffout*.png" -fuzz "40%" -layers OptimizeFrame "output.gif", что значительно уменьшает общий размер файла - Wilf
я думаю convertкоманда должна использовать -delay 10 (0,1 секунды между кадрами) в соответствии с -r 10 (10 кадров в секунду), которую вы кормите ffmpeg, Когда я использую -delay 5, Я вижу игру gif с двойной скоростью. - Jack O'Connor
Ладно, у меня есть, я использовал scale=0:-1, поэтому, когда вы устанавливаете масштаб на 0, он будет получать масштаб от видео. - Mousa Alfhaily


Если вы предпочитаете избегать промежуточных файлов изображений, команды, предоставляемые 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 без оптимизации.

Помните, что в течение всего этого процесса все в памяти, поэтому вам может понадобиться достаточная память, если изображения довольно большие.


79
2018-03-18 09:47



Этот набор команд также работает с avconv - raphael
Вы должны объединить две последние команды преобразования: convert -delay 5 -loop 0 -layers Optimize - output.gif - Clément
Кажется, что gif работает на 2x скорости исходного видео? - Titan
@Titan полагает, что это -r 10 в первой команде и -delay 5 во втором. Я тоже изменил задержку на 10, и теперь она выглядит нормально. - Steven Huang
Вы также можете избежать промежуточных файлов изображений, используя split фильтр в ffmpeg. Не нужно ничего трубить: ffmpeg -ss 30 -t 3 -i "input.flv fps=10,scale=320:-1:flags=lanczos,split[x][z];[z]palettegen[y];[x][y]paletteuse" output.gif - Ajedi32


Что касается 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

HT 


29
2018-03-23 18:39





Я сделал свою собственную версию скрипта, который также параметризует разрешение вывода и частоту кадров.

Бег ./gifenc.sh input.mov output.gif 720 10 будет выводить GIF в формате 720p шириной 10 кадров в секунду из фильма, который вы ему дали. Возможно, вам придется сделать 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, и скрипт находится в той же папке, что и другие файлы.


13
2017-07-12 09:35



Большое вам спасибо за ваш скрипт. Я просто протестировал его, и он отлично работает! - orschiro


сделал скрипт, протестировал и работает.

Применение:

./avi2gif.sh ./vokoscreen-2015-05-28_12-41-56.avi

У меня есть PHUN :)

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 является отличным инструментом ScreenCapturing для Linux :)

СПАСИБО БОЛЬШЕ Майкл Коаупт :) Скала устойчива.

некоторые данные о размере файла:

5.3M = vokoscreen-2015-04-28_15-43-17.avi -> vokoscreen-2015-05-28_12-41-56.avi.gif = 1013K

см. результаты здесь.


7
2018-05-28 10:55





Ответ от @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

7
2017-10-05 12:04





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 приложение, которое может создавать GIF-файлы из видеофайлов.


Кроме того, есть несколько веб-сайтов, которые делают онлайн-перевод онлайн.


6
2017-12-09 17:34



Tangential / offtopic: для кого-то интересно, почему Community отредактировал это, именно HTTPSify ссылку в первой строке ответа. (Переход HTTPS переполнения стека идет полным ходом!) - i336_


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 фильтр.


6
2017-09-30 15:23





Ниже приведен командный файл для пользователей 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

3
2018-06-23 22:31





Для пользователей 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


3
2018-04-21 15:36



Я вижу, что вы сделали две вещи здесь: (1) написал команды как сценарий команд Windows (.BAT) и (2) предоставил другую комбинацию фильтров (ни один из других ответов не использует и то и другое  fps=10 а также scale=-1:-1). Ответ Солнца уже дал нам пакетный файл, и тот (как скрипты оболочки в Ответ pje а также ответ ветерана) имеет то преимущество, что он присваивает список фильтров переменной (один раз), ... (Продолжение) - Scott
(Cont'd) ... поэтому вам не нужно указывать список дважды (как это делает ваш командный файл). (Я полагаю, что это создает риск того, что, если пользователь редактирует скрипт для изменения одного из списков, но не другого, непоследовательность вызовет проблему.) Можете ли вы хотя бы объяснить свой выбор фильтров (fps=10,scale=-1:-1)? (Видеть Ответ заметного для примера объяснения частей команды.) - Scott
@Scott. Вы сказали правильно, поэтому я пишу здесь новый полезный скрипт: github.com/NabiKAZ/video2gif - Nabi K.A.Z.


Выбранный ответ предполагает, что вы хотите масштабировать исходное видео и изменять его 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

Это пригодилось, когда я хотел получить gif, который верно воссоздал исходное видео, которое я использовал.


3
2017-11-14 23:01