You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

9.1 KiB

+++ title = 'Converting big videos' aliases = '/posts/2023-10-01-converting-big-videos' summary = '''I am subscribed to a few mailing lists and I stumbled across a big video file in one of them recently. Here is a small command-line command using ffmpeg that cut its filesize in half.''' date = '2023-10-01T10:37:00+0200' #lastmod = '' categories = [ 'computerstuff' ] tags = [ 'openbsd', 'freebsd', 'linux', 'command-line' ]

+++

I don't like big mail attachments but when I see them I try to reduce their filesize because I think it should be possible to send pictures with good quality but with reduced filesize.

{{< alert >}} Whenever I talk about filesizes or video sizes in this post, I want to send them via email. You can of course have big files with high bitrates, but forcing the mail recipient to download those in his email client is just not okay IMHO. {{< /alert >}}

For this I inspect images and videos with some basic commands.

Inspecting the video file

$ ll Video.MOV
-rw-------  1 dominic  dominic  10.7M Sep 23 19:05 Video.MOV
$ file Video.MOV
Video.MOV: ISO Media, Apple QuickTime movie, Apple QuickTime (.MOV/QT)
$ ffmpeg -i Video.MOV
ffmpeg version 4.4.4 Copyright (c) 2000-2023 the FFmpeg developers
  built with OpenBSD clang version 13.0.0
  configuration: --enable-shared --arch=amd64 --cc=cc --enable-debug --disable-stripping --disable-indev=jack --disable-outdev=sdl2 --enable-fontconfig --enable-frei0r --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libdav1d --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmp3lame --enable-libopus --enable-libspeex --enable-libtheora --enable-libv4l2 --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-nonfree --enable-openssl --enable-libvidstab --extra-cflags='-I/usr/local/include -I/usr/X11R6/include' --extra-libs='-L/usr/local/lib -L/usr/X11R6/lib' --extra-ldsoflags= --mandir=/usr/local/man --objcc=/usr/bin/false --optflags='-O2 -pipe -g -Wno-redundant-decls'
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Video.MOV':
  Metadata:
    major_brand     : qt
    minor_version   : 0
    compatible_brands: qt
    creation_time   : 2023-09-23T16:11:17.000000Z
    com.apple.quicktime.artwork: <20><>
    com.apple.quicktime.is-montage: iMovie
  Duration: 00:01:53.23, start: 0.000000, bitrate: 795 kb/s
  Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 94 kb/s (default)
    Metadata:
      creation_time   : 2023-09-23T16:11:17.000000Z
      handler_name    : Core Media Audio
      vendor_id       : [0][0][0][0]
  Stream #0:1(und): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 568x320, 693 kb/s, 30 fps, 30 tbr, 600 tbn, 1200 tbc (default)
    Metadata:
      creation_time   : 2023-09-23T16:11:17.000000Z
      handler_name    : Core Media Video
      vendor_id       : [0][0][0][0]
      encoder         : H.264
At least one output file must be specified

Converting to a smaller filesize

With default values (for bitrates). Takes about 12 seconds and creates a 4.4MB big file. I also strip metadata out of the videos, usually.

$ ffmpeg -i Video.MOV -acodec aac -vcodec h264 -map_metadata -1 newvideo-default.mp4

Another approach would be to specify the bitrates. You probably have to “play” with these values. For this example I chose 64k for audio and 300k for video. Note, that the filesize is actually bigger than the example above (with default values). This took about 16 seconds but creates a file of 5.0MB.

$ ffmpeg -i Video.MOV -acodec aac -vcodec h264 -map_metadata -1 -b:a 64k -b:v 300k newvideo-64k-300k.mp4

Also convert the video size

When we inspected the file above we notices a video size of 568×320. We will reduce this now to 240 on the shorter side and we will get a new file that is 3.2MB big.

$ ffmpeg -i Video.MOV -acodec aac -vcodec h264 -map_metadata -1 -filter:v scale=-1:240 newvideo-default-resized.mp4

We can improve this by reducing the audio bitrate to 32kb/s (going further down did not reduce the file much).

