web-dev-qa-db-fra.com

Comment convertir une vidéo au format GIF en utilisant ffmpeg, avec une qualité raisonnable?

Je convertis un film FLV en un fichier GIF avec ffmpeg.

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

Cela fonctionne très bien, mais le fichier gif en sortie a une qualité très basse.

Des idées comment puis-je améliorer la qualité de gif converti?

Sortie de commande:

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%

Merci.

288
Kamil Hismatullin

ffmpeg peut maintenant générer des fichiers GIF de meilleure qualité. Si vous utilisez une version plus ancienne, considérez en téléchargeant une version statique récente ou compiler ffmpeg .

ffmpeg exemple

gif with ffmpeg
203k

Cet exemple ignorera les 30 premières secondes de l'entrée et créera une sortie de 3 secondes. La largeur de sortie sera de 320 pixels et la hauteur sera déterminée automatiquement tout en préservant le rapport hauteur/largeur. Les filtres palettegen et paletteuse généreront et utiliseront une palette personnalisée générée à partir de votre source.

  1. Générez une palette:

    ffmpeg -y -ss 30 -t 3 -i input.flv \
    -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
    
  2. Produisez le GIF en utilisant la palette:

    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
    

Voir GIF haute qualité avec FFmpeg pour de nombreux autres exemples et options.


convert exemple

Une autre méthode de ligne de commande consisterait à exporter le film en images à l'aide de ffmpeg, puis à créer le GIF avec convert à partir de ImageMagick (ou GraphicsMagick).

ffmpeg and convert
246k

  1. Cadres d'exportation:

     mkdir frames
     ffmpeg -i input -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.png
    
  2. Utilisez ensuite convert (ou gm convert si vous préférez GraphicsMagick) pour créer votre GIF animé:

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

Avec convert, vous pouvez contrôler le délai entre les images avec -delay si vous le souhaitez.

419
llogan

Si vous préférez éviter les fichiers image intermédiaires, les commandes fournies par LordNeckBeard peuvent être transférées entre ffmpeg et convert de ImageMagick afin qu'aucun fichier intermédiaire ne soit requis:

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

-f image2pipe indique à ffmpeg de scinder la vidéo en images et de la rendre appropriée à une diffusion en sortie, et -vcodec ppm en spécifiant le format de sortie en ppm (pour une raison quelconque, si le format est png, la variable convert ne lit pas toutes les images du tube, ou ffmpeg ne les sort pas tous). Le - pour les deux commandes spécifie qu'un tube sera utilisé pour la sortie et l'entrée, respectivement.

Pour optimiser le résultat sans enregistrer de fichier, vous pouvez diriger la sortie de convert vers une seconde commande 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:- indique à convert de canaliser sa sortie sous forme de données gif et -layers Optimize indique à la deuxième convert d'effectuer les méthodes optimize-frame et optimize-transparancy (voir ImageMagick Introduction à l'optimisation de l'animation ). Notez que la sortie du -layers Optimize peut ne pas toujours fournir une taille de fichier plus petite, vous pouvez donc essayer de convertir en gif sans optimisation au préalable pour en être sûr.

N'oubliez pas que pendant tout ce processus, tout est en mémoire. Vous aurez donc peut-être besoin de suffisamment de mémoire si les images sont assez volumineuses.

85
notedible

A partir de ffmpeg 2.6, nous pouvons faire encore mieux:

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

35
pje

J'ai créé ma propre version du script, qui paramètre également la résolution de sortie et la fréquence d'images.

Si vous exécutez ./gifenc.sh input.mov output.gif 720 10, le film que vous avez donné est généré au format GIF 10 images par seconde large. Vous devrez peut-être faire chmod +x gifenc.sh pour le fichier.

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

Vous pouvez lire les détails sur mon Github

Hypothèses: ffmpeg est installé et le script se trouve dans le même dossier que les autres fichiers.

17
thevangelist

La réponse de @ Stephane est très bonne. Mais il y aura un avertissement tel que Buffer queue overflow, dropping. pour certaines vidéos, et la gif générée a perdu une image.

