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


Je suis en train de convertir .flv film à .gif fichier 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 la sortie du fichier gif est de très mauvaise qualité.

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.


247
2018-02-22 20:06


origine




Réponses:


ffmpeg peut maintenant produire une meilleure qualité GIF. Si vous utilisez une version plus ancienne, pensez à télécharger une version statique récente ou compilation ffmpeg.

ffmpeg Exemple

gif with ffmpeg
203k

Cet exemple ignore les 30 premières secondes de l’entrée et crée une sortie de 3 secondes. Il redimensionne la sortie à 320 pixels de large et détermine automatiquement la hauteur tout en préservant les proportions. le palettegen et paletteuse Les filtres génèrent et utilisent une palette personnalisée générée à partir de votre source.

  1. Générer une palette:

    ffmpeg -y -ss 30 -t 3 -i input.flv \
    -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
    
  2. Affiche 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 de haute qualité avec FFmpeg pour beaucoup plus d'exemples et d'options.


convert Exemple

Une autre méthode en ligne de commande consisterait à exporter le film sur des cadres en utilisant ffmpeg puis faire le GIF avec convert de ImageMagick (ou GraphicsMagick).

ffmpeg and convert
246k

  1. Exporter des cadres:

     mkdir frames
     ffmpeg -i input -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.png
    
  2. Puis utilisez 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 on le désire.


374
2018-02-22 21:31



Ajout de quelques exemples de résultats (mais encore des images). Ici, le premier fichier est 4,1 Mo, le second environ 8 Mo. - slhck
@ LordNeckbeard, vous êtes génial! merci beaucoup pour -vf scale=320:-1,format=rgb8,format=rgb24 - Kamil Hismatullin
Au fait, pour le convert commande pour convertir à partir des images PNG j'ai fini par utiliser convert -delay 5 -loop 0 -dither None -colors 80 "frames/ffout*.png" -fuzz "40%" -layers OptimizeFrame "output.gif", ce qui réduit considérablement la taille du fichier - Wilf
Je pense que le convert commande devrait utiliser -delay 10 (0,1 seconde entre les images) pour correspondre au -r 10 (10 images par seconde) taux de trame que vous nourrissez ffmpeg. Quand j'utilise -delay 5, Je vois le gif jouer à double vitesse. - Jack O'Connor
Ok, je l'ai eu, j'ai utilisé scale=0:-1, alors quand vous définissez la balance à 0, cela prendra l'échelle de la vidéo. - Mousa Alfhaily


Si vous préférez éviter les fichiers image intermédiaires, les commandes fournies par LordNeckBeard peuvent être reliées entre elles. ffmpeg et les images de ImageMagick convert 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

le -f image2pipe dit à ffmpeg de diviser la vidéo en images et de la rendre apte à être diffusée, et -vcodec ppm spécifie le format de sortie à ppm (pour une raison quelconque si le format est png, soit convert ne lit pas toutes les images du tube, ou ffmpeg ne les affiche pas toutes). le - pour les deux commandes spécifie qu'un canal sera utilisé pour la sortie et l'entrée respectivement.

Pour optimiser le résultat sans enregistrer un fichier, vous pouvez canaliser la sortie de convert à une seconde convert commander:

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

le gif:- raconte convert pour canaliser sa sortie en données formatées gif et -layers Optimize dit le second convert effectuer optimize-frame et optimize-transparancy méthodes (voir le 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, alors vous pouvez essayer de convertir en gif sans optimisation d'abord pour être sûr.

Rappelez-vous que pendant tout ce processus, tout est en mémoire, vous aurez donc besoin de suffisamment de mémoire si les images sont assez volumineuses.


79
2018-03-18 09:47



Cet ensemble de commandes fonctionne également avec avconv - raphael
Vous devez fusionner les deux dernières commandes de conversion: convert -delay 5 -loop 0 -layers Optimize - output.gif - Clément
Le gif semble fonctionner à deux fois la vitesse de la vidéo source? - Titan
@Titan pense que c'est le -r 10 dans la première commande et le -delay 5 dans le second. J'ai changé le délai à 10 également et il semble jouer normalement maintenant. - Steven Huang
Vous pouvez également éviter les fichiers image intermédiaires en utilisant le split filtre dans ffmpeg. Pas besoin de canaliser quoi que ce soit: ffmpeg -ss 30 -t 3 -i "input.flv fps=10,scale=320:-1:flags=lanczos,split[x][z];[z]palettegen[y];[x][y]paletteuse" output.gif - Ajedi32


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 


29
2018-03-23 18:39





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

Fonctionnement ./gifenc.sh input.mov output.gif 720 10 produira un GIF 10fps de 720p de large à partir du film que vous lui avez donné. Vous pourriez avoir besoin de 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 est dans le même dossier que les autres fichiers.


13
2017-07-12 09:35



Merci beaucoup pour votre script. Je viens de le tester et ça marche super bien! - orschiro


fait un script, testé et fonctionne.

usage:

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

AVEZ 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 outil EXCELLENT ScreenCapturing pour Linux :)

MERCI BEAUCOUP Michael Kohaupt :) Rock constant.

Quelques statistiques sur la taille du fichier:

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

voir le résultats ici.


7
2018-05-28 10:55





La réponse de @Stephane est très bonne. Mais il y aura un avertissement comme Buffer queue overflow, dropping. pour certains vidéo, et le généré gif a un cadre abandonné.

Voici une meilleure version avec fifo filtre à éviter Buffer queue overflow en utilisant paletteuse filtre. En utilisant split filtre pour éviter la création de la palette intermédiaire fichier 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

7
2017-10-05 12:04





Linux / Unix / macOS

Suivant Approche @LordNeckbeard avec ffmpeg commande, veuillez trouver la fonction Bash utile suivante qui peut être ajoutée à votre ~/bash_profile fichier:

# 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 le fichier chargé (. ~/.bash_profile), vous devriez avoir de nouvelles video2gif commander.

Exemple d'utilisation:

video2gif input.flv

ou:

video2gif input.flv 320 10

Échelle à 320 largeur avec 10 images par seconde.

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


macOS

Tu peux essayer Brasserie GIF application qui peut créer des fichiers GIF à partir de fichiers vidéo.


Il existe également plusieurs sites Web qui effectuent des conversions en ligne gratuitement.


6
2017-12-09 17:34



Tangential / offtopic: Pour ceux qui se demandent pourquoi Community a édité ceci, c'est à HTTPSify le lien dans la première ligne de la réponse. (La transition HTTPS de Stack Overflow va bon train!) - i336_