-
Notifications
You must be signed in to change notification settings - Fork 53
Description
Hi,
I recently come across ab-av1 and like it a lot, especially love the crf-search feature. I have large amount of video files that I've remuxed and would like to send though av1 encoding to reduce size. Quality is important for me but file size takes precedent. I like that I can use the max encode file target and target a minimal VMAF.
My target are the defaults of VMAF 95 and 80% file size ceiling, in case those cannot be met I am downstepping with 0.2 intervals as low as 93.0. For that reason I wrote a script that does it for me fully unattended and save results so I can later make intentional decision what to go with and for that I parse output of crf-search.
However, the output of crf-search is rather difficult to tame because it is not very machine parsable friendly and under conditions changes the output format.
First, by default the output into termnal has progress bar and output the samples it tried
% ab-av1 crf-search --min-vmaf 95 --preset 4 --input testfile.mkv | cat
- crf 32 VMAF 95.93 (9%) (cache)
- crf 46 VMAF 93.75 (4%) (cache)
00:00:00 crf 38 3/3 ######################################################################################################################################################################### (eta 0s)
Encode with: ab-av1 encode -i testfile.mkv --crf 38 --preset 4
crf 38 VMAF 95.16 predicted video stream size 72.07 MiB (6%) taking 26 minutes
if I capture stdout and null route stderr I get a format that is really easy to parse and the format is visible in source code with info! macro.
% ab-av1 crf-search --min-vmaf 95 --preset 4 --input testfile.mkv 2>/dev/null | cat
crf 38 VMAF 95.16 predicted video stream size 72.07 MiB (6%) taking 26 minutes
However there might be errors, and if the minimal conditions for percentage ratio or VMAF are not met it will error, so if I redirect stderr into stdout and also have pipe there it changes entire output format into Rust's debug format resulting in non deterministic output
% ab-av1 crf-search --min-vmaf 95 --preset 4 --input testfile.mkv 2>&1 | cat
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] encoding sample 1/3 crf 32
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] sample 1/3 crf 32 VMAF 95.62 (8%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] encoding sample 2/3 crf 32
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] sample 2/3 crf 32 VMAF 95.34 (11%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] encoding sample 3/3 crf 32
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] sample 3/3 crf 32 VMAF 96.83 (7%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] crf 32 VMAF 95.93 predicted video stream size 102.44 MiB (9%) taking 27 minutes (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::crf_search] crf 32 VMAF 95.93 (9%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] encoding sample 1/3 crf 46
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] sample 1/3 crf 46 VMAF 93.62 (4%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] encoding sample 2/3 crf 46
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] sample 2/3 crf 46 VMAF 91.95 (5%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] encoding sample 3/3 crf 46
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] sample 3/3 crf 46 VMAF 95.68 (3%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] crf 46 VMAF 93.75 predicted video stream size 47.16 MiB (4%) taking 27 minutes (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::crf_search] crf 46 VMAF 93.75 (4%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] encoding sample 1/3 crf 38
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] sample 1/3 crf 38 VMAF 94.84 (6%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] encoding sample 2/3 crf 38
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] sample 2/3 crf 38 VMAF 94.20 (8%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] encoding sample 3/3 crf 38
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] sample 3/3 crf 38 VMAF 96.45 (5%) (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::sample_encode] crf 38 VMAF 95.16 predicted video stream size 72.07 MiB (6%) taking 26 minutes (cache)
[2025-07-26T07:57:35Z INFO ab_av1::command::crf_search] crf 38 successful
crf 38 VMAF 95.16 predicted video stream size 72.07 MiB (6%) taking 26 minutes
Which also do not happen if the output is terminal and stderr lands there.
Currently I am able to catch the very last line which happens to keep the expected format and parse it but I think it would be great if there would be JSON format htat would provide deterministic output. I later use those data to run ffmpeg with them, auto-encode does not work well for me due to bunch of other switches that I add there, like -metadata or mapping of streams.
My ideal workflow would be:
- Run
crf-searchwith VMAF 95 and ratio 80.0 - If it fails, downstep VMAF by 0.2 steps until it succeed
- Keep all the data and errors for later investigation
- Fire up ffmpeg with the right parameters
For more context, the reason I do not start with setting minimal VMAF to say 93 is that I do not want 93 if I can get away with higher one and only fallback this low if no other choice works.