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.
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
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.
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
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
exempleUne 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).
246k
Cadres d'exportation:
mkdir frames
ffmpeg -i input -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.png
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.
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.
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
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.
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
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.
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).
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.
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
.
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.
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
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
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.