Как преобразовать видео в 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 версия 0.8.5-6: 0.8.5-0ubuntu0.12.10.1, Copyright (c) 2000-2012 разработчики Libav
  построено 24 января 2013 года 14:52:53 с gcc 4.7.2
*** ЭТА ПРОГРАММА УНИЧТОЖЕН ***
Эта программа предоставляется только для совместимости и будет удалена в будущей версии. Вместо этого используйте avconv.
Вход # 0, mov, mp4, m4a, 3gp, 3g2, mj2, from 'input.flv':
  Метаданные:
    major_brand: mp42
    minor_version: 0
    compatible_brands: isommp42
    create_time: 2013-02-14 04:00:07
  Продолжительность: 00: 00: 18,85, начало: 0,000000, бит: 3098 кб /с
    Stream # 0.0 (und): Видео: h264 (высокий), yuv420p, 1280x720, 2905 кбит /с, 25 кадров в секунду, 25 трб, 50 тбн, 50 тбс
    Метаданные:
      creation_time: 1970-01-01 00:00:00
    Stream # 0.1 (und): Аудио: aac, 44100 Гц, стерео, s16, 192 kb /s
    Метаданные:
      create_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
Выход # 0, gif, to 'output.gif':
  Метаданные:
    major_brand: mp42
    minor_version: 0
    compatible_brands: isommp42
    create_time: 2013-02-14 04:00:07
    кодировщик: Lavf53.21.1
    Stream # 0.0 (und): Видео: rawvideo, rgb24, 320x240, q = 2-31, 200 kb /s, 90k tbn, 10 tbc
    Метаданные:
      creation_time: 1970-01-01 00:00:00
Отображение потока:
  Поток # 0.0 -> # 0.0
Нажмите ctrl-c, чтобы остановить кодирование.
frame = 101 fps = 32 q = 0.0 Lsize = 8686kB time = 10.10 bitrate = 7045.0kbits /s dup = 0 drop = 149
видео: 22725kB аудио: 0kB глобальные заголовки: 0kB muxing overhead -61.778676%
 

Спасибо.

246 голосов | спросил Kamil Hismatullin 23 FebruaryEurope/MoscowbSat, 23 Feb 2013 00:06:30 +0400000000amSat, 23 Feb 2013 00:06:30 +040013 2013, 00:06:30

12 ответов


372

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

Пример ffmpeg

gif с 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 example

Другим способом командной строки было бы экспортировать фильм в кадры с помощью ffmpeg , а затем сделать GIF с convert из ImageMagick (или GraphicsMagick).

ffmpeg и convert
246k

  1. Экспорт кадров:

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

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

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

ответил LordNeckbeard 23 FebruaryEurope/MoscowbSat, 23 Feb 2013 01:31:46 +0400000000amSat, 23 Feb 2013 01:31:46 +040013 2013, 01:31:46
79

Если вы предпочитаете избегать промежуточных файлов изображений, команды, предоставляемые LordNeckBeard, могут быть переданы между ffmpeg и ImageMagick 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-transparentancy (см. ImageMagick Введение в оптимизацию анимации ). Обратите внимание, что вывод из -layers Optimize может не всегда обеспечивать меньший размер файла, поэтому сначала вы можете попробовать конвертировать в gif без оптимизации.

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

ответил notedible 18 MarpmTue, 18 Mar 2014 13:47:53 +04002014-03-18T13:47:53+04:0001 2014, 13:47:53
29

Как и в ffmpeg 2.6, мы можем сделать еще лучше:

  палитра = "/TMP /palette.png"
Фильтры = "кадров в секунду = 15, масштаб = 320: -1: флаги = Lanczos"

ffmpeg -i input.flv -vf "$ filters, palettegen" -y $ палитры
ffmpeg -i input.flv -i $ palette -lavfi "$ filters [x]; [x] [1: v] paletteuse" -y output.gif
 

HT

ответил pje 23 MarpmMon, 23 Mar 2015 21:39:20 +03002015-03-23T21:39:20+03:0009 2015, 21:39:20
13

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

