Skip to content

fix(cli): warn when a WebM render silently drops its alpha channel [P2]#2044

Open
miguel-heygen wants to merge 1 commit into
mainfrom
fix/webm-alpha-verify
Open

fix(cli): warn when a WebM render silently drops its alpha channel [P2]#2044
miguel-heygen wants to merge 1 commit into
mainfrom
fix/webm-alpha-verify

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What

After a WebM render completes, best-effort ffprobe the output's pix_fmt; if it lacks alpha, print a non-blocking warning that names the concrete remedy (--format mov).

Why

HyperFrames always encodes WebM with an alpha-capable pixel format (needsAlpha = isWebm || isMov || isPngSequenceyuva420p). But some ffmpeg/libvpx builds silently emit opaque yuv420p even when handed genuine alpha (PNG) input plus -pix_fmt yuva420p -auto-alt-ref 0 -metadata alpha_mode=1 — the encode args are already textbook-correct; the build just drops the alpha plane. The render succeeds and plays back fine, so the lost transparency is only discovered after compositing.

Reproduced end-to-end (transparent HTML/CSS composition, single <h1>, GSAP opacity tween, no video/image):

$ hyperframes render comp --format webm -o out.webm
◇  out.webm
   5.8 KB · 1.0s video · rendered in 46.7s
$ ffprobe -show_entries stream=pix_fmt out.webm   # → yuv420p  (alpha gone)

Isolation confirmed it's the ffmpeg build, not HyperFrames: even a direct transparent RGBA PNG through the exact encode args yields yuv420p on the affected build (libvpx-vp9 and libvpx/vp8). So the alpha-drop itself is upstream and unfixable in HF; what HF can do is stop shipping a silently-wrong file. This is the HF-side root fix: verify the output matches what we requested.

Scope / safety

  • Only WebM is checked. MP4 is intentionally opaque; MOV (ProRes 4444) and PNG-sequence carry alpha through paths that don't hit libvpx-vp9.
  • No false positives: because webm always requests yuva420p, a probed non-alpha pix_fmt is an unambiguous "alpha was requested but not delivered" signal — and on builds where VP9 alpha does work, the probe sees yuva420p and stays silent.
  • Best-effort: a failed/absent ffprobe stays silent rather than warning speculatively. Never fails a completed render.

Tests

  • Pure decision (pixelFormatHasAlpha, webmAlphaAdvisory) unit-tested (7 cases).
  • Verified end-to-end: transparent WebM render now surfaces the warning; MP4 render stays silent.

New user-facing output

⚠  Transparency not preserved
   The WebM output is yuv420p (opaque). Your ffmpeg build's VP9 encoder did not
   preserve the alpha channel HyperFrames requested (yuva420p), so any transparency
   was flattened. For guaranteed transparency, re-render with --format mov (ProRes 4444).

HyperFrames always encodes WebM with an alpha-capable pixel format
(yuva420p), but some ffmpeg/libvpx builds silently emit opaque yuv420p
even when handed alpha input and -pix_fmt yuva420p. The render succeeds
and plays back fine, so the lost transparency is only discovered after
compositing (users report shipping a solid-black clip and colorkeying it
out by hand).

After a WebM render, best-effort ffprobe the output's pix_fmt; if it
lacks alpha, print a non-blocking warning that names the concrete remedy
(--format mov / ProRes 4444). Only WebM is checked (mp4 is intentionally
opaque; mov/png carry alpha through paths that don't hit libvpx-vp9), and
a failed probe stays silent rather than warning speculatively.

Pure decision (pixelFormatHasAlpha / webmAlphaAdvisory) unit-tested;
verified end-to-end that a transparent WebM render now surfaces the
warning while an MP4 render stays silent.
@miguel-heygen miguel-heygen marked this pull request as ready for review July 8, 2026 02:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant