Como faço para converter um vídeo para GIF usando ffmpeg, com qualidade razoável?

257

Estou convertendo FLV movie em GIF file com ffmpeg.

ffmpeg -i input.flv -ss 00:00:00.000 -pix_fmt rgb24 -r 10 -s 320x240 -t 00:00:10.000  output.gif

Funciona muito bem, mas o arquivo gif de saída tem uma qualidade muito baixa.

Alguma idéia de como melhorar a qualidade do gif convertido?

Saída do comando:

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%

Obrigado.

    
por Kamil Hismatullin 22.02.2013 / 21:06

12 respostas

388

ffmpeg agora pode gerar GIF de maior qualidade. Se você estiver usando uma versão mais antiga, considere baixar o download de uma versão estática recente ou compilando ffmpeg .

ffmpeg example


203k

Esteexemplopulaosprimeiros30segundosdaentradaecriaumasaídade3segundos.Eledimensionaráasaídapara320pixelsdelarguraedeterminaráautomaticamenteaaltura,preservandoaproporção.Os palettegen e paletteuse geram e usam uma paleta personalizada gerada a partir de sua origem.

  1. Gerar uma paleta:

    ffmpeg -y -ss 30 -t 3 -i input.flv \
    -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
    
  2. Saída do GIF usando a paleta:

    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
    

Veja GIF de alta qualidade com FFmpeg para muitos mais exemplos e opções.

convert example

Outro método de linha de comando seria exportar o filme para quadros usando ffmpeg e, em seguida, criar o GIF com convert do ImageMagick (ou GraphicsMagick).


246k

  1. Exportar quadros:

     mkdir frames
     ffmpeg -i input -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.png
    
  2. Em seguida, use convert (ou gm convert , se você preferir GraphicsMagick) para criar seu GIF animado:

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

Com convert , você pode controlar o atraso entre os quadros com -delay , se desejado.

    
por 22.02.2013 / 22:31
80

Se você preferir evitar arquivos de imagem intermediários, os comandos fornecidos pelo LordNeckBeard podem ser canalizados entre ffmpeg e convert do ImageMagick, para que não sejam necessários arquivos intermediários:

ffmpeg -i input.flv -vf scale=320:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 5 -loop 0 - output.gif

O -f image2pipe diz ao ffmpeg para dividir o vídeo em imagens e torná-lo adequado para ser canalizado, e -vcodec ppm especifica o formato de saída para ser ppm (por algum motivo, se o formato for png, convert não não lê todas as imagens do pipe, ou o ffmpeg não produz todas elas. O - para ambos os comandos especifica que um canal será usado para saída e entrada, respectivamente.

Para otimizar o resultado sem salvar um arquivo, você pode canalizar a saída do comando convert para um segundo 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

O gif:- informa convert para enviar sua saída como dados formatados com gif e -layers Optimize informa ao segundo convert para executar os métodos optimize-frame e optimize-transparancy (consulte o ImageMagick Introdução à otimização de animação . Observe que a saída do -layers Optimize nem sempre fornece um tamanho de arquivo menor, portanto, convém tentar converter para um gif sem otimização, primeiro para ter certeza.

Lembre-se que durante todo este processo tudo está na memória, então você pode precisar de memória suficiente se as imagens forem muito grandes.

    
por 18.03.2014 / 10:47
29

A partir do ffmpeg 2.6, podemos fazer ainda melhor:

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

    
por 23.03.2015 / 19:39
13

Eu fiz minha própria versão do script, que também parametriza a resolução de saída e a taxa de quadros.

A execução de ./gifenc.sh input.mov output.gif 720 10 produzirá um GIF de 10 fps com largura de 720p a partir do filme que você forneceu. Pode ser necessário fazer chmod +x gifenc.sh para o arquivo.

#!/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"

Você pode ler os detalhes no meu Github

Suposições: o ffmpeg está instalado, e o script está na mesma pasta que os outros arquivos.

    
por 12.07.2015 / 11:35
8

fez um script, testou e funciona.

uso:

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

TENHA 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

btw: vokoscreen é uma ferramenta EXCELENTE de Captura de Tela para Linux:)

OBRIGADO MUITO Michael Kohaupt :) Rock estável.

