10

Hi I m using ffmpeg to add a.jpg to an.mp3 to make an.mp4

As there is only one image added to the video. I m wondering if there is a way to reduce the video size eg force bit rate/second = 1 instead of 28 ?

As it is a still image, no need to change. just stay still.

Updated:

a.jpg = 26.7K (image not so clear)
a.mp3 = 64.6M (54 minutes)
a.mp4 = 80.6M (video result is not so clear, music still good)

And here is the cmd line:

$ ffmpeg -loop 1 -i a.jpg -i a.mp3 -shortest -acodec copy a.mp4

And I did another test with reasonable size of image of acceptable video quality:

a.jpg = 151K
a.mp3 = 5.1M (5 minutes)
a.mp4 = 9.2M

And here is the output result:

enter image description here

Is it a reasonable size for mp4? Does image size matter a lot? Should I resize jpg to 1080 * 720, and make additional settings in ffmpeg to output as 720p (what is the ffmpeg setting then :) ?

  • Could you please post the ffmpeg command you use? – ridgy Jan 5 '17 at 11:07
  • Please don't make images of (some of the) text, but copy and paste it instead. Images are big, can't be searched, and can't be copied from. – llogan Jan 6 '17 at 3:49
  • oops yes sir. i have closed the cmd window, so can not paste you the text now :| – SIDU Jan 6 '17 at 3:54
  • I wonder if it is possible to meta mp4 so that it plays mp3 only and keep screen fixed on one jpg to save size :) – SIDU Jan 6 '17 at 3:57
  • What is the target player, device, or site for the output? – llogan Jan 6 '17 at 4:13
15

For uploading to YouTube

ffmpeg -loop 1 -framerate 1 -i image.jpg -i music.mp3 \
-c:v libx264 -preset veryslow -crf 0 -c:a copy -shortest output.mkv
  • YouTube accepts just about anything so this command uses a few tricks to make encoding faster, make the file size small, and to keep quality high because YouTube will re-encode whatever you give it.

  • In this example a low frame rate is used which should encode much quicker. Your player may not like it but YouTube should be able to handle it.

  • You could use libx265 instead for libx264, but it will encode slower for little or no file size difference and no quality difference since lossless mode is being used in this command (-crf 0).

Widest compatibility for any player

ffmpeg -loop 1 -i image.png -i music.mp3 -vf "scale='min(1280,iw)':-2,format=yuv420p" \
-c:v libx264 -preset veryslow -profile:v main -c:a aac -shortest -movflags +faststart output.mp4
  • This should play on just about anything except very ancient devices (change -profile:v main to -profile:v baseline if that is the case).

  • Encoding time will be longer and file size will be bigger than the YouTube command above.

  • Could you provide a line of code to make a.jpg + a.mp3 = a.mp4 in 1280 * 720 with lowest frames/sec allowed by youtube ? Also as there is only one job, do i need to delete "-loop 1" ? Thanks in advance. – SIDU Jan 6 '17 at 22:23
  • @SIDU The existing command does what you request (other than outputting MKV instead of MP4), but I don't know the lowest frame rate supported by YouTube is. You'll just have to experiment. Why do you require MP4 when you are just uploading to YouTube? – llogan Jan 8 '17 at 0:08
  • I tried it but it says: Unrecognized option 'preset'. Error splitting the argument list: Option not found – NineCattoRules Mar 3 '17 at 9:15
  • @NineCattoRules Hard to say without more info. Use a pastebin site to show your full ffmpeg command and the complete console output from the command, then provide the link in a comment. – llogan Mar 3 '17 at 18:06
  • Thanks, I reinstalled FFMPEG using mc3man repository and now works well! – NineCattoRules Mar 3 '17 at 18:09
3

With only the information you provided this what I can think of.

Let's go by pieces:

As there is only one image added to the video. I m wondering if there is a way to reduce the video size eg force bit rate/second = 1 instead of 28 ?

As it is a still image, no need to change. just stay still.

What you're talking about there it's frames per second (fps) not bitrate. And you're right in the concept. Beign just one still image 1 fps wouldn't be a problem.

Is it a reasonable size for mp4? Does image size matter a lot?

In this case image size wouldn't have a significant weight because we are dealing with just one still picture. If it were a high quality video then it's a different issue.

Should I resize jpg to 1080 * 720, and make additional settings in ffmpeg to output as 720p (what is the ffmpeg setting then :) ?

The resolution you are saying it's 1280x720.

I dont' see the point in the -loop 1 option here, it will only slow down the process. Did you use -shortest cause the file has more than 1 input stream? If no then there's no reason to use it. Since you used -acodec copy I will have to assume that you don't want to re-encode it.

For an output of 720p 1fps without re-encoding and not touching bitrate:

ffmpeg -framerate 1 -i input.mp3 -i cover.jpg -c:a copy -s 1280x720 output.mp4

Beign the case that it has more than one input stream and you want ffmpeg to finish encoding at the shortest stream then:

ffmpeg -framerate 1 -i input.mp3 -i cover.jpg -c:a copy -s 1280x720 -shortest output.mp4

Now if you have to change the bitrate (let's say 1024k as an example);

ffmpeg -framerate 1 -i input.mp3 -i cover.jpg -c:a copy -b:v 1024k -bufsize 1024k -s 1280x720 output.mp4

See: Limit the output bitrate

-c:a copy = Copy the input audio stream so we not re-encode.

-b:v = The bitrate specified to be (not precisely) constant.

-bufsize = It's the interval in which calculates the average bitrate. Meaning the lowest more loss quality image but more accurate bitrates according to the specified in -b:v.

-s = The actual size of the video output.

-framerate = The input frame rate we want that the output will use.

Note that if you still want a smaller size video at one point you will have to sacrifice quality in order to achieve that. And other ways to do it involve re-encoding with lossy compression.

From what you say, the information you provide and what you are trying to do I think it seems that your target is to embed album-art to mp3. If that's your goal this would fit your requirements better:

ffmpeg -i input.mp3 -i cover.jpg -map_metadata 0 -map 0 -map 1 output.mp3

-map_metadata = The ffmpeg metadata specifier to output file from infile. In this case (zero) the global metadata.

-map 0 = Input stream 1 (audio).

-map 1 = Input stream 2 (image).

If nothing here suits your requests please give more information.

  • Consider using -framerate as an input option and removing the output -r: otherwise the default input framerate of 25 will be used and then ffmpeg will drop frames to achieve -r 1. If you just declare the input frame rate then the output will use the same frame rate. – llogan Jan 6 '17 at 19:07
  • Thanks. Didn't know that. Edited to reflect the changes suggested. – Fenrir Jan 6 '17 at 19:32
  • Thanks for the tutorial. My origianl ffmpeg line of code was a copy-paste from google search, which I have no idea what is what. – SIDU Jan 6 '17 at 22:27

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.