DEV Community

yue xing
yue xing

Posted on

My transparent WebM turned black in the editor, and three checks that found out why

Take an 8-second clip, cut the person out with the video background removal in ImgIng, export a transparent WebM, convert it for an editor, and the background comes out black. The first suspect is the export. In this case it wasn't the export: the black came from a later step. Below are three checks to run in order. Everything here is from one clip (540×960, 2,394,232 bytes), one machine, one run, and an FFmpeg 7.1 build. I did not try other FFmpeg versions, and I found no official import notes for any editor, so I say nothing about how editors treat the file.

Check whether the file really has alpha

The obvious first move is ffmpeg -i and a look at the metadata. It prints alpha_mode : 1, which looks like proof. It isn't. When I re-encoded the clip to plain yuv420p with FFmpeg as a test, the output still carried ALPHA_MODE : 1 (FFmpeg copies the stream tag over), and it had no alpha data at all. The reverse also happens: I stripped the tag from a file with -c copy and the alpha data stayed inside, still readable. The tag is only a label.

What I trust instead is whether each video block in the WebM carries a BlockAdditions element, since that is where VP9 alpha is stored. I didn't have ffprobe or mkvinfo on this machine, so I wrote a small EBML reader to count them. The original had 240 blocks with BlockAdditions, one per frame. The tag-stripped copy had 60 of 60, so it still had alpha. I haven't tried ffprobe's side-data output, so I can't say it would show the same thing.

Check which decoder reads the file

This is the step that explains the black background. FFmpeg's built-in vp9 decoder reads the picture but ignores the alpha plane, and it does so quietly. The Stream line just says yuv420p. Asking for the libvpx-vp9 decoder, placed before -i, reads it as yuva420p. I ran both on frame 60 and printed the alpha statistics:

$ ffmpeg -hide_banner -i input.webm -vf "select=eq(n\,60),format=rgba,alphaextract,signalstats,metadata=print" -an -f null -
lavfi.signalstats.YMIN=255
lavfi.signalstats.YAVG=255
lavfi.signalstats.YMAX=255

$ ffmpeg -hide_banner -c:v libvpx-vp9 -i input.webm -vf "select=eq(n\,60),format=yuva420p,alphaextract,signalstats,metadata=print" -an -f null -
lavfi.signalstats.YMIN=0
lavfi.signalstats.YAVG=46.7618
lavfi.signalstats.YMAX=255
Enter fullscreen mode Exit fullscreen mode

With the default decoder every pixel is fully opaque, so the person's cutout sits on a solid black frame. With libvpx-vp9 the minimum is 0 and the average 46.76, which is what a cutout should look like: roughly 79% of that frame is fully transparent and 16% fully opaque. The order matters too. Put -c:v libvpx-vp9 after -i and the numbers came back as a constant 235, which is not real alpha. (I only know it is a constant, not why it is 235.)

Check what the converted file really holds

Editors usually want ProRes 4444, QuickTime Animation or a PNG sequence rather than WebM. The trap: if you convert with the default decoder, FFmpeg still writes the file, it plays, and it is smaller. It is also opaque. Read back, every pixel was 255.

Converted to Decoded with Bytes Alpha kept
ProRes 4444 libvpx-vp9 62,034,554 yes, same values as the source
QuickTime Animation (qtrle) libvpx-vp9 92,176,076 yes, same values
PNG sequence (240 files) libvpx-vp9 63,857,616 yes
ProRes 4444 default 41,105,728 no, all 255
H.264 MP4 libvpx-vp9 1,440,811 no, H.264 has no alpha

The ProRes file from the default decoder is about 21 MB smaller than the good one, and FFmpeg printed no warning. So after any conversion, read the output back with the same alpha statistics instead of trusting that the file opens. The three good formats are 26 to 38 times the size of the WebM, which is the price of handing a clip to an editor.

I don't know how a given editor treats a transparent WebM directly, so the safer hand-off on this evidence is ProRes 4444 converted from the libvpx-vp9 read, though that rests on FFmpeg read-backs, not on any editor. The WebM here came from ImgIng's video background removal, a Beta that runs in desktop Chrome or Edge, processes locally, and doesn't work on phones: https://imging.ai/

Top comments (0)