Resize your video files

Having a large media collection can be cumbersome and can also lead to mismatching formats and resolutions. This can have negative impacts like:

  • Not all your clients can play easily the videos, resulting in transcoding on your server
  • Storage space might be full or nearly full

In theory you could re-download all the stuff in the proper formats and resolutions, but in practice this could not be al option because:

  • Some media is rare and cannot be found, or not in the formats you like
  • New formats might come up which are better suited do your needs
  • Downloading large collections might be overkill
  • You might have data-caps or just don't want to bother with searching again

In this case you can try to re-encode all your videos using a different codec, resolution or container format.

Be aware of the following possible issues:

  • Time: encoding takes time, a lot of it
  • Power consumption: encoding takes a lot of CPU power, which cost money in terms of electricity
  • quality degradation: encoding already degraded stuff will result in worse quality

Clearing some ambiguity

A video file is a mix of different stuff: actual video tracks, audio tracks, subtitles and sometimes even data tracks. Moreover, subtitles can be burned-in, text subtitles, or image subtitles. The file itself is a container of those streams.

Containers: the file itself is just a container. There are many different container formats like avi, mp4, mkv (Matrioska) and so on. I like mkv because it's an open and free format that support basically whatever combination of streams inside. Mp4 has more limitations, and other formats are even worse. Bear in mind that not all containers can have all streams and formats inside. The action of changing a video container is called transmuxing and it's usually pretty fast.

Video Streams: is your actual video data. This is the most space-hungry stream and the only one that make sense to encode differently. A video stream is encoded with a video codec.

Audio Streams: is the audio track of the movie. You might have more than one audio track, for example one for each language. There is usually no need to encode audio tracks as all major formats are well supported. The best open audio codec seems to be Opus, but to be honest i don't bother with touching audio tracks.

Subtitles: are a mess. They can be text or video streams, they can have different formats (mov_text, SRT…) and they could be both embedded in the container or standalone files. Again, i tend to convert them to SRT when possible or discard them, since i can download them separately anyway.

My choice of preference is:

  • Container: mkv. Open, solid and versatile
  • Video Codec: AV1. It's the new kid on the block, but Android must support it from A14+ and it's getting wide support everywhere today. It's incredibly optimized for space while retaining a great image quality. File sizes can be reduced significantly from x264/x265 without quality loss at the same resolution. ffpmeg support it quite well.
  • Subtitles: srt, seems to be the one that works better everywhere.

Tools

There are plenty of tools to convert your media. Every single one of them uses FFMpeg under the hood:

  • Handbrake: cool GUI and CLI tool with lots of presets. It's manual and can be scripted on the CLI.
  • TDarr it's an autmatic web-based service that scan your collections and convert stuff. Highly cusotmizable and quite difficult to use, not the nicest GUI. Check this page on how to set it up.
  • Unmanic is a library optimized, like Tdarr, that iwll autmatically convert your library for you. Better GUI, still quite complex to use, but a better experience than Tdarr for me. Check this page on how to set it up.

After trying them all, i choose a different path. My use case was a lot simpler: i only needed to encode and make my entire library more uniform, i don't add much stuff to it fast enough to justify a dedicated service running for that scope.

So i wrote my own bash script to get the job done.

Media Fixer: a bash script to Get The Job Done

You can get the script here, download the bash file or clone the repository to your server.

You can customize codecs and containers by editing the following lines in the script:

CONTAINER="Matroska"
CONTAINER_EXTENSION="mkv"
VIDEO_CODEC="AV1"
VIDEO_WIDTH="1280"
VIDEO_HEIGHT="720"
FFMPEG_ENCODE="-c:v libsvtav1 -crf 38"
FFMPEG_RESIZE="-vf scale=${VIDEO_WIDTH}:${VIDEO_HEIGHT}"

These are my preferences, but you can freely adapt to your needs.

In order to work, you need to enable the proper USE flags for ffmpeg. Mine are:

media-video/ffmpeg x264 v4l jpeg2k lzma vpx webp x265 xvid mp3 openal opencl opus twolame vorbis wavpack svt-av1

Then you just run the script and it will scan & convert all the video files in all the sub-directories under the current one. It will skip any file that is already in the correct format.

Please note that the script will preserve your files if the encoding or transmuxing fails, and that the filenames will not be changed (except for the extension if they change container of course) so that any additional poster and media info support files will still work as before.

I provide this script as-is, works for me, it could transform all your videos in Windows XP ISOs if used without precautions.