I have one image ~1MB (jpg) and a ~30 mins audio file ~7MB (m4a).

What I am trying to get is a final video that lasts like the audio file (30 mins) with the same image displayed. I get that with the following ffmpeg usage:

ffmpeg -loop 1 -i image.jpg -i audio.m4a -c:v copy -c:a copy -shortest -y video.mp4

The final result is correct but the size of the file is way far too big ~41GB as we consider the original size of the 2 files (image+audio ~8MB).

Is there a way to get a smaller size for the final video? I have used -r 1, -vf fps=1 etc but it didn't change.


Following your suggestions I have changed the command into this:

ffmpeg -loop 1 -r 1 -i image.jpg -i audio.m4a -c:a copy -vf fps=1 -shortest -y video.mp4

and now the final video size is dropped from 41GB to only 22MB and it built all in 2 mins.

Anyway it comes out a new issue: The image appears after 3/4 seconds that video is started. How can I fix that to have the image displayed from the beginning?

I think the solution for the delay is using fps=3.

  • just remove -c:v copy Jan 19 '16 at 22:13
  • @incBrain is a good practice also specify the codec that you want to use and some settings instead of relaying on defaults that can always change in future ;) Jan 19 '16 at 23:08
  • its actually not important in this case since we have only one input frame. So we actually can go with quite every codec. It is only important to remove this copy option because it tells ffmpeg not to change jpeg and replicate it with some framerate for some duration. But the best way to encode it would be to use IPPPPPPP......P structure. But I have no idea how to tell ffmpeg to do that. Jan 20 '16 at 0:25
  • @incBrain is indeed important, the encode you talking about is the compression strategy chosen by the codec. And there are some codecs that doesn't take advantage of intra - predictive frame scheme you talking about. Also if you don't specify the codec ffmpeg nowadays (in future who knows) pick h264 for you but in a lossy fashion, i don't think that one is the solution OP was searching for. Jan 20 '16 at 10:13
  • so your assumption is that ffmpeg will use less efficient codec by default in the future? Jan 20 '16 at 10:18

Just remove -c:v copy. So it should look like this:

ffmpeg -loop 1 -i image.jpg -i audio.m4a -c:a copy -shortest -y video.mp4

ffmpeg will select H.264 encoder to encode your image. You could also try -c:v libx264 -tune stillimage option. But probably the result will be similar.


You are right about -r 1 and -vf fps=1 but you said also that you have 30 mins audio, in this case even if you keep fps at 1 it will be still 1800 seconds, 1800 times the repetitions of the same image converted as bitmap data.

Different thing is if you start using a codec that could take advantage of the redundancy of the data present in the stream. For example, even using h264 in lossless fashion retaining the 100% of the quality will make you save a huge amount of disk space.

Take your video 41 GB video as input and try:

ffmpeg -i video.mp4 -c:v libx264 -preset slow -crf 0 output.mp4
  • ffmpeg will not create an I-frame for each second. Default keyframe distance is 250 frames, and there's no scene change here to trigger earlier placement by x264.
    – Gyan
    Jan 20 '16 at 5:35
  • @Mulvya Ok for the default keyframe distance but he used copy as codec with a jpeg input not h264 in his original post, how h264 scene change detection algorithm is pulled in in this case? Jan 20 '16 at 10:15
  • Ah, I just tested the OP's command and expected an error or warning but got none. Turns out that although MJPEG isn't an ISO registered codec for MP4, it is an Apple registered one, so ffmpeg generates a MJPEG stream with a major brand of M4A for the .mp4. So, yeah x264 does not come into the OP's command.
    – Gyan
    Jan 20 '16 at 10:54


ffmpeg -loop 1 -framerate 1 -i image.jpg -i audio.m4a -c:a copy -fflags +genpts -shortest -y video.mp4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.