I have been encoding some videos in AV1 lately and I thought I’d share my technique for those who may wish to do some AV1 on their own without having a messy setup. I think this is a pretty clean way, ultimately, to use Av1an’s Docker image.

A forewarning: AV1 can be pretty to slow encode with. I’ve been doing it with DVDs where the 640x480 resolution of the video means a frame can be processed relatively quickly, but videos in 1920x1080 or 4k resolutions might be pretty intense where the encode speed only ends up being a frame a second.

Forewarning pt. 2: Something I learned that I CANNOT rely on is trying a faster encode speed to guesstimate the resulting file size and picture quality and then really maximize my results by lowering the encode speed. My observation has been that a slower encode speed will in fact improve the picture quality (and file size), such that I cannot be sure what something will look like without just encoding a very short sample at a slow speed. OK. Let’s begin.

Operating System & Environment

I am using Fedora Linux 38. I’d like to use the Av1an package but that only has an official Arch release. I definitely don’t want to spend time compiling this myself, so I will use the official Docker image instead. And I won’t use Docker, actually, but Podman. I also use the Fish Shell. Its syntax is very slightly different from Bash’s.

Now, Fedora users may know about SELinux. And something that kept happening to me was the security context of some of the files I’m shuffling around my hard drives would end up being not correct, making Podman incapable of seeing the files I’m trying to use. So instead of fixing the context per file (annoying) I just temporarily disabled SELinux.

sudo setenforce Permissive

Container image

From here things are pretty straightforward. I’ll pull the docker image, which has a full Av1an setup ready to go.

podman pull docker.io/masterofzen/av1an:master

One little note is that you should use the master tag. A confusing thing about this image is that the latest tag is the old python version, and we want the current Rust version.

Executing Av1an

Now, navigate to whatever directory your source video is in. In my case, I losslessly encoded the DVDs with Handbrake into h264 and passed through the audio/chapter markers, etc. This gave me a good source to work with, even though it was a little bloated in file size. I don’t think Av1an accepts MPEG-2, which is why I did that.

First I’ll explain what the Podman command is doing for those who aren’t familiar with Docker/Podman, and then I’ll give a full working example.

podman run -v "$(pwd)":/videos:z --userns=keep-id -it --rm docker.io/masterofzen/av1an:master -i sourcevideo.mp4 -s scenes.csv --pix-format yuv420p10le -o output.webm -v "--VIDEO_OPTIONS" --keep -a "--AUDIO_OPTIONS"

  • podman run - Execute a container
  • -v "$(pwd)":/videos:z - Mount the present working directory as /videos in the container, and the :z is an SELinux labeling thing that can be dropped for non-SELinux users.
  • --userns=keep-id - This flag helps keep the user id and group ids consistent between the host and container so that they don’t get mangled. Your output file will belong to your user.
  • -it - Execute the command in a visible shell session
  • --rm - Remove the container (not the image, the container) when the command is done executing.

Final example

The rest of the flags are for Av1an itself, or for the encoders. So here’s a full working example of how I used it, to encode with aomenc and Opus for the audio. Av1an uses aomenc by default.

podman run -v "$(pwd)":/videos:z --userns=keep-id -it --rm docker.io/masterofzen/av1an:master -i sourcevideo.mp4 -s scenes.csv --pix-format yuv420p10le -o output.webm -v " --cpu-used=3 --enable-qm=1 --threads=4 -b 10 --end-usage=q --cq-level=28 --lag-in-frames=48 --auto-alt-ref=1 --enable-fwd-kf=1" --keep -a "-c:a libopus -b:a 128k"

I think for an explanation for what individual flags do, and perhaps some guidance on how to use them effectively, I can only refer one to the guide written by Reddit user BlueSwordM https://www.reddit.com/r/AV1/comments/t59j32/encoder_tuning_part_4_a_2nd_generation_guide_to/