algumas estatísticas de tamanho de arquivo:

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

veja os resultados aqui.

    
por 28.05.2015 / 12:55
7

Linux / Unix / macOS

Seguindo abordagem @LordNeckbeard com o comando ffmpeg , por favor, encontre a seguinte função Bash útil que pode ser adicionada ao seu ~/bash_profile file:

# 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"
}

Quando o arquivo for carregado ( . ~/.bash_profile ), você deverá ter o novo comando video2gif .

Exemplo de uso:

video2gif input.flv

ou:

video2gif input.flv 320 10

Escala para 320 de largura com 10 quadros por segundo.

Você também pode especificar um formato de vídeo diferente (como mp4).

macOS

Você pode experimentar o aplicativo GIF Brewery , que pode criar GIFs a partir de arquivos de vídeo.

Alternativamente, existem vários sites que estão fazendo a conversão online gratuitamente.

    
por 09.12.2016 / 18:34
7

A resposta do @Stephane é muito boa. Mas ele receberá um aviso como Buffer queue overflow, dropping. para alguns vídeos, e o gif gerado perderá alguns frames.

Aqui está uma versão melhor com fifo filter para evitar Buffer queue overflow ao usar o filtro paletteuse . Usando o filtro split para evitar a criação do arquivo PNG da paleta intermediária.

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
    
por 05.10.2017 / 14:04
6

O método ffmpeg with paleta method pode ser executado em um único comando, sem intermediário .png file.

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

Isso pode ser feito graças ao filtro split .

    
por 30.09.2017 / 17:23
4

A resposta selecionada assume que você deseja dimensionar o vídeo de origem e alterar seus fps no gif produzido. Se você não precisa fazer isso, o seguinte funciona:

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

Isso foi útil quando eu queria um gif que recriava fielmente o vídeo de origem que eu estava usando.

    
por 15.11.2017 / 00:01
3

Abaixo está o arquivo em lote para usuários do 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

Fonte: GIF de alta qualidade com FFmpeg: extrair apenas uma amostra

Se você quiser usar apenas uma variável de entrada e o nome da saída tiver apenas a extensão GIF (pronunciado JIF), use-a:

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
    
por 24.06.2016 / 00:31
3

Para usuários do Windows:
crie o arquivo video2gif.bat no diretório windows com este conteúdo:

@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

E, em qualquer lugar, você pode usá-lo como este exemplo:

video2gif myvideo.mp4

Então você tem myvideo.gif no diretório atual.
Se myvideo.gif existir, pergunta de você para sobrescrevê-lo.

EDITAR:

Sugiro usar este script em lote: link

    
por 21.04.2017 / 17:36
2

Como adicionar uma entrada de menu de contexto do Windows com o botão direito do mouse para converter seu arquivo de vídeo em gif

Algumas das outras respostas mencionaram o script video2gif , que usei. Mas você poderia usar qualquer script.

Para criar a opção de menu de contexto, você precisa editar seu registro. Abra um prompt de comando do powershell, executando w / admin privs. Execute estes comandos:

$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

Agora, quando você clica com o botão direito do mouse em um arquivo, você tem a opção "Executar Video2Gif"!

btw instalei o ffmpeg em C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\ e coloquei o script video2gif.bat na pasta bin ao lado de ffmpeg.exe . Eu também adicionei C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin ao meu windows PATH , mas eu não acho que você precise.

Se você quiser a opção de fornecer alguns argumentos / argumentos adicionais de linha de comando ao script, crie um novo arquivo chamado video2gif-prompt.bat e peça ao registro que o referencie em vez de 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%

Você ainda pode apertar enter para obter rapidamente os padrões.

    
por 16.04.2018 / 01:48

Tags