Before a batch transcode I only ask ffprobe one thing: is this file worth re-encoding at all? Answering that takes a handful of fields. One of them, the video stream's bit rate, came back as N/A on every one of the five WebM clips I tried, and the fallback for it quietly changes your number.
The fields I ask for
The number I care about is bits per pixel per frame, bpp for short: video bit rate divided by width × height × frame rate. Low bpp means the file is already squeezed.
The stream-level fields I ask for are codec_name, width, height, r_frame_rate and bit_rate. From the container I ask for duration, size and bit_rate. r_frame_rate comes back as a fraction such as 30/1, so it needs one division before it is a number.
On a 10-second 720p H.264 clip, the stream bit rate was 732,591 and the container bit rate was 736,016. Under half a percent apart, so for plain H.264 in MP4 it hardly matters which one you pick.
Where the bit rate goes missing
These WebM files carry no per-stream bit rate, and ffprobe says so with N/A instead of leaving the line out. This is the 1080p moose clip from my set:
$ ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,r_frame_rate,bit_rate:format=duration,size,bit_rate -of default=nw=1 input.webm
On the moose clip (VP9 in WebM), the stream-level bit_rate comes back as N/A and the format-level one is about 2.06 Mbps.
bit_rate shows up twice, stream first and container second. All five WebM clips behaved this way, and a script that calls float() on the stream value would crash on them.
What the fallback does to the number
The fallback I use is file size × 8 ÷ duration. That includes the audio track and the container overhead, so the bpp it gives is higher than the video alone. The table sets it against the bpp of the same clips with audio stripped, and adds what one more x264 pass (CRF 23, preset medium, audio removed) did to the size.
| Clip | bpp from the whole file | bpp from video only | Size after one more pass ÷ before |
|---|---|---|---|
| moose, VP9 1080p | 0.033 | 0.032 | 2.805 |
| crowd A, VP8 720p | 0.288 | 0.279 | 0.348 |
| crowd B, VP9 720p | 0.243 | 0.239 | 0.560 |
| crowd C, VP9 1080p | 0.115 | 0.113 | 0.831 |
| crowd D, VP8 360p | 0.322 | 0.264 | 0.664 |
The overstatement is 1.7% to 3.1% on three clips, 4.7% on the moose clip and about 22% on the 360p one, where the audio is a bigger share of a very small file.
Did it change a verdict
Not on these five. With a skip line at 0.10 (my choice for an x264 CRF 23 target), the moose clip is skipped and the other four go through, whichever bpp you use. The moose clip came out 2.805 times bigger after the extra pass. The other four shrank, to between 0.348 and 0.831 of their size.
The clip nearest the line is crowd C, at 0.115 whole-file and 0.113 video-only. Both are above 0.10, and it did save 16.9%. I had no clip sitting just under the line with a loud audio track, and a file like that is exactly where the inflation would push a skip into a transcode. My guess is it would cost little: in a separate 36-point run on H.264 inputs, the four points between 0.08 and 0.13 saved only 4% to 9% when re-encoded, while all 24 points below 0.08 grew, by 1.34 to 6.67 times. That is a guess about the borderline, not something I measured on WebM.
Fields I print but do not decide on
codec_name goes into my log line and nothing else. In the 36-point run every input was H.264 and in the five-clip check every input was VP8 or VP9, so I have no data on a codec-dependent threshold and did not want to invent one.
duration and size only matter as fallback inputs. Variable frame rate, HDR, rotated phone clips and multi-stream files were not in my set.
When the batch goes through a browser
If the folder is going through a browser instead of a script, I ran the same five clips through ImgIng https://imging.ai/ video compression on a desktop browser. It takes several files at once and has quality presets. Phones and tablets only do image compression there. During the compression step of that run I saw no non-GET requests.
With its default smart pick, it kept the originals for four of the five clips, including three the bpp rule would send to transcode. The site says it only adopts a result that saves at least 12% and passes a quality check. That looks like a different rule from bpp, as far as I can tell from outside.
What I did not check
Only five public clips plus 36 generated points, all in one environment. No phone-original H.264 files, no H.265 or AV1 targets, no preset other than medium.
Sample clips: Wikimedia Commons, re-encoded and trimmed, so modified from the originals. Moose by the road.webm (Forza1000, CC BY-SA 4.0); A Demonstration of Disabled People June 2018 1.webm (DGW, CC BY-SA 3.0); Worldwide Demonstration – March 2021 Amsterdam.webm (Karen Eliot, CC BY-SA 2.0); Demonstration of Ethiopian residents in Israel, July 2019.webm (Israel Police, CC BY-SA 3.0); Demonstration in Al-Zabadani, 23 March 2012.webm (Allfor Syria, CC BY 3.0).
Top comments (0)