I came to video from content work, not from a codec background, so my first instinct with a transparent WebM was to check the metadata. If a file says alpha_mode: 1, it has alpha, right? I built two test files to check that, and both break the idea: one whose tag says alpha while the video holds none, and one that holds alpha with no tag at all.
Everything below comes from one 8-second, 540×960 clip with a person on a partly green backdrop, plus a 2-second clip FFmpeg encoded for the second counterexample, all run through FFmpeg 7.1 on one machine, once. The transparent WebM came out of ImgIng (https://imging.ai/), a browser tool whose video matting is still in Beta and runs locally in desktop Chrome or Edge. Treat the numbers as a single sample, not a general result.
Where the tag shows up
ffmpeg -i prints the tag under the video stream's metadata. The file exported from the tool shows alpha_mode : 1 in lowercase. Files FFmpeg writes itself show ALPHA_MODE : 1 in uppercase, so a case-sensitive grep can miss the ones FFmpeg wrote.
Reading the tag takes one command. The next two files are why I stopped trusting it.
Counterexample one: the tag stays, the alpha goes
I decoded the transparent file and re-encoded it as plain yuv420p. The output still printed ALPHA_MODE : 1. FFmpeg copies the input stream's tags onto the output, so the label rode along into a file that has no alpha data. This is a side effect of re-encoding with FFmpeg, not something the original export does. Any re-encode step that keeps the stream tags would leave a file like this.
Counterexample two: the alpha stays, the tag goes
I encoded a 2-second clip with alpha through libvpx-vp9, then stripped the tag with -c copy -metadata:s:v:0 alpha_mode=. The tag disappeared from ffmpeg -i. Decoding with -c:v libvpx-vp9 still returned a real alpha channel on frame 30 (min 0, max 255, mean 45.48). Again this is something FFmpeg did to my file, but it shows the data and the label are stored separately and can disagree.
What I check now
A VP9 alpha channel in WebM is stored as extra data attached to each video block (BlockAdditions in the Matroska structure). If the blocks carry it, the alpha is there, whatever the tag says. ffmpeg -i does not show that, and I did not have ffprobe or mkvinfo on this machine, so I used a short script that walks the file structure and counts the blocks with extra data. I did not try ffprobe's packet side data, so I can't say whether that route works.
$ python3 check_blockadditions.py input.webm
input.webm {'AlphaMode': 1, 'BlockGroups': 240, 'BlockAdditions_count': 240, 'BlockAdditional_bytes': 1036225, 'SimpleBlocks': 401}
$ python3 check_blockadditions.py noflag.webm
noflag.webm {'BlockGroups': 60, 'BlockAdditions_count': 60, 'BlockAdditional_bytes': 248054}
The exported file has 240 blocks with extra data, about 1.0 MB of it. The stripped file has no AlphaMode entry at all, yet all 60 of its blocks still carry alpha. The re-encoded file from counterexample one has the tag and no BlockAdditions, which is how you tell it apart from the real one.
The quiet failure that makes this matter
Even with real alpha in the file, FFmpeg's default VP9 decoder ignores it. On frame 60 of the exported clip, the default decode gave alpha 255 everywhere. Adding -c:v libvpx-vp9 before -i gave 0 to 255, with a mean of 46.762. If you convert with the default decoder, ProRes 4444 or QuickTime Animation files are still produced and still play, but every frame is opaque. There is no error and no warning; the stream line just says yuv420p.
Where this stops
This is one clip, one FFmpeg build, one run. I did not test other FFmpeg versions, and I did not check how any editing app imports a transparent WebM, so I have nothing to say about that.
Top comments (0)