I am working on a project that provides video streaming to the users over the internet on web-browsers as well as mobile devices.

I am using following sample FFMPEG command to transcode the video:

ffmpeg -y -i inputvideo.mp4 -async 1 -metadata:s:v:0 start_time=0 
-s 1280x720 -vcodec libx264 -strict experimental -pix_fmt yuv420p 
-profile:v baseline -movflags +faststart -acodec aac -profile:a aac_low 
-b:v 2000k -refs 6 -coder 1 -sc_threshold 40 -flags +loop -me_range 16 
-subq 7 -i_qfactor 0.71 -qcomp 0.6 -qdiff 4 -trellis 1 -b:a 128k outputvideo.mp4

The command is generated dynamically using programming language after getting the video details once uploaded. What am I doing is, just reset bit-rate, height and width of the video using following settings:

If height >= 720 then set it to 720, width will be automatically set according to height and bit-rate will be 5000k,

If height >= 480 then set it to 480, width will be automatically set according to height and bit-rate will be 2500k,

If height >= 360 then set it to 360, width will be automatically set according to height and bit-rate will be 1000k

I got this logic from this link.

However, I want to downgrade the quality of video by 25-30% more as still videos are of greater size than I suppose to get after transcoding and it will cost the data charges more.

While searching for it, I found another link and it have different bit rate than the one I am using. I am not sure which one is better.

Can anyone suggest me how to downsizing the videos more by 25-30% more than current setting without more affecting the quality of video?


1 Answer 1


Rather than using constant bitrate, have a go using constant quality (AKA constant rate factor, or crf).

So instead of -b:v 2000 use -crf 23 (adjust the number to change the quality, higher is smaller / lower quality and lower is larger / better quality).

Constant quality usually gives you more bang for your bits, as it skimps on bitrate where it's not really needed. It also removes the need for extra scripting for diferent sizes, as it will automatically lower the bitrate for smaller frame sizes.

You could also use the x264 presets, like -preset slower or -preset veryslow to get x264 to spend more time optimising. It also removes the need to add all the extra encoding flags — the presets are basically some ready-rolled encoding flags (presumably made by people who know what they're doing). More on x264 encoding here

So your command could look like:

ffmpeg -y -i inputvideo.mp4 -async 1 -metadata:s:v:0 start_time=0 -s 1280x720 -vcodec libx264 -pix_fmt yuv420p -profile:v baseline -movflags faststart -profile:a aac_low -preset slower -crf 23 -b:a 128k outputvideo.mp4

I don't think you need the -strict-experimental flag, unless you've got an old version of ffmpeg.

  • 1
    +1 for -crf. If you have the time, -crf 23 and veryslow can give very compact files with quite good quality.
    – Jim Mack
    Sep 2, 2015 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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