Combinez une image + un fichier audio pour créer une vidéo à l'aide de FFmpeg

184

Cela devrait être assez trivial, mais je ne peux pas trouver un moyen de le faire fonctionner.

Je veux que FFmpeg prenne une image JPEG et un fichier audio en entrée et génère un fichier vidéo de la même durée que le fichier audio (en étirant l'image fixe pendant toute la durée).

Peu m'importe le codec vidéo utilisé pour la sortie, mais il est essentiel de pouvoir utiliser "copier" comme codec audio (c.-à-d. Copier le flux audio sans le transcoder).

Quelle est la bonne ligne de commande qui ferait cela?

J'ai essayé:

ffmpeg -i image8.jpg -i sound11.amr -acodec copy test.avi

et essayé beaucoup de combinaisons avec et sans -s 640x360, -loop_input, -shortest, -t xxx, -r 0.1(artificiellement bas taux de trame dans l'espoir que la vidéo serait plus) et-f image2

Ou je reçois des erreurs ou je reçois un fichier vidéo d'une durée d'une image.

J'ai cherché sur Google et trouvé une douzaine de solutions proposées (supposées répondre à la même question), mais aucune ne fonctionne.

Quelqu'un peut-il suggérer un commandement de travail et expliquer la raison derrière ce choix?

matteo
la source
Je viens d'essayer votre ligne de commande et cela a fonctionné comme prévu. Votre problème pourrait venir du format sonore. Le transcodage du son fonctionne-t-il?
Capitaine Giraffe,
Par "comme prévu" voulez-vous dire que la vidéo résultante a la même durée que l'entrée audio? Avez-vous joué? N'est-ce pas une image longue?
Matteo
Le format sonore n’est pas le problème, transcoder les œuvres sonores
lundi
J'ai eu un problème de commande de paramètres aussi et ça m'a coûté des heures! Dommage que ce genre de problèmes ne soit pas couvert dans l'aide. gregoire.org/2009/12/05/fun-with-ffmpeg
Paul Gregoire
3
c'est mieux que la réponse choisie, j'ai expérimenté et c'est rapide et la taille du fichier est petit ..ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.avi
Muhammad Umer

Réponses:

146

L'ordre des options dans la ligne de commande est important. Ce qui suit fonctionne pour mon cas:

ffmpeg -loop 1 -y -i image8.jpg -i sound11.amr -shortest -acodec copy -vcodec mjpeg result.avi

Dans un cas plus général, où image.jpget audio.wavsont votre entrée, vous pouvez utiliser la commande suivante, adaptée du wiki de FFmpeg :

ffmpeg -loop 1 -i image.jpg -i audio.wav -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -shortest out.mp4

Cela utiliserait l' libx264encodeur et vous fournirait une meilleure compression que le codec MJPEG utilisé ci-dessus. L'audio est AAC, avec l' ffmpegencodeur AAC intégré .

matteo
la source
5
Comment se fait-il que les fichiers soient tellement plus volumineux que [taille de l'image] + [taille du fichier audio]? Je m'attendrais à ce que la compression vidéo devienne folle avec une image constante?
Alec Jacobson le
2
Cela dépend du codec vidéo que vous utilisez. Si vous copiez les commandes dans mes exemples, j'utilise mjpeg comme codec, qui compresse chaque image séparément, de sorte que le fait que toutes les images soient égales ne présente aucun avantage. De plus, je pense que même les autres codecs recodent la totalité de la trame de temps en temps, c’est-à-dire chaque trentième trame, afin d’obtenir un fichier beaucoup plus petit mais bien plus grand que la taille de l’image + son. Ils le font parce que (a) sinon le décodeur aurait besoin de lire le fichier entier depuis le début, même si vous voulez juste passer à la dernière image, et
matteo
2
Option shortest (finish encoding within shortest input) cannot be applied to input file image.jpg -- you are trying to apply an input option to an output file or vice versa. Move this option before the file it belongs to.
wim
2
utiliser ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.avicela fonctionne mieux !!!?! ??!?!
Muhammad Umer
2
Cette réponse est en cours de discussion sur la méta.
DavidPostill
41

Vous rendre ainsi plus difficile qu'il doit être. FFmpeg est bien plus intelligent que vous ne le croyez - il sait que vous voulez que la vidéo ait la même longueur que votre piste audio.

ffmpeg -i still.png -i narrate.wav -acodec libvo_aacenc -vcodec libx264 final.flv

pause

Les seuls attributs que vous devez spécifier sont le input filenames, le output codecset le output filename(ce qui inclut ipsooutput container , le ,).

Bien entendu, il est judicieux de commencer par une image fixe qui partage les mêmes dimensions que votre éventuelle vidéo. Si vous utilisez un éditeur d'image dédié au lieu de spécifier les dimensions de sortie que FFmpeg doit respecter, vous devez vous assurer que vos dimensions d'entrée sont des nombres pairs .

La taille de sortie est l’ un des problèmes les plus courants de FFmpeg; Certains codecs ont des dimensions de sortie plus limitées que d'autres, mais aucune sortie ne peut avoir d'attribut de hauteur ou de largeur de numéro impair.

La pausecommande située à la fin du fichier de commandes maintient la CLI ouverte. La meilleure façon de déboguer votre ligne de commande consiste à lire les messages d'erreur générés. Ils sont extrêmement spécifiques - et constituent la meilleure documentation de FFmpeg - mais le travail ardu des développeurs est perdu si vous laissez la fenêtre se fermer avant de pouvoir la lire.

L'interpréteur de commande a un commutateur cmd /kqui maintient une fenêtre ouverte dans laquelle vous pouvez exécuter les mêmes instructions à partir de votre script batch à l'invite de commande.

FFmpeg et avconv seront à la fois vous faire utiliser -c:apour -acodecet -c:vpour la -vcodecsuite, mais les anciennes instructions fonctionnent très bien dans les builds que j'utilise.

Nota Bene: Chaque commit a ses particularités. Si votre ligne de commande échoue sans raison apparente, il est souvent utile d'essayer une autre version - ou de suivre la fourchette jusqu'à libav , où se trouvent actuellement les développeurs les plus actifs de FFmpeg. Leur outil de transcodage a été renommé avconv, mais vos fichiers de commandes doivent fonctionner avec l’un ou l’autre.


la source
Je dois utiliser une version différente de la votre (si vous avez essayé votre commande et que cela fonctionne comme vous le décrivez), car, comme je l’ai déjà mentionné dans la question, j’avais déjà essayé votre commande exacte et que je recevais une vidéo de la durée. de 1 image (une fraction de seconde), PAS la durée du fichier audio. Je m'attendais à ce qu'il soit intelligent, mais (dans ma version), il s'est avéré que non.
Matteo
2
Salut Matteo , oui, j'ai exécuté ce code et, oui, il fonctionne comme annoncé. Je suis sûr qu'il y a beaucoup de demi-sorciers qui seraient si négligents que de faire de telles affirmations sans les tester, je vais donc essayer de ne pas être offensés :) Dans un post complet ci-dessous, je fournirai des liens Pastebin vers la sortie de la console FFmpeg et MediaInfo. données sur les fichiers d'entrée et le fichier de sortie final. Mes fichiers d'entrée, mon fichier de commandes et mon fichier de sortie se trouvent sur un lecteur GoogleDrive où ils sont librement téléchargeables , si vous souhaitez les tester par rapport à votre version de FFmpeg.
@ShinMuraoka Mine is a win-64 ffmpeg build compiled on: Jan 6 2013, at: 16:16:53Ni votre solution ni la solution @matteo n'ont fonctionné pour moi. De plus, j'ai téléchargé vos fichiers à partir de Google Drive, mais cela ne donnait pas la sortie attendue (le fichier de sortie était en noir et ne contenait que de l'audio). S'il vous plaît aidez-moi à trouver la bonne commande à utiliser.
coding_idiot
2
"aucune sortie ne peut avoir d'attributs de hauteur ou de largeur de numéro impair". Définissez pix_fmt sur quelque chose qui n'a pas de sous-échantillonnage de la chrominance, comme rgb24 ou yuv444p, puis assurez-vous que le codec et le conteneur le prennent en charge et ne sont soumis à aucune restriction. En ce qui concerne pix_fmt, FFmpeg est moins qu'intelligent; il suppose yuv420p (avec un sous-échantillonnage de la chrominance), sauf indication contraire de votre part.
Jonathan Baldwin
Qu'en est-il des images multiples? J'ai besoin que l'image change à un moment donné en une autre image. Je voudrais pouvoir les spécifier sur la ligne de commande avec un paramètre de temps pour chacun.
36

Encore plus facile:

ffmpeg -i ep1.png -i ep1.wav ep1.flv

FFmpeg essaiera de choisir automatiquement le meilleur codec, en fonction de l’extension de votre fichier de sortie.

Mise à jour: j'ai remarqué que YouTube avait du mal à traiter la vidéo (elle reste bloquée à 95%), car il n'y a qu'une seule image. La solution que j'ai trouvée pour rendre YouTube heureux: ajouter plus de cadres. En outre, j'ai ajouté -acodec copypour préserver la qualité audio. Vous avez besoin -shortestou ça boucle pour toujours. (Il s’arrête à la fin du flux le plus court, l’audio, car la boucle image est infinie.) L’ordre des options est très important pour la rapidité, car les filtres (et autres) sont traités dans l’ordre que vous spécifiez. Si vous modifiez l'ordre de ces paramètres, les résultats sont radicalement différents.

ffmpeg -r 1 -loop 1 -i ep1.jpg -i ep1.wav -acodec copy -r 1 -shortest -vf scale=1280:720 ep1.flv

Notez également que je règle la cadence deux fois, ce n’est pas un hasard: la première cadence concerne l’entrée, la seconde la sortie. Si vous le faites correctement, il ne devrait y avoir qu'une image par seconde de vidéo, ce qui signifie que le codage est relativement rapide. De plus, je règle ici la résolution sur 720p, ce qui signifie que vous devriez obtenir de l'audio HD sur YouTube :-)

PJ Brunet
la source
Il est également possible que votre fichier audio ne soit pas compatible avec votre conteneur .flv. Dans ce cas, vous devriez simplement essayer un conteneur (de sortie) différent, tel que .webm, .avi ou autre, jusqu'à ce que vous trouviez un format de conteneur compatible avec votre fichier audio.
PJ Brunet
1
Utilisé cela pour un .JPG et .MP3 pour faire un MP4 - a fonctionné parfaitement. Le fichier FLV que j’ai créé à partir du fichier JPG / MP3 ne semble pas fonctionner - ce qui peut être conforme à l’avertissement de commentaires précédents.
2
La version mise à jour fonctionne pour Youtube. Je pensais que c'était bloqué à 95% mais finalement ça a fonctionné.
Basj
a obtenu ceci: No pixel format specified, yuvj420p for H.264 encoding chosen. Use -pix_fmt yuv420p for compatibility with outdated media players. [libx264 @ 0x2b5c940] height not divisible by 2 (700x457)... cela fonctionne:ffmpeg -r 1 -loop 1 -i ep1.jpg -i ep1.wav -acodec copy -r 1 -shortest -vf scale=1280:-2 video.mp4
NineCattoRules
Qu'en est-il des images multiples? J'ai besoin que l'image change à un moment donné en une autre image. Je voudrais pouvoir les spécifier sur la ligne de commande avec un paramètre de temps pour chacun.
14

La version qui a fonctionné pour moi:

 ffmpeg -loop 1 -y -i pic.jpg -i sound.amr -shortest video.mp4

Checkout l'option -shortestdoit être devant le fichier de sortie sinon j'obtiens l'erreur ci-dessous:

L'option la plus courte (terminer le codage dans l'entrée la plus courte) ne peut pas être appliquée au fichier d'entrée pic.jpg - vous essayez d'appliquer une option d'entrée à un fichier de sortie ou inversement. Déplacez cette option avant le fichier auquel elle appartient. Erreur lors de l'analyse des options pour le fichier d'entrée pic.jpg.

fguillen
la source
Merci pour cela. La plupart des autres réponses n'ont pas fonctionné pour moi (utilisation de ffmpeg sur Alpine linux). Cette réponse a la commande la plus courte qui a fonctionné sans faille pour moi.
DannyB
8

De la page de manuel ffmpeg:

ffmpeg [[infile options][-i infile]]... {[outfile options] outfile}...

Comme vous l'avez découvert, les options infiles doivent précéder l'infile auquel elles s'appliquent.

Ce n’est pas un bogue, c’est juste un mécanisme permettant de spécifier les arguments infiles s’appliquant à.

ComputerDruid
la source
Qu'en est-il des images multiples? J'ai besoin que l'image change à un moment donné en une autre image. Je voudrais pouvoir les spécifier sur la ligne de commande avec un paramètre de temps pour chacun.
4

Cela a fonctionné pour moi

ffmpeg -loop 1 -shortest -y -i image.jpg -i audio.mp3 -acodec copie -vcodec libx264 video.avi

J'ai trouvé vcodec libx264créé des fichiers beaucoup plus petits que mpjeg(10 Mo au lieu de 100 Mo).

Colonel Panic
la source
1
-shortestest une option de sortie et peut être ignoré en tant qu'option d'entrée lorsque vous l'utilisez.
llogan
1

J'essayais de faire comme @matteo , mais sans l'audio, et la solution de @Colonel Panic fonctionnait mieux:

ffmpeg -loop 1 -shortest -y -i still.png -vcodec libx264 -t 10 video.avi

Je n'avais qu'à ajouter un argument de durée en secondes ( -t 10).


la source
-shortestest une option de sortie, mais vous l'utilisez comme option d'entrée. Déplacez-le avant le fichier de sortie et vous pourrez éliminer le -t 10, mais votre réponse sera sensiblement la même que les autres.
llogan
0

ffmpeg -loop 1 -i img.jpg -i audio.wav -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest out.mp4


la source
5
Pouvez-vous expliquer comment la commande que vous avez ajoutée fonctionne?
Neelsg
Cette réponse n’est pas très différente de l’autre simple "commentaire-réponses" ici.
llogan
0

Si quelqu'un souhaite les convertir par lots, essayez ceci.

Vous pouvez définir le dossier d'entrée et de sortie, ainsi que le format dans lequel vous voulez que la vidéo soit insérée. Dans ce cas, je le règle sur AVI.

Cette réponse Combiner une image + un fichier audio pour créer une vidéo à l'aide de FFmpeg m'a beaucoup aidé.

 @echo off
 set "sourcedir=C:\Users\CodeHard\Desktop\BOX\Newfolder"  
 set "outputdir=C:\Users\CodeHard\Desktop\BOX\Converted" 

 PUSHD "%sourcedir%"

 for %%F in (*.mp3) DO ffmpeg -r 1 -loop 1 -i abc.jpeg -i "%%F" -acodec copy -r 1 -shortest -vf scale=1280:720 "%outputdir%\%%F.avi"  

 POPD
Suraj Jain
la source
-1

Essayez cette commande. C'est travaillé pour moi.

-y -i /storage/emulated/0/images.jpg -i /storage/emulated/0/audio.wav -acodec aac -vcodec mpeg4 -s 480*320 -f mp4 -r 2 /storage/emulated/0/output.mp4"
Phani Varma
la source
2
Ceci est une commande incomplète qui ne pourrait probablement pas fonctionner. Bien que je puisse réparer et déboguer votre commande, je ne ferai pas votre travail pour vous. Modifiez donc votre réponse et corrigez-la vous-même. J'ai également remarqué que la taille de votre vidéo n'était pas celle que voulait matteo.
Karel