Voici une meilleure version avec le filtre fifo pour éviter Buffer queue overflow lors de l'utilisation du filtre paletteuse. En utilisant le filtre split pour éviter la création d'un fichier PNG de palette intermédiaire.

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
12
alijandro

fait un script, testé et fonctionne.

usage:

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

AVOIR 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 est un excellent outil de capture d'écran pour Linux :)

MERCI BEAUCOUP Michael Kohaupt :) Rock stable.

quelques statistiques de taille de fichier:

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

voir le résultats ici.

10
canoodle

Linux/Unix/macOS

Après la commande @LordNeckbeard avec la commande ffmpeg, veuillez trouver la fonction Bash utile suivante qui peut être ajoutée dans votre fichier ~/.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"
}

Une fois la fonction chargée (manuellement ou à partir de . ~/.bash_profile), vous devriez avoir une nouvelle commande video2gif.

Exemple d'utilisation:

video2gif input.flv

ou:

video2gif input.flv 320 10

Échelle jusqu'à 320 largeur avec 10 images par seconde.

Vous pouvez également spécifier un format vidéo différent (tel que mp4).


macOS

Vous pouvez essayer GIF Brewery app qui permet de créer des GIF à partir de fichiers vidéo.


Alternativement, plusieurs sites Web effectuent une conversion en ligne gratuitement.

9
kenorb

La ffmpeg avec palette méthode peut être exécutée en une seule commande, sans fichier .png intermédiaire.

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

Cela peut être fait grâce au filtre split .

8
Stephane

La réponse sélectionnée suppose que vous souhaitez redimensionner la vidéo source et modifier ses images par seconde dans le gif généré. Si vous n'avez pas besoin de le faire, les opérations suivantes fonctionnent:

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

Cela m'a été utile lorsque je voulais un gif reproduisant fidèlement la vidéo source que j'utilisais.

7
Jet Blue

Vous trouverez ci-dessous le fichier de commandes pour les utilisateurs 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

Source: GIF haute qualité avec FFmpeg: Extraire un échantillon

Si vous souhaitez uniquement utiliser une variable d'entrée et que le nom du résultat ait uniquement l'extension GIF (prononcé JIF), utilisez plutôt ceci:

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
4
Sun

Pour les utilisateurs de Windows:
crée un fichier video2gif.bat dans le répertoire Windows avec le contenu suivant:

@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

Et puis n'importe où vous pouvez l'utiliser comme ceci:

video2gif myvideo.mp4

Ensuite, vous avez myvideo.gif dans le répertoire actuel.
S'il existe myvideo.gif, demandez à vous de le remplacer.

EDIT:

Je suggère d'utiliser ce script batch: https://github.com/NabiKAZ/video2gif

4
Nabi K.A.Z.

Comment ajouter une entrée de menu contextuel Windows 7/10 "clic droit" pour convertir votre fichier vidéo en gif

Certaines des autres réponses ont mentionné le script video2gif que j'ai utilisé. Mais, vous pouvez utiliser n'importe quel script.

Pour créer l'option de menu contextuel, vous devez modifier votre registre. Ouvrez une invite de commande powershell, exécutant w/admin privs. Exécutez ces commandes:

$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

Maintenant, lorsque vous cliquez avec le bouton droit sur un fichier, vous avez l'option "Exécuter Video2Gif"!

btw j'ai installé ffmpeg à C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\ et mis le script video2gif.bat dans le répertoire bin juste à côté de ffmpeg.exe. J'ai également ajouté C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin à mes fenêtres PATH, mais je ne pense pas que vous ayez à le faire.

Si vous souhaitez avoir la possibilité de fournir au script des indicateurs/arguments de ligne de commande supplémentaires, créez un nouveau fichier nommé video2gif-Prompt.bat et demandez au registre de le référencer à la place 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%

Vous pouvez toujours appuyer sur Entrée pour obtenir rapidement les valeurs par défaut.

2
chris