2013-02-22 20:06:30 +0000 2013-02-22 20:06:30 +0000
335
335

Come si converte un video in GIF utilizzando ffmpeg, con una qualità ragionevole?

Sto convertendo un video in un 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 benissimo, ma il file gif in uscita ha una qualità molto bassa.

Qualche idea su come posso migliorare la qualità delle gif convertite?

Risposte (12)

505
505
505
2013-02-22 21:31:46 +0000

ffmpeg esempio

183k

ffmpeg può emettere GIF di alta qualità. Prima di iniziare si consiglia sempre di utilizzare una versione recente: scarica o compila .

ffmpeg -ss 30 -t 3 -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif
``` ```
ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos" -c:v pam -f image2pipe - | convert -delay 10 - -loop 0 -layers optimize output.gif
  • Questo esempio salterà i primi 30 secondi (-ss 30) dell'ingresso e creerà un'uscita di 3 secondi (-t 3).
  • fps filtro imposta il frame rate. Nell'esempio si usa una velocità di 10 fotogrammi al secondo.
  • scala filter ridimensionerà l'uscita a 320 pixel di larghezza e determinerà automaticamente l'altezza mantenendo il rapporto d'aspetto. In questo esempio si usa l'algoritmo lanczos scale .
  • palettegen e paletteuse filter genererà e utilizzerà una palette personalizzata generata dal vostro input. Questi filtri hanno molte opzioni, quindi fare riferimento ai link per una lista di tutte le opzioni e i valori disponibili. Vedere anche la sezione Opzioni avanzate qui sotto.
  • split filter permetterà di fare tutto in un unico comando ed eviterà di dover creare un file PNG temporaneo della palette.
  • Control looping con l'opzione di uscita -loop ma i valori sono confusi. Un valore di 0 è looping infinito, -1 non è looping, e 1 andrà in loop una volta, il che significa che suonerà due volte. Quindi un valore di 10 farà suonare il GIF 11 volte.

Opzioni avanzate