Запуск ./gifenc.sh input.mov output.gif 720 10 выдаст 720p широкий 10fps GIF из фильма, который вы ему дали. Возможно, вам понадобится chmod + x gifenc.sh для файла.

  #! /Bin /ш

палитра = "/TMP /palette.png"

Фильтры = "кадров в секунду = $ 4, шкала = $ 3: 1: флаги = Lanczos"

ffmpeg -v warning -i "$ 1" -vf "$ фильтры, palettegen" -y "$ palette"
ffmpeg -v warning -i "$ 1" -i $ palette -lavfi "$ filters [x]; [x] [1: v] paletteuse" -y "$ 2"
 

Вы можете прочитать информацию о моем Github

Предположения: устанавливается ffmpeg, и скрипт находится в той же папке, что и другие файлы.

ответил thevangelist 12 J000000Sunday15 2015, 12:35:07
7

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

использование:

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

ИМЕЕТ PHUN:)

vim avi2gif.sh

  #! /Bin /ш

ВХОД = $ 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
 

btw: vokoscreen - ОТЛИЧНЫЙ инструмент ScreenCapturing для Linux:)

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

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

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

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

ответил canoodle 28 Maypm15 2015, 13:55:51
7

Ответ от @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
 
ответил alijandro 5 +03002017-10-05T15:04:32+03:00312017bEurope/MoscowThu, 05 Oct 2017 15:04:32 +0300 2017, 15:04:32
6

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 из видеофайлов.


В качестве альтернативы есть несколько веб-сайтов, которые делают онлайн-перевод онлайн бесплатно.

ответил kenorb 9 FriEurope/Moscow2016-12-09T20:34:16+03:00Europe/Moscow12bEurope/MoscowFri, 09 Dec 2016 20:34:16 +0300 2016, 20:34:16
6

ffmpeg с палитрой метод можно запускать в одной команде без посредника < code> .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 .

ответил Stephane 30 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowSat, 30 Sep 2017 18:23:29 +0300 2017, 18:23:29
3

Ниже приведен командный файл для пользователей Windows:

gifenc.bat:

  set start_time = 0
установленная продолжительность = 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
установленная продолжительность = 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
 
ответил Sun 24 J0000006Europe/Moscow 2016, 01:31:26
3

Для пользователей 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 , существует вопрос от вас для его перезаписывания.

EDIT:

Я предлагаю использовать этот пакетный скрипт: https://github.com/NabiKAZ/video2gif

ответил Nabi K.A.Z. 21 PMpFri, 21 Apr 2017 18:36:34 +030036Friday 2017, 18:36:34
3

В выбранном ответе предполагается, что вы хотите масштабировать исходное видео и изменять его fps в выпуске gif. Если вам не нужно это делать, следующие работы:

  SRC = "input.flv"
Dest = "output.gif"
палитра = "/TMP /palette.png"

ffmpeg -i $ src -vf palettegen -y $ палитра
ffmpeg -i $ src -i $ palette -lavfi paletteuse -y $ dest
 

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

ответил Jet Blue 15 32017vEurope/Moscow11bEurope/MoscowWed, 15 Nov 2017 02:01:37 +0300 2017, 02:01:37
2

Как добавить пункт контекстного меню «щелкнуть правой кнопкой мыши», чтобы преобразовать ваш видеофайл в 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
 

Теперь, когда вы щелкните правой кнопкой мыши файл, у вас будет опция «Запустить видео2Gif»!

btw Я установил 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 , но я не думаю, что вам нужно.

Если вы хотите иметь возможность предоставить некоторые дополнительные флаги командной строки /args для скрипта, затем создайте новый файл с именем video2gif-prompt.bat , и вместо этого реестр ссылается на него video2gif.bat :

  @echo off
set /p inp = Введите extrta args, если хотите:
C: \ dev \ ffmpeg \ ffmpeg-3.4.2-win64-static \ bin \ video2gif.bat% *% inp%
 

Вы можете просто нажать Enter, чтобы быстро получить значения по умолчанию.

ответил chris 16 AMpMon, 16 Apr 2018 02:48:54 +030048Monday 2018, 02:48:54

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132