Get into video, and you soon realize one thing - these files take up space. "But storage is getting cheaper!" someone says. Yes, and I want that to translate to actual savings for me, not get eaten up by a horde of gigantic movie clips.
1. The Idea
Video compression on the camera must be less efficient than video compression post-capture, on a much more capable machine. The camera is limited not just by onboard processing power, but by having to compress the video as it is being recorded. We should therefore be able to save some space by recompressing the video file post-capture.
2. Three Sets of Data
Each video file typically comes with three sets of data - video, audio, and metadata - and recompressing it we must at least consider each one of them.
-
Video: Perhaps surprisingly, this is the easiest kind of data to handle with good results. If the video has been captured with a reasonable color profile, then for the absolute majority of cases it can be recompressed with reasonable defaults.
-
Audio: Compressing the sound is also fairly straightforward, but it's difficult to get a good compression ratio compared to the original without completely mangling it. Best bet is to just leave it unchanged.
-
Metadata: Out of nowhere comes the boss fight[a] - dealing with the metadata. While metadata in standard format dealing with the movie clip as a whole is realtively simple to just copy over, non-standard metadata synchronized to the movie, such as accelerometer data for stabilization, is typically not supported by video encoders.
We'll deal with these one at a time.
2.1. Video
Compressing video is fairly straightforward. H264 or H265 compression with ffmpeg can be done with a preset and a single quality parameter that gives good results for the absolute majority of cases. The CRF parameter sets the quality, and when in doubt a value of 23 is your go-to setting. We use a slow preset to let the encoder take its time to get it right.
ffmpeg -i <input> -c:v libx264 -preset veryslow -crf 23 -vf format=yuv420p ...
2.2. Audio
There's little to gain by compressing the sound more, so we'll just copy it.
ffmpeg ... -c:a copy ...
2.3. Metadata
ffmpeg has support for copying some metadata, at least for MP4/MOV containers, so we'll start by copying what we can easily copy:ffmpeg -i <input> -movflags use_metadata_tags ...
For other metadata I'm afraid there is no good answer. I settled on the following process:
-
Use Exiftool to extract existing metadata as XML:
exiftool -X -all <input> > <input>.exiftool.xml
-
Use Exiftool again to copy any metadata to the new file:
exiftool -TagsFromFile <input> -overwrite_original <recompressed>
-
Keep a copy of the original video with any
mdat
,free
, andwide
atoms removed. Since the contents of these atoms make up the overwhelming majority of the data in the file the resulting file is of insignificant size. If we ever need the metadata in the original we can at least in theory extract it from this.
3. Results

OriginalRecompressed
The results were surprisingly good. 4K video would recompress to as little as 10% of the original file with no loss that I could see, while FullHD would recompress to about one-fifth (8.9 GB down to 1.6 GB). Some files didn't compress at all and some actually grew. The more things that were happening in the video, the worse it would compress, which isn't a surprise.
This makes is feasible to record in 4K by default without having to worry about the file sizes.
Perhaps unsurprisingly the best compression was seen on clips where I had used a fast lens to get good foreground-background separation by turning the background into a blur. The on-camera encoder spent a lot of bits encoding that blur with perfect fidelity, while ffmpeg correctly assumed that nobody would be looking there.
Links
https://en.m.wikipedia.org/wiki/Boss_(video_games) |