I filtri palettegen e paletteuse hanno molte opzioni aggiuntive. Le più importanti sono:

  • stats_mode (palettegen). È possibile forzare i filtri a focalizzare la palette sul quadro generale (full che è l'impostazione predefinita), solo le parti mobili (diff), o ogni singolo fotogramma (single). Per esempio, per generare una tavolozza per ogni singolo fotogramma usare palettegen=stats_mode=single & paletteuse=new=1.

  • dither (paletteuse). Scegliere l'algoritmo di dithering. Ci sono tre tipi principali: deterministico (bayer), diffusione dell'errore (tutti gli altri, compreso il default sierra2_4a), e nessuno. Il vostro GIF può avere un aspetto migliore utilizzando un particolare algoritmo di dithering, oppure nessun dithering. Se si vuole provare bayer assicurarsi di testare anche l'opzione bayer_scale.

Vedere GIF di alta qualità con FFmpeg per spiegazioni, immagini di esempio, e informazioni più dettagliate per un uso avanzato.

Vedere anche la documentazione palettegen e paletteuse per tutte le opzioni e i valori disponibili.


ImageMagick convert esempio

227k

Un altro metodo a riga di comando è quello di pipe da ffmpeg a convert (o magick) da ImageMagick.

&001 &001

ffmpeg opzioni:

  • -vf "fps=10,scale=320:-1:flags=lanczos" un filtergraph usando i filtri fps e scale . fps imposta il frame rate a 10, e la scala imposta la dimensione a 320 pixel di larghezza e altezza viene determinata automaticamente e usa un valore che preserva il rapporto d'aspetto. In questo esempio si usa l'algoritmo di scala [ lanczos scale .

  • -c:v pam Sceglie il codificatore d'immagine pam. L'esempio produce il formato immagine PAM (Portable AnyMap) che è un semplice formato RGB senza perdita di dati che supporta la trasparenza (alfa) ed è supportato da convert. È più veloce da codificare rispetto a PNG.

  • -f image2pipe sceglie il muxer image2pipe perché quando si emette su un pipe ffmpeg deve essere detto quale muxer usare.

convert opzioni:

  • -delay Vedi Impostazione del frame rate sezione sottostante.

  • -loop 0 fa loop infinito.

  • -layers optimize Attiva l'ottimizzatore GIF per uso generale. Vedere ImageMagick Animation Optimization per maggiori dettagli. Non è garantito che produrrà un output più piccolo, quindi vale la pena provare senza -layers optimize e confrontare i risultati.

Impostazione frame rate

Set frame rate con una combinazione del filtro fps in ffmpeg e -delay in convert. Questo può diventare complicato perché convert ottiene solo un flusso grezzo di immagini in modo da non conservare nessun fps. In secondo luogo, il valore di -delay in convert è in ticks (ci sono 100 ticks al secondo), non in frames al secondo. Per esempio, con fps=12.5 = 100/12.5 = 8 = -delay 8.

convert arrotonda il valore -delay ad un numero intero, quindi 8.4 risulta in 8 e 8.5 risulta in 9. Ciò significa che solo alcuni frame rate sono supportati quando si imposta un ritardo uniforme su tutti i frame (un ritardo specifico può essere impostato per frame, ma questo va oltre questa risposta).

-delay sembra essere ignorato se usato come opzione di uscita, quindi deve essere usato prima di - come mostrato nell'esempio.

Infine, i browser e i visualizzatori di immagini possono implementare un ritardo minimo, quindi il vostro -delay può essere ignorato comunque.

Video per gentile concessione del U.S. Fish & Wildlife Service National Conservation Training Center.

88
88
88
2014-03-18 09:47:53 +0000

Se si preferisce evitare i file immagine intermedi, i comandi forniti da LordNeckBeard possono essere inviati tra ffmpeg e convert di ImageMagick in modo che non siano necessari 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 ad essere piped out, e -vcodec ppm specifica il formato di output da ppm (per qualche ragione se il formato è png, o convert non legge tutte le immagini dal pipe, o ffmpeg non le emette tutte). L’- per entrambi i comandi specifica che un pipe sarà usato rispettivamente per l'uscita e per l'ingresso.

Per ottimizzare il risultato senza salvare un file, si può eseguire il pipe dell'uscita da convert ad un secondo comando 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

L’gif:- dice a convert di eseguire il pipe della sua uscita come dati in formato gif e -layers Optimize dice al secondo convert di eseguire i metodi optimize-frame e optimize-transparancy (vedere l'ImageMagick Introduzione all'ottimizzazione dell'animazione ). Si noti che l'output del -layers Optimize potrebbe non sempre fornire una dimensione di file più piccola, quindi si potrebbe voler provare a convertirlo in un gif senza ottimizzazione prima per esserne sicuri.

Ricordate che durante tutto questo processo tutto è in memoria, quindi potreste aver bisogno di memoria sufficiente se le immagini sono abbastanza grandi.

38
38
38
2015-03-23 18:39:20 +0000

A partire dal 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

20
20
20
2017-10-05 12:04:32 +0000

La risposta di @Stephane è molto buona. Ma otterrà un avviso come Buffer queue overflow, dropping. per alcuni video, e il gif generato ha qualche fotogramma caduto.

Ecco una versione migliore con il filtro fifo per evitare Buffer queue overflow quando si usa il filtro paletteuse. Utilizzando il filtro split per evitare la creazione di file PNG di palette intermedie.

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
18
18
18
2015-07-12 09:35:07 +0000

Ho fatto la mia versione dello script, che parametrizza anche la risoluzione di uscita e il frame rate.

Running ./gifenc.sh input.mov output.gif 720 10 emetterà una GIF a 720p di larghezza 10fps dal filmato che gli avete dato. Potrebbe essere necessario fare 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"
``` &001 


È possibile leggere i dettagli sul mio [ Github ](https://github.com/thevangelist/FFMPEG-gif-script-for-bash) 


Assunzioni: ffmpeg è installato, e lo script è nella stessa cartella degli altri file.
12
12
12
2017-09-30 15:23:29 +0000

Il ffmpeg con palette metodo può essere eseguito in un unico comando, senza file .png intermediario.

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

Questo può essere fatto grazie al filtro split .

11
11
11
2015-05-28 10:55:51 +0000

fatto uno script, testato e funzionante.

uso:

./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
``` &001 


btw: [ vokoscreen ](http://www.kohaupt-online.de/hp/) è uno strumento di cattura schermo ECCELLENTE per Linux :) 


GRAZIE A LOTTO Michael Kohaupt :) Rock steady. 


alcune statistiche sulle dimensioni del file: 

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


vedi i [ risultati qui. ](http://dwaves.de/2015/05/28/gimp-how-to-move-a-text-field-around/)
10
10
10
2016-12-09 17:34:16 +0000

Linux/Unix/macOS

Seguendo @LordNeckbeard approach con il comando ffmpeg, si trova la seguente utile funzione Bash 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 che la funzione è stata caricata (manualmente o da . ~/.bash_profile), si dovrebbe avere il nuovo comando video2gif.

Esempio di utilizzo:

video2gif input.flv

o:

video2gif input.flv 320 10
``` &001 


Scala a 320 larghezza con 10 fotogrammi al secondo. 


Si può anche specificare un formato video diverso (come mp4). 


* * * * 


### macOS 


Si può provare l'applicazione [ GIF Brewery ](http://gifbrewery.com/) che può creare GIF da file video. 


* * * * 

In alternativa ci sono diversi siti web che stanno facendo la conversione online gratuitamente.
9
9
9
2017-11-14 23:01:37 +0000

La risposta selezionata presuppone che si voglia scalare il video sorgente e cambiare i suoi fps nella gif prodotta. Se non è necessario farlo, i seguenti lavori:

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
``` &001 


Questo mi è tornato utile quando volevo una gif che ricreasse fedelmente il video sorgente che stavo usando.
6
6
6
2017-04-21 15:36:34 +0000

Per gli utenti di windows: creare video2gif.bat file 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 lo si possa usare essere come questo esempio:

video2gif myvideo.mp4

Allora avete myvideo.gif nella directory corrente. Se myvideo.gif esiste, domanda da parte vostra per sovrascriverlo.

EDIT:

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

4
4
4
2016-06-23 22:31:26 +0000

Di seguito è riportato il file batch per gli utenti 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
``` ```
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

Source: GIF di alta qualità con FFmpeg: Estrarre solo un campione

Se si vuole usare solo una variabile di ingresso e il nome dell'uscita ha solo l'estensione GIF (si pronuncia JIF), allora usare questa invece:

&001

3
3
3
2018-04-15 23:48:54 +0000

Come aggiungere una voce di menu contestuale di windows 7/10 “tasto destro del mouse” per convertire il file video in gif

Alcune delle altre risposte hanno menzionato lo script video2gif , che ho usato. Ma, si potrebbe usare qualsiasi script.

Per creare l'opzione del menu contestuale, è necessario modificare il registro di sistema. Aprire un prompt di comando powershell, con i comandi di admin privs. Eseguite questi comandi:

$key = "Registry::HKEY_CLASSES_ROOT# Come aggiungere una voce di menu contestuale di windows 7/10 "tasto destro del mouse" per convertire il file video in gif 


Alcune delle altre risposte hanno menzionato lo script [ video2gif ]&003, che ho usato. Ma, si potrebbe usare qualsiasi script. 


Per creare l'opzione del menu contestuale, è necessario modificare il registro di sistema. Aprire un prompt di comando powershell, con i comandi di admin privs. Eseguite questi comandi: 


*\shell\Run Video2Gif"
New-Item -Path $key"\Command" -Value "C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin\video2gif.bat `"%1`"" -Force
``` ```
@echo off
set /p inp=Enter extrta args, if desired:
C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin\video2gif.bat %* %inp%

Ora quando fate clic con il tasto destro del mouse su un file avrete l'opzione “Esegui Video2Gif”!

btw Ho installato ffmpeg su `C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static# Come aggiungere una voce di menu contestuale di windows 7/10 “tasto destro del mouse” per convertire il file video in gif

Alcune delle altre risposte hanno menzionato lo script [ video2gif ]&003, che ho usato. Ma, si potrebbe usare qualsiasi script.

Per creare l'opzione del menu contestuale, è necessario modificare il registro di sistema. Aprire un prompt di comando powershell, con i comandi di admin privs. Eseguite questi comandi:

$key = "Registry::HKEY_CLASSES_ROOT# Come aggiungere una voce di menu contestuale di windows 7/10 "tasto destro del mouse" per convertire il file video in gif 


Alcune delle altre risposte hanno menzionato lo script [ video2gif ]&003, che ho usato. Ma, si potrebbe usare qualsiasi script. 


Per creare l'opzione del menu contestuale, è necessario modificare il registro di sistema. Aprire un prompt di comando powershell, con i comandi di admin privs. Eseguite questi comandi: 


*\shell\Run Video2Gif"
New-Item -Path $key"\Command" -Value "C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin\video2gif.bat `"%1`"" -Force
``` ```
@echo off
set /p inp=Enter extrta args, if desired:
C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin\video2gif.bat %* %inp%

Ora quando fate clic con il tasto destro del mouse su un file avrete l'opzione “Esegui Video2Gif”!

btw Ho installato ffmpeg su e ho messo lo script video2gif.bat nel bin dir proprio accanto a ffmpeg.exe. Ho anche aggiunto C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin alle mie finestre PATH, ma non credo sia necessario.

Se volete l'opzione di poter fornire alcuni flag / args extra a riga di comando allo script, allora fate un nuovo file di nome video2gif-prompt.bat, e fate fare riferimento al registro di sistema invece di video2gif.bat:

&001 &001

Potete ancora premere invio per ottenere rapidamente i valori predefiniti.