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.

190 lines
9.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

+++
title = '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
```console
$ 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.
```console
$ ffmpeg -i Video.MOV -acodec aac -vcodec h264 -map_metadata -1 newvideo-default.mp4
```
Another approch 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.
```console
$ 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.
```console
$ 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).
```console
$ 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:
```console
$ 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][1] (switches `-t`, `-to`, `-ss`).
[1]: https://ffmpeg.org/ffmpeg.html
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.
```console
$ 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
```
```console
$ 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
```
## Related content (optimizing images)
I've created a similar post for images in 2020:
[Optimizing PNG images]({{< ref "2020-01-20-optimizing-png-images/" >}})
(there is also some info on JPG files).