Is there a way to set the maximum final size for video converting using ffmpeg (or any other CLI based video converter)?

Like if I have an 100mb video and want to convert it to a 10mb video with the highest quality possible, considering the final format isn't important.


Going from 100mb to 10mb is a slightly unrealistic 90% drop in size but I will give an example of reducing to 50mb creating an H.264 video, which is a more reasonable 50% reduction in size as well as reducing to 40mb using HEVC.

I am using the following sample file:

wget http://dl3.h265files.com/TearsOfSteel_720p_h265.mkv

You can use this sample file to confirm the following results that I have given and perhaps experiment a little further yourself. MediaInfo reveals the following for this downloaded file:

mediainfo \
--Inform="General;Duration=%Duration/String3%\nFile size=%FileSize/String1%" \
Duration=00:12:14.058   <-----
File size=101 MiB       <-----

The arrows of course are my own! You then perhaps have 2 really good choices:

  1. Re-Encode to H.264
  2. Re-encode to HEVC

1. Re-Encode to H.264 (50mb)

H.264 is widely accepted now and would be an excellent choice for your output video file. The formula to calculate the output bitrate for the desired 50mb would then be:

(50 MiB * 8192 [converts MiB to kBit]) / 734 seconds = ~558 kBit/s total bitrate
558 - 128 kBit/s (desired audio bitrate) = 430 kBit/s video bitrate

To accomplish this use the following FFmpeg 2 pass command:

ffmpeg -y -i TearsOfSteel_720p_h265.mkv \
      -c:v libx264 -b:v 430k -pass 1 \
      -c:a libmp3lame -b:a 128k -f mp4 /dev/null && \
ffmpeg -i TearsOfSteel_720p_h265.mkv \
       -c:v libx264 -b:v 430k -pass 2 \
       -c:a libmp3lame -b:a 128k TearsOfSteel_smaller.mp4

The resulting file size is 49.4MiB with quite reasonable, but not amazing, viewing quality. Pretty good for a 50% reduction in file size and a huge drop in video bitrate actually!

2. Re-encode to HEVC (40mb)

Another choice (as suggested by emk2203) is to re-encode the existing HEVC stream with a lower bitrate, this time aiming for 40mb as HEVC claims better quality at a lower bitrate.

This time the formula would be:

(40 MiB * 8192 [converts MiB to kBit]) / 734 seconds = ~446 kBit/s total bitrate
446 - 128 kBit/s (desired audio bitrate) = 318 kBit/s video bitrate

and the FFmpeg 2 pass command line is:

ffmpeg -y -i TearsOfSteel_720p_h265.mkv \
      -c:v libx265 -x265-params pass=1 -b:v 318k \
      -c:a libmp3lame -b:a 128k -f mp4 /dev/null && \
ffmpeg -i TearsOfSteel_720p_h265.mkv \
       -c:v libx265 -x265-params pass=2 -b:v 318k \
       -c:a libmp3lame -b:a 128k TearsOfSteel_smaller.mp4

And this provides a 40mb file with quite reasonable quality.

In conclusion:

From these example you can experiment further by decreasing the required MiB in the formula and observing the subsequent viewing quality. Have Fun!!


| improve this answer | |
  • Any comment about the libx264 video codec? The rest is well detailed. – Asme Just Apr 25 '18 at 19:32
  • @AsmeJust Added some comments :) – andrew.46 Apr 25 '18 at 23:04
  • 1
    Going to the old H.264 codec is not a good idea in this situation. H.265 was especially made for bitrate-starved situations like this one, where OP wants to compress to 10% of the original size. So, a better solution would be to keep H.265 with a 'lib265' part in the ffmpeg lines. OPs demands here make H.265 practically mandatory. It's the only format which can do extreme compression and still retain a modicum of image quality. – emk2203 Apr 25 '18 at 23:51
  • @emk2203 Good point. Mind you if you do the maths for a 10mb encode for this file you will see that the target bitrate for either H.264 or HEVC is actually negative 16MiB :). I will however add an example in for HEVC re-encoding after finding the sweet spot for file size and at least respectable video quality... – andrew.46 Apr 26 '18 at 0:33
  • @emk2203 Added an example in.... – andrew.46 Apr 26 '18 at 1:42

Yes. Choose a video codec (x264 is a good universal one) and choose the resolution, leave most settings at default, but do a 2-pass conversion with a set average bitrate.

Quick lesson in video compression: video complexity changes throughout the video, so if you compress to the same visual quality level the whole way through, actual bitrate is going to fluctuate up and down. If you compress to a fixed bitrate, the quality is going to be bad in bits of high complexity because the bitrate is too low, and/or the bitrate used will be too high for the parts of low complexity. So as much as you can you let it aim for a constant quality and let the bitrate fluctuate as it may. But if the compressor is aiming for a particular file size it doesn't know whether the video complexity is going to go up or down in the parts it hasn't converted yet, so that's why people use a 2 pass conversion when aiming for a particular file size.

You need to specify the output as a bitrate (audio and video, plus the container has a slight overhead), so you need a calculator to convert from filesize and duration to a bitrate.

| improve this answer | |
  • Can you give an example please? Notes, The quality isn't really important for me, Even though I want it to be the highest possible. – Asme Just Apr 23 '18 at 5:24

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.