Reducing filesize of video in ubuntu?

How do I reduce the filesize of videos? For some reason, by phone takes giant videos. The worst of these is a 20 minute video that takes up an entire 13 GB. How can I shrink the filesizes of these? They are mp4s encoded in H.264 and MPEG-4 AAC and play at 30 fps.

It's okay if there is reduction in quality.

I tried using avconv to reduce resolution, but even though this outputted a video with smaller dimensions, the size had bizarrely increased.

What is a good way for reducing the sizes of these file?


To reduce the size of your mp4 you have two good choices with FFmpeg:

  1. Experiment with Constant Rate Factor (CRF) settings to find a match between video output size and video quality
  2. Experiment with the set bitrate of your choice and use a 2 pass encode.

Details of both below:

1. Resize using FFmpeg's Constant Rate Factor (CRF) option:

In FFmpeg the CRF settings vary from 0-51 with 0 being lossless and 51 being shockingly poor quality. The default is 23 and you need to find the 'sweet spot' for your particular video of file size and video quality with some experimentation.

A sample command-line would be:

ffmpeg -i input.mp4 \
       -c:v libx264 -preset slow -crf 22 \
       -c:a copy \
       output.mp4

Note that in this command-line the video is re-encoded and the audio is simply copied across. Things to consider:

  1. If the size is still too big and the video quality is still acceptable you would try -crf 24 and so on (incrementally increasing the crf integer) until you find an acceptable compromise between video quality and file size.
  2. If the video quality is too poor you would try crf 20 and so on (incrementally decreasing the crf integer) until you find an acceptable compromise between video quality and file size.

2. Resize using FFmpeg's 'set bitrate' + '2 pass encode' options:

Another choice, which arguably will not produce as good results as the CRF example is to use the set bitrate of your choice and use a 2 pass encode. The following example of this is a single command:

ffmpeg -y -i input.mp4 \
       -c:v libx264 -preset slow -b:v 1000k -pass 1 \
       -c:a copy -f mp4 /dev/null && \
ffmpeg -i input.mp4 \
       -c:v libx264 -preset slow -b:v 1000k -pass 2 \
       -c:a copy \
       output.mp4

Again in this example the video is re-encoded and the audio is simply copied over. Things to consider:

  1. Video still too big? Decrease the bitrate...
  2. Quality too poor? Increase the bitrate...

Keep doing this until you find an acceptable compromise between video quality and file size.

References:

  • FFmpeg and H.264 Encoding Guide : FFmpeg's canonical guide to encoding to H.264

So I figured it out. The "-b" flag in ffmpeg sets the bit rate. I also found out that 1,000,000 is a good general use value that provides a decent tradeoff between file size and quality.

So run:

ffmpeg -i inputfilename.mp4 -b 1000000 outputfilename.mp4

You can substitute 1000000 for another bitrate value if you want. Also, you can include a "-s WxH" flag to set the size of the output video. So to make the output video 720p, you'd include "-s 1080x720"