214 votes

Comment créer un GIF animé à partir d'une vidéo MP4 via la ligne de commande ?

Je veux faire une animation .gif d'un .mp4 vidéo. Je préférerais le faire à partir de la ligne de commande, donc veuillez ne citer que des outils en ligne de commande.

265voto

ffmpeg 3.4.4 peut le faire directement sur Ubuntu 18.04

Vous voudrez probablement utiliser quelque chose comme :

sudo apt install ffmpeg
wget -O opengl-rotating-triangle.mp4 https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.mp4?raw=true
ffmpeg \
  -i opengl-rotating-triangle.mp4 \
  -r 15 \
  -vf scale=512:-1 \
  -ss 00:00:03 -to 00:00:06 \
  opengl-rotating-triangle.gif

opengl-triangle rotatif.gif

enter image description here

Infos sur l'image : 426kB, 45 images, 512x512 taille apparente, coalescé Temps de conversion sur un Lenovo P51 : 0.5s.

La conversion ci-dessus a également fonctionné après une ulimit -Sv 1000000 (utilisation de la DRAM limitée à 1GB), donc il ne "consomme pas d'énormes quantités de mémoire" comme les tentatives précédentes que j'ai faites avec Imagemagick qui ont presque tué ma machine. 500MB a cependant échoué parce que ffmpeg n'a pas réussi à charger ses bibliothèques partagées... il est temps d'améliorer votre RAM ;-) ?

Procédure de génération des données d'essai décrite sur ce post .

La sortie a un motif de pointillés visible, qui n'est pas aussi visible dans la méthode "ffmpeg + convert" ci-dessous. Nous pouvons essayer d'améliorer la qualité de l'image avec les méthodes décrites à :

Par exemple, en utilisant le palettegen filtre :

ffmpeg \
  -i opengl-rotating-triangle.mp4 \
  -r 15 \
  -vf "scale=512:-1,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
  -ss 00:00:03 -to 00:00:06 \
  opengl-rotating-triangle-palettegen.gif

opengl-rotating-triangle-palettegen.gif

enter image description here

Infos sur l'image : 979K, 45 images, 512x512 taille apparente, coalescé Temps de conversion sur un Lenovo P51 : 3.5s.

C'est ce que nous voyons :

  • le motif en pointillé est beaucoup moins visible maintenant
  • La taille du GIF a grossièrement doublé. TODO : pourquoi le simple fait de choisir une palette augmente-t-il la taille de l'image ? Est-ce parce qu'il y a maintenant plus de couleurs et que nous avons besoin de plus de bits par couleur ? Comment observer chaque palette ?
  • Le temps de génération était 7x plus lent, probablement parce que ffmpeg scanne d'abord toute la vidéo pour déterminer une palette optimale.

Nous pourrions également jouer avec des documents palettegen des paramètres comme palettegen=max_colors=16 pour atteindre différents points de compromis entre la taille et la qualité.

Analyse de l'argumentation

  • -ss 00:00:03 -to 00:00:06 : heure de début et de fin pour couper la vidéo.

    Non, les GIFs ne sont pas le meilleur moyen de pirate distribuer des vidéos en ligne.

    Voir aussi : https://stackoverflow.com/questions/18444194/cutting-the-videos-based-on-start-and-end-time-using-ffmpeg

  • -vf scale=512:-1 : faire la sortie 512 pixels en hauteur, et ajuster la largeur pour maintenir le ratio d'aspect.

    Il s'agit d'un cas d'utilisation courant pour les images destinées au web, qui ont généralement une résolution beaucoup plus faible que les vidéos.

    Si vous supprimez cette option, le GIF de sortie a la même hauteur que la vidéo d'entrée.

    La hauteur de la vidéo originale peut être trouvée par exemple avec ffprobe : https://superuser.com/questions/595177/how-to-retrieve-video-file-information-from-command-line-under-linux/1035178#1035178 et est de 1024 x 1024 dans notre cas.

  • -r 15 : échantillonnage FPS.

    Par exemple, la vidéo originale était de 30 FPS, donc -r 15 signifie que ffmpeg choisira un cadre sur 2 ( = 30 / 15 ).

    Le nombre d'images par seconde perçu en sortie est cependant ajusté pour correspondre à l'entrée, vous ne remarquerez donc pas d'accélération, mais seulement une plus grande granularité.

    Le FPS d'entrée peut être trouvé avec ffprobe et le nombre total de trames d'entrée peut être trouvé avec mediainfo comme expliqué à : https://superuser.com/questions/84631/how-do-i-get-the-number-of-frames-in-a-video-on-the-linux-command-line/1044894#1044894

    Je recommande cette option car les formats vidéo ont généralement un taux de rafraîchissement plus élevé en raison de la plus grande résolution. Avec des GIFs plus petits, le taux de rafraîchissement est moins perceptible, et nous pouvons donc sauter certaines images et faire des GIFs plus petits.

