fix(render): probe the base-chain filters and fail fast when one is missing (#89) - #90
Conversation
…issing (renezander030#89) `render` applies fps/scale/pad/setsar/format/concat/trim/setpts to every segment unconditionally, but probeFfmpegCapabilities only checked the flag-gated drawtext/overlay/libx264. A minimal ffmpeg build missing one of the unconditional filters (Remotion's bundled compositor binary, reported in renezander030#89) reached ffmpeg anyway and surfaced its raw parser error instead of naming the missing filter. The probe now checks all eight against the existing -filters output, and render fails fast with the same "ffmpeg lacks X" style message the drawtext/overlay fallback already uses. Closes renezander030#89
renezander030
left a comment
There was a problem hiding this comment.
Hi @Kubaklibre, thanks, the core fix is exactly what we scoped and the probe + renderDraft tests are solid. One thing before merge: the CLI test "--dry-run still fails fast" fails on Linux (exit 0). Root cause: cmdRender never routes --dry-run through renderDraft; it calls buildRenderPlan directly (src/index.ts ~L4412), and that's deliberate: dry-run is ffmpeg-free so plans stay inspectable on machines with no ffmpeg at all. The existing CLI dry-run test runs ungated on ffmpeg-less machines for the same reason. All three new tests skip on Windows, which is why it looked green locally.
Suggestion: keep dry-run ffmpeg-free, flip that test to assert exit 0 + a plan even with the minimal fake ffmpeg (locks the design in as a regression test), and trim the dry-run claim from the PR text and CHANGELOG entry. The renderDraft-internal dryRun fail-fast can stay as you have it; that path already probed before this PR. With that, happy to merge. Nice find on the real Remotion filter set.
…doesn't cmdRender routes --dry-run through buildRenderPlan directly, never through renderDraft/probeFfmpegCapabilities, so a plan stays inspectable on a machine with no ffmpeg at all (the pre-existing --dry-run test already relied on that). The new "--dry-run still fails fast" test from the first commit assumed otherwise and would have failed on Linux/macOS; it only looked green here because the fake-ffmpeg fixture skips on Windows. Flips that test to assert what actually happens (exit 0 + a plan) and corrects the CHANGELOG entry's --dry-run claim to match. The renderDraft-internal dryRun fail-fast is untouched — that path already probed before this PR and still does when renderDraft is called directly as a library function. Per review on renezander030#90.
|
Good catch — you're right, I hadn't noticed
Verified against the real Remotion binary and a local fake-ffmpeg script (can't run the new fixture through |
Closes #89.
What
renderappliesfps/scale/pad/setsar/format/concat/trim/setptsto every segment unconditionally — there's no flag that turns any of these off. ButprobeFfmpegCapabilitiesonly ever checked the flag-gated ones (drawtext,overlay,libx264), so a build missing one of the unconditional filters reachedspawnSyncanyway and surfaced ffmpeg's own low-level parser error (No option name near '30',Failed to set value '...' for option 'filter_complex': Invalid argument) instead of naming the actual missing filter.Reported and root-caused against Remotion's bundled compositor ffmpeg binary (
@remotion/compositor-win32-x64-msvc), a minimal build that compiles in only an explicit--enable-filter=allowlist. Turns out that build is missing four of the eight, not justfps:fps,pad,setsar,setptsare absent;scale,format,trim,concatare present. The new probe + test fixture reflect that real shape rather than afps-only guess.How
probeFfmpegCapabilitiesnow checks all eight base-chain filter names against the same-filtersoutput it already fetches (no extra spawn).renderDraftfails fast — beforebuildRenderPlan, same placement as the existingavailablecheck — naming exactly which filter(s) are missing, in the same "ffmpeg lacks X" style thedrawtext/overlayfallback already uses.--dry-runis unaffected by design:cmdRenderroutes it throughbuildRenderPlandirectly rather thanrenderDraft, so a plan stays inspectable on a machine with no ffmpeg at all — same reason the pre-existing--dry-runtest already ran ungated on ffmpeg-less machines. (renderDraft's owndryRunbranch, used when calling it as a library, still probes first — unchanged, and already covered before this PR.)fps=for an output-level-r. That would change per-segment CFR normalization ahead ofconcat, so fail-fast is the whole fix; an-rfallback can be a follow-up.Testing
probeFfmpegCapabilitiesagainst a fake ffmpeg fixture (/bin/shscript, same pattern asdetect-scenes.test.mjs's fake binaries) that reportsscale/format/trim/concatpresent and omitsfps/pad/setsar/setpts— mirrors the real Remotion binary's-filtersoutput.renderDraftagainst the same fixture: asserts the thrown message names exactly the four missing filters and never names a present one.--dry-runagainst the same fixture: asserts exit 0 + a valid plan, locking in that dry-run stays ffmpeg-free even when the probe would fail — this is the test the first commit had backwards (see review discussion below).spawnSynccan't exec a shebang script there directly — same constraintdetect-scenes.test.mjsalready works around); verified manually via explicitshinvocation + a standalone script exercisingprobeFfmpegCapabilities/buildRenderPlan/renderDraft/the CLI directly against the fake binary. Full existing suite still green except two pre-existing, unrelated Windows-onlysymlinkSyncEPERMfailures inatomic-temp.test.mjs(reproduced identically onmasterwith these changes stashed — needs Windows Developer Mode or admin, not something this PR touches).missing the filters 'fps', 'pad', 'setsar', 'setpts'against that same binary after.Test plan
npm run buildnpm test(678 pass / 2 pre-existing unrelated fails / 18 skipped, same skip/fail set asmaster)npx biome checkon the changed files (clean; the project-wide CRLF noise from this Windows checkout is acore.autocrlfartifact, not present in the actual git blobs — confirmed viagit diff)