Comment créer une vidéo à partir d'images en utilisant FFmpeg?

86

Est-il possible d'utiliser ffmpegcréer une vidéo à partir d'un ensemble de séquences, où le nombre ne commence pas à partir de zéro?

Par exemple, j'ai des images [test_100.jpg, test_101.jpg, test_102.jpg, ..., test_200.jpg] et je souhaite les convertir en vidéo. J'ai essayé la commande suivante, mais cela n'a pas fonctionné (il semble que le nombre devrait partir de zéro):

ffmpeg -i test_% d.jpg -vcodec mpeg4 test.avi

Un conseil?

JakeGould
la source
Cela fait longtemps que vous avez posé cette question, mais si la question vous intéresse toujours, la réponse est OUI - j'ai posté les détails et un exemple ci-dessous: stackoverflow.com/a/12160155/181638
Assad Ebrahim
@casperOne serait utile d'avoir une idée pourquoi c'est hors sujet. Cela ressemble à un problème de programmation spécifique. Le tag FFmpeg a 3,7k abonnés, et avec 27k vues, les gens le trouvent utile.
geotheory
2
@geotheory Les statistiques des balises ne sont pas pertinentes. ffmpeg est un programme qui ressemble beaucoup à WinRar. Bien que vous puissiez programmer contre les bibliothèques dans ffmpeg , cette question ne porte pas sur cela. Utiliser ffmpeg à partir de la ligne de commande doit être demandé au super utilisateur , où il se trouve dans le sujet.
casperOne

Réponses:

81

Il n’est pas nécessaire de renommer les fichiers si vous utilisez le -start_numbercommutateur comme ceci:

ffmpeg -start_number n -i test_%d.jpg -vcodec mpeg4 test.avi

nest le début de la séquence d'images fixes.

Notez que cela fonctionnera tant que la séquence sera ininterrompue une fois lancée. S'il y a des lacunes et que vous souhaitez que toutes les images soient incluses, il peut être nécessaire de renuméroter pour combler les lacunes.

Il existe d'autres commutateurs que vous pourriez trouver utiles.

J'utilise la pellicule suivante pour obtenir un taux de trame plus lent, pour compresser les images et obtenir une vidéo plus petite:

ffmpeg.exe -f image2 -framerate 25 -pattern_type sequence -start_number 1234 -r 3 -i Imgp%04d.jpg -s 720x480 test.avi

L' -r 3option définit le nombre d'images par seconde de la vidéo obtenue sur 3 images par seconde afin que je puisse les voir toutes pendant une courte période. L' -soption redimensionne les images à la résolution souhaitée pour gérer la taille de la vidéo obtenue.

