1

I want to reduce the size of a video to be able to send it via email and such. I looked at this question where I got good advice on how to reduce it. Problem is that I need to manually calculate the bitrate. And also when doing this I had to finish of with manual trial and error.

Is there any good way to use ffmpeg (or another tool) to reduce the size of a video to a target size?

Note due to a comment from frostschutz:

Worrying too much about size and going for a fixed filesize regardless of video length / resolution / framerate / content will not give satisfactory results most of the time... Upload it somewhere, email the link. If you must encode it, set a quality level, leave the bitrate dynamic. If it's obvious that size will not be met, cancel the encode and adapt quality level accordingly. Rinse and repeat.

Good advice in general, but it does not suit my usecase. Uploading to an external link is not an option due to technical limitations, one of them being that the receiver does not have http access.

I could also clarify that I'm NOT looking for exactly the size I'm specifying. It's enough if it is reasonably close to what I want (maybe up to 5 or 10% lower or so) but it should be guaranteed that it will not exceed my target limit.

  • Not possible with ffmpeg. – Gyan May 23 at 10:35
  • @Kiwy it's very rare for a question referencing another to be an exact duplicate of the question they're referencing. – Philip Couling May 23 at 11:20
  • Worrying too much about size and going for a fixed filesize regardless of video length / resolution / framerate / content will not give satisfactory results most of the time... Upload it somewhere, email the link. If you must encode it, set a quality level, leave the bitrate dynamic. If it's obvious that size will not be met, cancel the encode and adapt quality level accordingly. Rinse and repeat. – frostschutz May 23 at 21:25
1

It's relatively simple to put two answers together here:

Assuming you want a 10MB file (10485760 bytes) you could use ffprobe to find the duration and get the shell to perform the calculation.

Just be careful because ffprobe will report decimal places which will trip up the shell arithmetic. I've used ${length%.*} to strip off the decimal places:

size=10485760 
length=`ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4`
ffmpeg -i input.mp4 -b $(( $size / ${length%.*} )) output.mp4
  • I tried this with size=25000000 but the file ended up at 5MB. If it were off by a factor 8, it could be explained with bits/bytes, but now it's off with a factor 5 – klutt May 23 at 11:46
  • Hmmm, that's a little odd. Do try with a bits to by conversion anyway and see what happens. 25MB is 209715200 bits. (25 *1024 * 1024 * 8). Also echo $(( $size / ${length%.*} )) just to check the bitrate you're asking for. – Philip Couling May 23 at 12:29
  • 1
    Did that. The size of the file became 28MB. 3MB too large. – klutt May 23 at 12:58

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.