Combine one image + one audio file to make one video using FFmpeg

The order of options in the command line matters. The following works for my case:

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

In a more general case, where image.jpg and audio.wav are your input, you can use the following command, adapted from the FFmpeg wiki:

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

This would use the libx264 encoder and provide you with better compression than the MJPEG codec used above. The audio is AAC, with the built-in ffmpeg AAC encoder.


Even easier:

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

FFmpeg will try to pick the best codec automatically, depending on the extension of your output file.

Update: I noticed YouTube has difficulty processing the video (gets stuck at 95%) I think because there's only one frame. The solution I found to make YouTube happy: add more frames. Also, I added-acodec copy to preserve the audio quality. You need -shortest or it loops forever. (It stops at the end of the shortest stream, which is the audio, because the image loop is infinite.) The order of your options is very important for speed, as filters (and such) are processed in the order you specify. If you change the order of these parameters, the results are dramatically different.

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

Also notice that I set the frame rate twice, that's not an accident--the first frame rate is for the input, second is for the output. If you do this correctly, there should only be one frame per second of video, which means it encodes relatively fast. Also I set the resolution to 720p here, which means you should get HD audio on YouTube :-)


You're making it way harder than it has to be. FFmpeg is a lot smarter than you give it credit for--it knows you want the video to be the same length as your audio track.

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

pause

The only attributes you have to specify are the input filenames, the output codecs, and the output filename (which eo ipso includes the output container, ).

Of course, it makes sense to start with a still image that shares the same dimensions as your eventual video; if you are using a dedicated image editor instead of specifying output dimensions for FFmpeg to meet, you need to make sure your input dimensions are even numbers.

Output size is one of FFmpeg's most common hang-ups; some codecs are more restricted in output dimensions than others, but no output can have odd-number height- or width attributes.

The pause command at the end of the batch file keeps the CLI open--the best way to debug your command line is by reading the error messages it generates. They are extremely specific--and the best documentation FFmpeg has--but the developers' hard work is wasted if you allow the window to close before you can read them.

The command shell has a switch cmd /k that maintains an open window where you can run the same the same instructions from your batch script at the command prompt.

FFmpeg and avconv will both make you use -c:a for -acodec and -c:v for -vcodec eventually, but the old instructions work fine in the builds I use.

Nota Bene: Every commit has idiosyncracies. If your command line is failing for no apparent reason, it is often helpful to try another build--or follow the fork over to libav, where FFmpeg's most active developers have been for the last couple of years. Their transcoding tool has been renamed avconv but your batch files should work with either one.