$ ffmpeg -i Video.MOV -acodec aac -vcodec h264 -map_metadata -1 -filter:v scale=-1:240 -b:a 32k newvideo-default-resized-32k.mp4

Another look into the last converted file:

$ ffmpeg -i newvideo-default-resized-32k.mp4
ffmpeg version 4.4.4 Copyright (c) 2000-2023 the FFmpeg developers
  built with OpenBSD clang version 13.0.0
  configuration: --enable-shared --arch=amd64 --cc=cc --enable-debug --disable-stripping --disable-indev=jack --disable-outdev=sdl2 --enable-fontconfig --enable-frei0r --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libdav1d --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmp3lame --enable-libopus --enable-libspeex --enable-libtheora --enable-libv4l2 --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-nonfree --enable-openssl --enable-libvidstab --extra-cflags='-I/usr/local/include -I/usr/X11R6/include' --extra-libs='-L/usr/local/lib -L/usr/X11R6/lib' --extra-ldsoflags= --mandir=/usr/local/man --objcc=/usr/bin/false --optflags='-O2 -pipe -g -Wno-redundant-decls'
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'newvideo-default-resized-32k.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.76.100
  Duration: 00:01:53.24, start: 0.000000, bitrate: 140 kb/s
  Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 426x240, 100 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 31 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
At least one output file must be specified

How to find the best values

The best option is probably to get routined. Convert some videos and look what changes (video and audio quality, filesize). Also try to trim them if you need to. Have a look at the manpages of ffmpeg (switches -t, -to, -ss).

I guess a short video where someone is talking and explaining something does not always need high bitrates. This is like a slideshow where someone is talking in the background.

If you want to share music you might use higher bitrates. The classic mp3 files sounded quite good with 192kb/s or even 320kb/s but I think 128kb/s should also be fine. For aac files I'd probably try 96kb/s first and then increase or decrease on another run and look if the filesize improves.

It basically makes no sense reducing much of a bitrate if the filesize stays nearly the same in the end (as long as you can't see or hear much difference).

Some values for reference

The filename suggest the used bitrates and options.

$ ll Video.MOV newvideo-*
-rw-------  1 dominic  dominic  10.7M Sep 23 19:05 Video.MOV
-rw-r--r--  1 dominic  dominic   5.0M Oct  1 09:48 newvideo-64k-300k.mp4
-rw-r--r--  1 dominic  dominic   6.4M Oct  1 09:40 newvideo-64k-400k.mp4
-rw-r--r--  1 dominic  dominic   1.8M Oct  1 10:04 newvideo-default-resized-16k.mp4
-rw-r--r--  1 dominic  dominic   1.8M Oct  1 10:03 newvideo-default-resized-24k.mp4
-rw-r--r--  1 dominic  dominic   1.9M Oct  1 10:01 newvideo-default-resized-32k.mp4
-rw-r--r--  1 dominic  dominic   3.2M Oct  1 09:54 newvideo-default-resized.mp4
-rw-r--r--  1 dominic  dominic   4.4M Oct  1 09:43 newvideo-default.mp4
$ ls -l Video.MOV newvideo-*
-rw-------  1 dominic  dominic  11254505 Sep 23 19:05 Video.MOV
-rw-r--r--  1 dominic  dominic   5290645 Oct  1 09:48 newvideo-64k-300k.mp4
-rw-r--r--  1 dominic  dominic   6705317 Oct  1 09:40 newvideo-64k-400k.mp4
-rw-r--r--  1 dominic  dominic   1844227 Oct  1 10:04 newvideo-default-resized-16k.mp4
-rw-r--r--  1 dominic  dominic   1869904 Oct  1 10:03 newvideo-default-resized-24k.mp4
-rw-r--r--  1 dominic  dominic   1991368 Oct  1 10:01 newvideo-default-resized-32k.mp4
-rw-r--r--  1 dominic  dominic   3382468 Oct  1 09:54 newvideo-default-resized.mp4
-rw-r--r--  1 dominic  dominic   4647129 Oct  1 09:43 newvideo-default.mp4

I've created a similar post for images in 2020: [Optimizing PNG images]({{< ref "posts/2020/2-optimizing-png-images" >}}) (there is also some info on JPG files).