(Dans le shell Windows, remplacez -i Imgp%04d.jpgpar -i "Imgp%%04d.jpg". Merci à Mike Fitzpatrick https://superuser.com/a/344178/153054 )

Assad Ebrahim
la source
4
Quelle est la différence entre -r et -framerate?
1
ils sont les mêmes IIRC
rogerdpack
22
Pas besoin de numéroter des bêtises, tant que vous êtes heureux d'accepter l'ordre dans lequel elles apparaissent dans (par exemple) 'ls' ... utilisez simplement: ffmpeg -pattern_type glob -i '* .jpg' movie.mp4
Orwellophile
2
Existe-t-il un commutateur permettant de contrôler l’ écart temporel entre les images, par exemple, je voudrais afficher la première image 13s, la deuxième 15s, 24s pour la troisième, l’intervalle temporel est défini par l’utilisateur, est-ce possible?
Zionpi
2
voir aussi trac.ffmpeg.org/wiki/…
david.libremone
38

vous pouvez utiliser l'extrait de code ci-dessous:

 cat *.jpg | ffmpeg -f image2pipe -r 1 -vcodec mjpeg -i - -vcodec libx264 out.mp4

la source
Cela ne fait pas pivoter les fichiers JPG selon la rotation indiquée dans les métadonnées.
Erik Johansson
17

Vous pouvez trouver un exemple de script dans la documentation de ffmpeg :

3.2 Comment encoder des images uniques dans des films?

Si vous devez renommer un grand nombre d'images, vous pouvez utiliser la commande suivante pour alléger le fardeau. La commande, à l’aide de la syntaxe du shell bourne, lie symboliquement tous les fichiers du répertoire en cours correspondant à * jpg au /tmp' directory in the sequence offichier img001.jpg ', `img002.jpg', etc.

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done

Puis lancez:

ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
Gaizka
la source
2
Vous feriez mieux de faire x = 0 pour commencer afin que le nom de l'image commence img000.jpg car c'est ce à quoi ffmpeg s'attend. De plus, les liens symboliques ne fonctionnaient pas pour moi, car ffmpeg ne parvenait pas à trouver les fichiers; je devais donc utiliser cp (vitesse et encombrement évidents, mais je les récupère quand même). mv fonctionnerait également si vous ne craignez pas de perdre les originaux.
Notez que dans cette réponse, la commande fournie crée des liens physiques, et non des liens symboliques. En ce qui concerne l'utilisation de cpsi la liaison ne fonctionne pas, si votre système de fichiers le prend en charge, cp --reflink=autol'utilisation de la vitesse / de l'espace sera bien meilleure.
Félix Saparelli
12

De la documentation de ffmpeg:

Utiliser un motif glob

ffmpeg prend également en charge l’agencement de style bash (* représente un nombre quelconque de caractères).

Ceci est utile si vos images sont séquentielles mais pas nécessairement dans un ordre séquentiel numérique comme dans les exemples précédents.

ffmpeg -r 1 -pattern_type glob -i 'test_*.jpg' -c:v libx264 out.mp4

Donc, tant que vos fichiers sont triés, l'utilisation du -pattern_type globcommutateur devrait fonctionner pour vous.

Nevin Williams
la source
Notez que ce glob est plus limité que les globs de shell réguliers: trac.ffmpeg.org/ticket/3620 apparemment parce que le type d'image est déduit de l'extension.
Ciro Santilli a annoncé le
11

Autant que je sache, vous ne pouvez pas commencer la séquence de manière aléatoire (je ne me souviens pas si vous devriez la commencer à 0 ou 1), en plus, elle ne peut pas avoir de trous, si ffmpeg supposera que la séquence est terminée et arrêtez d'ajouter plus d'images.

En outre, comme indiqué dans les commentaires de ma réponse, rappelez-vous que vous devez spécifier la largeur de votre index. Comme:

image% 03d.jpg

Et si vous utilisez un type d'index% 03d, vous devez ajouter à 0 le nom de fichier, comme suit:

image001.jpg image002.jpg image003.jpg

etc.

Francisco Soto
la source
1
Si les noms de fichier image ont des zéros non significatifs, la chaîne de format doit également spécifier une largeur telle que "% 03d".
1
Si c'est le seul obstacle, vous pouvez simplement écrire un script pour renommer ou lier de manière symétrique vos images à un ensemble correctement réindexé.
Cascabel
1
Oui, j'ai déjà travaillé dessus, j'ai écrit il y a quelque temps un wrapper dans Ruby où vous avez appelé instance.addImage (), puis instance.processVideo () et cela créerait un répertoire temporel, copier / renommer les images avec les index appropriés et créer la vidéo. C'est assez facile.
@Jefromi J'ai créé un lien symbolique, mais comment puis-je donner le chemin du fichier de lien symbolique à ffmpeg? Cela suppose simplement que le fichier symlink est l'image que je tente de convertir? Je suis sur win7 btw
La séquence peut commencer de 0 à 4 inclus.
Assad Ebrahim
5

Je suis d'accord avec Francisco, mais comme solution de contournement, vous pouvez simplement écrire un script rapide pour déplacer ou créer des liens symboliques vers les fichiers avec les numéros de séquence nécessaires à ffmpeg. Le script pourrait alors appeler ffmpeg, puis supprimer les liens ou ramener les fichiers à leur emplacement d'origine.

Jason B
la source
1

Chercher

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i"
/tmp/img"$counter".jpg; x=$(($x+1)); done

la source
1

Je sais que c'est une vieille question, mais je l'ai trouvée dans Google en cherchant la même réponse. Aucune des réponses ici ne me satisfaisait complètement alors j'ai fait plus de recherches et de lectures et c'est une commande que j'ai formulée pour mon propre problème.

cat {0032..1501}*.png | ffmpeg -f image2pipe -framerate 5 -i - -s 720x480 test2.avi

La raison pour laquelle j'utiliserais une commande comme celle-ci est ...

  1. Cat et -f image2pipe vous permettent de mieux contrôler les images que vous utilisez. Par exemple, il vous permet d’utiliser des fonctionnalités bash telles que l’élargissement du support et d’autres commandes telles que grep pour affiner vos résultats si vous le souhaitez.
  2. Moins de commutateurs à retenir.
  3. Je recommande de NE PAS utiliser -r, mais simplement -framerate. Dans mon expérience, -r a tendance à perdre des images plus souvent.
  4. Moins complexe, pas de commutateurs inutiles utilisés et cela fonctionnera tel quel. Vous pouvez ajouter plus de complexité (par exemple, spécifier un encodeur) et ajuster au mieux vos besoins.
David Bobb
la source
Pour la question du PO, -start_numberc'est tout ce qui est nécessaire.
Gyan
0

J'utilise l'encodeur flv depuis que ma vidéo est enregistrée dans un lecteur flash (Jwplayer)

ffmpeg -i% d.jpg -vcodec flv test.flv


la source
0

D'après la documentation , il semble que vous puissiez simplement utiliser *

For example, for creating a video from filenames matching the glob pattern foo-*.jpeg:

ffmpeg -f image2 -pattern_type glob -framerate 12 -i 'foo-*.jpeg' -s WxH foo.avi

Il est à noter que pour améliorer la qualité, le débit en ips pourrait être important (par exemple, spécifier d'abord une fréquence d'images très basse / élevée, puis passer d'un deuxième filtre qui ramènera la vidéo au ralenti à la normale?)

ntg
la source
0

Dans mon cas, c'était un peu plus compliqué à cause des chiffres dans les fichiers. Voici à quoi ressemblent mes images:

$ ls | head -5
2014_aq_unprocessed 001.jpg
2014_aq_unprocessed 002.jpg
2014_aq_unprocessed 003.jpg
2014_aq_unprocessed 004.jpg
2014_aq_unprocessed 005.jpg

et voici la commande que j'ai utilisée:

ffmpeg -i 2014_aq_unprocessed\ %3d.jpg  -vcodec mpeg4 test.avi
Mona Jalal
la source
0

Vous pouvez le faire avec convert -morph:

convert *.jpg -delay 10 -morph 10 %05d.jpg

Si vous voulez utiliser ffmpeg, j'ai utilisé

ffmpeg -pattern_type glob -i '*.jpg' -vf "setpts=10*PTS" movie.mp4

où le 10*PTSffmpeg dit de le ralentir 10 fois. Vous pouvez également avoir des fractions pour accélérer le processus.

Martin Thoma
la source
Ceci consiste simplement à interpoler votre séquence d’image originale vers un nouvel espace, cela ne créera pas un fichier vidéo comme celui demandé par le PO.
F0ster
0

-pattern_type glob exemples concrets avec audio

Cette option a été mentionnée à l' adresse : https://superuser.com/a/782520/128124, mais voici quelques exemples concrets de son utilisation, notamment pour l'ajout d'audio à la sortie vidéo.

Diaporama vidéo avec une image par seconde

ffmpeg -framerate 1 -pattern_type glob -i '*.png' \
  -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

Ajoutez de la musique, coupez quand le son quand les images se terminent:

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
  -c:a copy -shortest -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

Voici deux démos sur YouTube:

Soyez un hippie et utilisez le format vidéo non-breveté de Theora :

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
  -c:a copy -shortest -c:v libtheora -r 30 -pix_fmt yuv420p out.ogg

Vos images doivent bien sûr être triées par ordre alphabétique, généralement comme suit:

0001-first-thing.jpg
0002-second-thing.jpg
0003-and-third.jpg

etc.

Voir aussi: http://unix.stackexchange.com/questions/68770/converting-png-frames-to-video-at-1-fps/339399#339399

Vidéo à vitesse normale avec une image par image à 30 ips

ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
  -c:v libx264 -pix_fmt yuv420p out.mp4

Voici à quoi ça ressemble:

GIF généré avec: https://askubuntu.com/questions/648603/how-to-create-an-animated-gif-from-mp4-video-via-command-line/837574#837574

Ajoutez de l'audio à cela:

ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
  -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4

Résultat: https://www.youtube.com/watch?v=HG7c7lldhM4

Convertir un fichier de musique en vidéo avec une image fixe pour le téléchargement sur YouTube

Réponse de: Comment convertir des MP3 au format vidéo autorisé par Youtube?

Obtenir des images d’entrée de test synthétiques

Voici les images de test que j'ai utilisées dans cette réponse:

wget -O opengl-rotating-triangle.zip https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.zip?raw=true
unzip opengl-rotating-triangle.zip
cd opengl-rotating-triangle
wget -O audio.ogg https://upload.wikimedia.org/wikipedia/commons/7/74/Alnitaque_%26_Moon_Shot_-_EURO_%28Extended_Mix%29.ogg

Images générées avec: https://stackoverflow.com/questions/3191978/how-to-use-glut-opengl-to-render-to-a-file/14324292#14324292

Il est intéressant d'observer à quel point la vidéo compresse mieux la séquence d'images que ZIP, car elle est capable de compresser des images à l'aide d'algorithmes spécialisés:

  • opengl-rotating-triangle.mp4: 340K
  • opengl-rotating-triangle.zip: 7,3M

À propos des options de l'interface de ligne de commande

Notez cependant que, malgré le nom, -globcela n’est pas aussi général que les modèles de Glob de shell, par exemple: -i '*'échoue: https://trac.ffmpeg.org/ticket/3620 (apparemment parce que le type de fichier est déduit de l’extension).

-r 30rend la -framerate 1vidéo 30 FPS pour surmonter les bugs dans les joueurs comme VLC pour low framerates: https://stackoverflow.com/questions/19267443/playback-issues-in-vlc-with-low-fps-video-from-images-using- ffmpeg / 41797724 # 41797724 Par conséquent, il répète chaque image 30 fois pour conserver l’effet souhaité d’une image par seconde.

Prochaines étapes

Vous voudrez aussi:

TODO: apprendre à couper et concaténer plusieurs fichiers audio dans la vidéo à partir de la ligne de commande:

Testé sur

ffmpeg 3.4.4, vlc 3.0.3, Ubuntu 18.04.

Bibliographie

Ciro Santilli 改造 中心 六四 事件
la source