web-dev-qa-db-fra.com

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

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).

Je ne me soucie pas beaucoup de savoir quel codec vidéo est utilisé pour la sortie, mais il est essentiel que je puisse 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 (fréquence d'images artificiellement basse dans l'espoir que la vidéo serait plus longue) 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ément à cette même question) dont aucune ne fonctionne.

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

172
matteo

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.jpg et audio.wav sont votre entrée, vous pouvez utiliser la commande suivante, adaptée de 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 le codeur libx264 et vous fournirait une meilleure compression que le codec MJPEG utilisé ci-dessus. L’audio est AAC, avec l’encodeur ffmpeg AAC intégré.

134
matteo

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 rencontrait des difficultés pour traiter la vidéo (reste bloqué à 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. De plus, j'ai ajouté -acodec copy pour préserver la qualité audio. Vous avez besoin de -shortest ou il 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 :-)

33
PJ Brunet

La version qui a fonctionné pour moi:

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

Vérifiez que l'option -shortest doit se trouver devant le fichier de sortie sinon je reçois 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.

14
fguillen

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 à.

8
ComputerDruid

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é que vcodec libx264 a créé des fichiers beaucoup plus petits que mpjeg (10 Mo au lieu de 100 Mo).

4
Colonel Panic

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).

1
user284130

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

0
user3535334

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 faire une vidéo en utilisant 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
0
Suraj Jain