Exemple de séquence de caméra vidéo

Si vous voulez voir la qualité du résultat d'une caméra vidéo de Wikimedia Commons avec une commande similaire :

wget https://upload.wikimedia.org/wikipedia/commons/f/f9/STS-132_Liftoff_Space_Shuttle_Atlantis.ogv
ffmpeg -i STS-132_Liftoff_Space_Shuttle_Atlantis.ogv -r 15 -vf scale=512:-1 \
  -ss 00:00:17 -to 00:00:22 STS-132_Liftoff_Space_Shuttle_Atlantis.gif

STS-132_Liftoff_Shuttle_Shuttle_Atlantis.gif

enter image description here

Infos sur l'image : 1.3MB, 75 images, taille apparente 512x288, coalescé (a un effet minime cependant, car le métrage est légèrement panoramique depuis le début), temps de conversion sur un Lenovo P51 : 2.3s.

Voici une version avec palettegen mais seulement 2 secondes pour respecter la limite de téléchargement de 2MiB :

enter image description here

Infos sur l'image : 1.5MB, 30 images, taille apparente 512x288, temps de conversion sur un Lenovo P51 : 43s.

Un plus direct :

sudo apt-get install ffmpeg
ffmpeg -i in.mp4 out.gif

fonctionne également, mais le GIF de sortie serait beaucoup plus volumineux que la vidéo d'entrée, car les formats vidéo peuvent être compressés plus efficacement entre les trames grâce à des algorithmes avancés, alors que le GIF ne peut faire que de la un simple cadre rectangulaire diff .

Avant 18.04 : ffmpeg + convert one-liner sans fichiers intermédiaires

ffmpeg ne pouvait pas gérer le GIF auparavant. Le meilleur que j'ai eu était quelque chose comme :

sudo apt-get install ffmpeg imagemagick
ffmpeg -i opengl-rotating-triangle.mp4 -r 15 -vf scale=512:-1 \
  -ss 00:00:03 -to 00:00:06 -f image2pipe -vcodec ppm - |
  convert -deconstruct -delay 5 -loop 0 - opengl-rotating-triangle-image-magick.gif

opengl-rotating-triangle-image-magick.gif

enter image description here

Infos sur l'image : 995kB, 45 images, taille apparente 512x512, coalescé.

Pour les images de la navette Atlantis, et analogues :

ffmpeg -i STS-132_Liftoff_Space_Shuttle_Atlantis.ogv -r 15 -vf scale=512:-1 \
  -ss 00:00:17 -to 00:00:22 -f image2pipe -vcodec ppm - |
  convert -deconstruct -delay 5 -loop 0 - STS-132_Liftoff_Space_Shuttle_Atlantis_512x.gif

a donné un meilleur résultat, mais le GIF final était considérablement plus gros (6,2 Mo), et je ne peux donc pas le télécharger.

Explication de certains des arguments :

Même si vous réduisez la hauteur et la fréquence d'images, le GIF de sortie peut toujours être plus grand que la vidéo, car les "vrais" formats vidéo non GIF compriment les images entre elles, tandis que le GIF comprime uniquement les images individuelles.

Un direct :

convert input.mp4 rpi2-bare-metal-blink.gif

a fonctionné, mais a presque tué mon ordinateur à cause d'un dépassement de mémoire, et a produit un résultat 100x plus grand pour mon fichier d'entrée de 2s 1Mb. Peut-être qu'un jour ImageMagick rattrapera son retard.

