Reducing bitrate with ffmpeg using `-b:v 500k` doesn't actually reduce bitrate to 500k
I am trying to create several downgraded versions of a video file with ffmpeg. I am using the following command via the command line (the command is taken from the documentation):
ffmpeg -i ../../tos.avi -b:v 500k tos_500k.avi
I am trying this with several values below 2000 kbps (down to ~125 kbps), however the bottom limit that gets actually produced when I check the generated video files is at about 2000 kbps. I am checking the values using the software videospec.
- Does anyone have an idea why reducing the bitrate further doesn't seem to have any effect?
- Can you give me a hint how I can effectively reduce the bitrate of a video to a given level?
[EDIT] To be a bit more precise, my original video has a resolution of 1920x1080 with a bitrate of about 15 Mbps. When using the above command, I am able to downgrade it without issues to larger bitrates such as 8000, 5000, down to 2000 kbps. However, anything below 2000 doesn't seem to get handled, resulting output files are always stuck at a bitrate of a bit over 2000 kbps. (The file size is also very close to the file that was successfully downgraded to 2000 kbps.)
Solution 1:
When re-encoding a file, you shouldn't just specify a bitrate. My guess is that ffmpeg tries to use the mpeg4 codec by default, and it refuses to use less than 2mbps because it simply can't go below with such a high resolution.
I suggest you re-encode with the H.264 codec which you can do like this :
ffmpeg -i ../../tos.avi -c:v libx264 -b:v 500k tos_500k.mp4
Please note however that this will use a 1-pass average bitrate method which is pretty bad for quality. Instead, you should try encoding with "constant rate factor", i.e. you target a certain quality and the encoder decides which average bitrate is the best for your file :
ffmpeg -i ../../tos.avi -c:v libx264 -crf 23 tos_500k.mp4
You're free to experiment with the crf value. Increasing it will mean lower bitrate and worse quality, lowering it vice versa.
If you absolutely want to target an average bitrate, you should checkout 2-pass encoding. Also, don't forget about presets !
As a side note, 500k for 1080p is way too low and you will get poor results. If you wish to target such a low bitrate, I suggest you downscale to 480p (854x480). 720p should have a minimum of 1,5mbps bitrate and 1080p 3mbps.
For your future questions, don't forget to post the input/output logs from ffmpeg, they're always helpful :-) .
Solution 2:
500K is not sufficient for 1080p resolution at all eve on H264 or H265 you will bad image quality , since their is no enough data to fill the big frame size , as @Ely mention you should specified the encoder too even I think recent version of ffmpeg uses h264 by default if you specify file extension as .mp4 Your converting command should looks like this :-
ffmpeg -i ../../tos.avi -s 640x360 -v:c libx264 -b:v 500k tos_500k.mp4
and if you want more compression and trade with best possible quality for the size
use crf
Constant Rate Factor
with two pass converting method , since it will try to spread the bitrate according the each frame status (moving fast scene ) will get more bitrate .
ffmpeg -y -i ../../tos.avi -s 640x360 -c:v libx264 -crf 23 -pass 1 -c:a aac -f mp4 /dev/null && \
ffmpeg -i ../../tos.avi -s 640x360 -c:v libx264 -crf 23 -pass 2 -c:a aac tos_500k.mp4
if you still not satisfied with file size increase crf value until you reach ~27