Come faccio a convertire un video in GIF utilizzando ffmpeg, con una qualità ragionevole?

Sto convertendo il file .flv in file .gif con ffmpeg.

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

Funziona grande, ma il file gif di output ha una qualità molto bassa.

Qualche idea su come posso migliorare la qualità del gif convertito?

Uscita del command:

 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% 

Grazie.

ffmpeg può ora produrre GIF di qualità superiore. Se si utilizza una build precedente, si consiglia di scaricare una creazione statica recente o di compilare ffmpeg .

esempio ffmpeg

gif con ffmpeg
203k

Questo esempio salterà i primi 30 secondi dell'ingresso e crea un'output di 3 secondi. Scala l'output per essere largo 320 pixel e determina automaticamente l'altezza mantenendo il rapporto di aspetto. I filtri palettegen e paletteuse generano e utilizzano una tavolozza personalizzata generata dalla sorgente.

  1. Generazione di una tavolozza:

     ffmpeg -y -ss 30 -t 3 -i input.flv \ -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png 
  2. Uscita del GIF usando la tavolozza:

     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 

Vedere GIF di alta qualità con FFmpeg per molti altri esempi e opzioni.


esempio di convert

Un altro metodo della row di command sarebbe quello di esportre il filmato in fotogrammi usando ffmpeg quindi fare il GIF con la convert da ImageMagick (o GraphicsMagick).

ffmpeg e convertire
246K

  1. Strutture di esportzione:

      mkdir frames ffmpeg -i input -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.png 
  2. Quindi utilizzare la convert (o gm convert se si preferisce GraphicsMagick) per rendere il tuo animato GIF:

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

Con la convert è ansible controllare il ritardo tra i fotogrammi con -delay se lo si desidera.

Se si desidera evitare i file di immagini intermedi, i comandi forniti da LordNeckBeard possono essere collegati tra la convert di ffmpeg e ImageMagick in modo che non siano richiesti file intermedi:

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

Il -f image2pipe dice a ffmpeg di dividere il video in immagini e renderlo adatto per essere estratto, e -vcodec ppm specifica il formato di output in ppm (per qualche motivo se il formato è png, la convert non legge tutte le immagini dal pipe, o ffmpeg non li emette tutti). Il - per entrambi i comandi specifica che un pipe verrà utilizzato rispettivamente per l'output e l'ingresso.

Per ottimizzare il risultato senza salvare un file, è ansible pipare l'output da convert in un secondo command di 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 

Il gif:- dice convert a pipeline l'output come dati e -layers Optimize formattati gif. -layers Optimize dice la seconda convert per eseguire methods di optimize-transparancy e optimize-transparancy (vedere l' introduzione di ImageMagick optimize-transparancy dell'animation ). Tieni presente che l'output del -layers Optimize non può sempre fornire una dimensione minore di file, pertanto è consigliabile provare a convertire in un gif senza ottimizzare innanzitutto.

Ricorda che durante tutto questo process tutto è in memory in modo da poter avere bisogno di memory sufficiente se le immagini sono abbastanza grandi.

Come ffmpeg 2.6, possiamo fare ancora meglio:

 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

Ho fatto la mia versione dello script, che parametrizzano anche la risoluzione dell'output e la velocità del frame. Uso:

Correndo ./gifenc input.mov output.gif 720 10 largo 10fps gif dal filmato che hai dato. Potrebbe essere necessario eseguire chmod +x gifenc.sh per il file.

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

Puoi leggere i dettagli sul mio Github

Assunzioni: ffmpeg è installato, lo script è nella stessa cartella di altri file.

ha fatto uno script, testato e funzionante.

utilizzo:

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

HANNO 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 è uno strumento EXCELLENT ScreenCapturing per Linux 🙂

GRAZIE UN LOTTO Michael Kohaupt 🙂 Rock stabile.

alcune statistiche di dimensione del file:

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

vedere i risultati qui.

Linux / Unix / MacOS

Dopo l'approccio @LordNeckbeard con il command ffmpeg , è ansible trovare la seguente function Bash utile che può essere aggiunta nel file ~/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" } 

Una volta caricato il file ( . ~/.bash_profile ), dovresti avere un nuovo command video2gif .

Esempio di utilizzo:

 video2gif input.flv 

o:

 video2gif input.flv 320 10 

Scala a 320 width con 10 fotogrammi al secondo.

È inoltre ansible specificare un formato video diverso (ad esempio mp4).


Mac OS

Puoi provare l'applicazione GIF Brewery che può creare GIF da file video.


In alternativa ci sono diversi siti web che stanno facendo la conversione on-line gratuitamente.

Di seguito è riportto il file batch per gli utenti di 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 di alta qualità con FFmpeg: estrarre solo un campione

Se si desidera utilizzare una variabile di input e avere il nome di output solo l'estensione GIF (pronunciata JIF), utilizzare invece questo:

 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 

Per gli utenti di Windows:
creare il file video2gif.bat nella directory di Windows con questi contenuti:

 @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 poi ovunque si può usare è come questo esempio:

 video2gif myvideo.mp4 

Allora hai myvideo.gif nella directory corrente.
Se myvideo.gif esiste, myvideo.gif di sovrascriverlo.

EDIT:

Suggerisco di utilizzare questo script batch: https://github.com/NabiKAZ/video2gif