Voir aussi : https://superuser.com/questions/556029/how-do-i-convert-a-video-to-gif-using-ffmpeg-with-reasonable-quality

Testé sur Ubuntu 17.10.

Gifski

https://gif.ski/

C'est une autre option qui a été portée à mon attention et qui revendique des algorithmes intelligents, alors essayons-la.

Nous devons d'abord convertir la vidéo en une séquence d'images, puis l'introduire dans gifsky, par exemple :

sudo snap install gifski
mkdir -p frames
ffmpeg \
  -i opengl-rotating-triangle.mp4 \
  -r 15 \
  -vf scale=512:-1 \
  -ss 00:00:03 -to 00:00:06 \
  frames/%04d.png
gifski -o opengl-rotating-triangle-gifski.gif frames/*.png

opengl-triangle rotatif-gifski.gif

enter image description here

Infos sur l'image : 954K, 45 images, taille apparente 512x512, non coalescé, temps de conversion sur un Lenovo P51 : 4.8s.

Et la STS 2s :

enter image description here

Infos sur l'image : 1.6M, 30 images, taille apparente 512x288, non coalescé, temps de conversion sur un Lenovo P51 : 2.8s.

Donc pour moi, subjectivement, cela n'a pas semblé offrir d'avantage significatif par rapport à ffmpeg. palettegen .

130voto

Maythux Points 77506

Deux étapes :

  • Extraire des images d'une vidéo

    Créez un répertoire appelé frames dans le même répertoire que votre .mp4 fichier. Utilisez la commande :

    ffmpeg -i video.mp4  -r 5 'frames/frame-%03d.jpg'
    
    -r 5 stands for FPS value
        for better quality choose bigger number
        adjust the value with the -delay in 2nd step
        to keep the same animation speed
    
    %03d gives sequential filename number in decimal form

    source

  • Convertir des images en gif

    cd frames
    convert -delay 20 -loop 0 *.jpg myimage.gif
    
    -delay 20 means the time between each frame is 0.2 seconds
       which match 5 fps above.
       When choosing this value
           1 = 100 fps
           2 = 50 fps
           4 = 25 fps
           5 = 20 fps
           10 = 10 fps
           20 = 5 fps
           25 = 4 fps
           50 = 2 fps
           100 = 1 fps
           in general 100/delay = fps
    
    -loop 0 means repeat forever

    Docs : options de conversion gif

Vous vous retrouverez avec un fichier assez volumineux. guide de la magie des images pour optimiser les gif sur les options que vous pouvez ajouter à la commande de la deuxième étape pour obtenir un fichier plus petit.

13voto

ccpizza Points 1294

gififier est un utilitaire tout-en-un basé sur les nœuds qui simplifie la conversion. Il dépend de nodejs , npm , ffmpeg y imagemagick qui sont tous disponibles dans les dépôts.

Une fois que vous avez npm installé, vous pouvez installer gifify globalement avec :

    npm install -g gifify

Une vidéo peut être convertie en un fichier .GIF avec :

    gifify video.mp4 -o video.gif

Vous pouvez également définir une position de début et de fin dans la vidéo et ajouter une légende :

    gifify clip.mp4 -o clip.gif --from 01:48:23.200 --to 01:48:25.300 --text 'we are the knights who say nip!'

La conversion peut prendre plusieurs minutes, même pour les petites vidéos.

NOTE : ffmpeg y imagemagick peut avoir besoin d'être compilé avec certaines bibliothèques spécifiques (par exemple libass et fontconfig en conséquence).

0voto

Lance Points 101

J'ai commencé à mettre en place un outil afin de fournir une interface simplifiée pour les actions courantes.

Vous pouvez convertir un MP4 en GIF comme suit :

$ npm install @mountbuild/mouse -g
$ mouse convert input.mp4 -o output.gif -s 00:00:00 -e 00:00:03

Vous pouvez modifier l'heure de début et de fin, ainsi que l'heure d'arrivée. --fps y --width également.

Il nécessite l'installation de ffmpeg.

Si vous n'avez rien d'autre à faire, consultez la source et voyez comment écrire votre propre script pour faire cela en JavaScript.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X