render: fix WebM overlay alpha and ffmpeg 8 subtitles filter syntax#102
render: fix WebM overlay alpha and ffmpeg 8 subtitles filter syntax#102wdeynes wants to merge 1 commit into
Conversation
Two rendering bugfixes: 1. WebM/VP9 overlay transparency: ffmpeg's built-in vp9 decoder ignores the alpha side-channel, so transparent WebM overlays composite as opaque black boxes. Select libvpx-vp9 explicitly for .webm overlay inputs. 2. Subtitles filter on ffmpeg 8: the filtergraph parser rejects the positional quoted form (subtitles='/path...') when the path needs quoting - burns fail with a parse error. Use the filename= named-option syntax. Also skip force_style for .ass inputs, which carry their own embedded styles that force_style would clobber. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="helpers/render.py">
<violation number="1" location="helpers/render.py:521">
P2: Forcing the `libvpx-vp9` decoder on every `.webm` overlay based only on file extension introduces a codec-compatibility regression. WebM is a container that can hold VP8 as well as VP9, and `libvpx-vp9` is registered in FFmpeg exclusively for VP9 (`AV_CODEC_ID_VP9`)—it cannot decode VP8 streams. If a `.webm` overlay happens to contain VP8 (or another codec), ffmpeg will fail to open the input and abort compositing. Previously ffmpeg auto-selected the correct decoder, so this change narrows acceptable inputs and could break existing workflows. Consider probing the actual codec (e.g., via `ffprobe`) before selecting the decoder, or constraining the forced decoder to files verified as VP9.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
| if ov_path.suffix.lower() == ".webm": | ||
| inputs += ["-c:v", "libvpx-vp9"] |
There was a problem hiding this comment.
P2: Forcing the libvpx-vp9 decoder on every .webm overlay based only on file extension introduces a codec-compatibility regression. WebM is a container that can hold VP8 as well as VP9, and libvpx-vp9 is registered in FFmpeg exclusively for VP9 (AV_CODEC_ID_VP9)—it cannot decode VP8 streams. If a .webm overlay happens to contain VP8 (or another codec), ffmpeg will fail to open the input and abort compositing. Previously ffmpeg auto-selected the correct decoder, so this change narrows acceptable inputs and could break existing workflows. Consider probing the actual codec (e.g., via ffprobe) before selecting the decoder, or constraining the forced decoder to files verified as VP9.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At helpers/render.py, line 521:
<comment>Forcing the `libvpx-vp9` decoder on every `.webm` overlay based only on file extension introduces a codec-compatibility regression. WebM is a container that can hold VP8 as well as VP9, and `libvpx-vp9` is registered in FFmpeg exclusively for VP9 (`AV_CODEC_ID_VP9`)—it cannot decode VP8 streams. If a `.webm` overlay happens to contain VP8 (or another codec), ffmpeg will fail to open the input and abort compositing. Previously ffmpeg auto-selected the correct decoder, so this change narrows acceptable inputs and could break existing workflows. Consider probing the actual codec (e.g., via `ffprobe`) before selecting the decoder, or constraining the forced decoder to files verified as VP9.</comment>
<file context>
@@ -515,6 +515,11 @@ def build_final_composite(
+ # WebM/VP9 alpha lives in a side-channel that ffmpeg's native vp9
+ # decoder ignores; force libvpx-vp9 so transparent overlays stay
+ # transparent instead of compositing as opaque black.
+ if ov_path.suffix.lower() == ".webm":
+ inputs += ["-c:v", "libvpx-vp9"]
inputs += ["-i", str(ov_path)]
</file context>
| if ov_path.suffix.lower() == ".webm": | |
| inputs += ["-c:v", "libvpx-vp9"] | |
| if ov_path.suffix.lower() == ".webm": | |
| # Probe to ensure we only force libvpx-vp9 for actual VP9 streams. | |
| probe = subprocess.run( | |
| ["ffprobe", "-v", "error", "-select_streams", "v:0", | |
| "-show_entries", "stream=codec_name", "-of", | |
| "default=noprint_wrappers=1:nokey=1", str(ov_path)], | |
| capture_output=True, text=True, | |
| ) | |
| if probe.returncode == 0 and probe.stdout.strip() == "vp9": | |
| inputs += ["-c:v", "libvpx-vp9"] |
Two small rendering bugfixes in
helpers/render.py, independent of each other and of #62:1. WebM overlay transparency is lost (composites as opaque black).
ffmpeg's built-in
vp9decoder ignores the alpha side-channel in WebM/VP9, so any transparent overlay rendered to.webmcomposites as a solid black box. Fix: pass-c:v libvpx-vp9for.webmoverlay inputs so the alpha plane is actually decoded.2. Subtitle burns fail to parse on ffmpeg 8.
ffmpeg 8's filtergraph parser rejects the positional quoted form
subtitles='/abs/path'whenever the path needs quoting; the render dies with a filter parse error. Fix: use thefilename=named-option syntax, which works on ffmpeg 5–8. While here:.assinputs now skipforce_style— ASS files carry their own embedded styles, andforce_stylewas clobbering them.Both found in production use editing 4K talking-head videos with transparent motion-graphic overlays and burned captions on ffmpeg 8.1/macOS.
🤖 Generated with Claude Code
Summary by cubic
Fixes two rendering issues: transparent
.webmoverlays now keep alpha, and subtitle burns work onffmpeg 8while preserving.assstyles.-c:v libvpx-vp9for.webmoverlay inputs so the alpha channel is decoded.subtitles=filename='...'to avoidffmpeg 8parse errors; skipforce_stylefor.assto keep embedded styles.Written for commit 532446e. Summary will update on new commits.