Repository navigation
fix(cli): check warns when a video's browser-playable copy cannot be made - #5441
Conversation
Edit accuracy: accurate 2061 (base branch 2061), smooth 1529 of thoseThe gate passes. Quarantined, measured but not gated (0) |
jrusso1020
left a comment
There was a problem hiding this comment.
Approving at 6167fa43.
The batch fix has the right shape. resolveProxies runs min(running slots, N) workers that each pull the next index and wait for that copy, so a batch never touches the waiting queue and can't hit ProxyCapacityError.
- Memory stays bounded, each index is taken once, and per-file dedupe still applies.
- A per-file rejection stays a settled result.
- The preview path and the other
resolveProxycallers are unchanged. The newFfmpegUnavailableErrorextendsProxyTranscodeError, so existinginstanceofhandling still matches.
I checked the description's claim against the source. The defaults are 2 running + 8 waiting (proxyTranscoder.ts:43-44), and the 11th request gets exactly media proxy queue is full; retry shortly.
Tests run locally: proxyTranscoder 41/41, checkBrowser + publishProxyBake 32/32. 5 of 7 mutants were killed; the 2 survivors are covered below.
Should-fix (not blocking):
stderrReason(proxyTranscoder.ts:403) splits on\nonly. ffmpeg's progress lines end in\r, and the runner doesn't pass-nostats, so a failure mid-encode carries the wholeframe=… \rframe=… \r[…] Error …run into the warning. The\rs also make terminal output overwrite itself. Splitting on/[\r\n]+/and capping at ~160 chars fixes it, and the existing 41 tests still pass with that change.- Nothing covers
runBrowserCheckactually callingdropFailedProxyEchoes(checkBrowser.ts:242-245). Removing the call keeps every test green, and that call is what turns "check failed" into "one finding, check passes". A case where the fake page emits a 502 for a failed file's?hf-proxy=URL would pin it.
Nits:
- With ffmpeg missing, render can't succeed either, yet check now passes with a warning where the 502s used to fail it. Worth a line in the description if that's intended.
resolveProxieshas no test for its 15-minute per-file wait cap. The publish test that covered it was removed here.
— Rames
What
hyperframes checknow reports a warning for each video whose browser-playable copy (the H.264/VP8 preview proxy) could not be made, naming the file and the reason. Before, check printed one stderr line such asmedia proxy pre-resolve: 0/2 ready, 2 failedand thenCheck passed, with no finding and no reason.Scope grew after review, to make that warning trustworthy:
media proxy queue is full; retry shortly(the transcoder queue holds 2 running plus 8 waiting). Check's pre-resolve and publish's proxy bake both fired every file at once. They now go through one batch resolver (resolveProxies) that keeps at most the running-slot count of its own asks in flight, so a long batch waits for room instead of being refused. This also fixespublishfailing outright on such projects.http_error502s on the?hf-proxy=request (errors, failing check) plus two runtime info notes. Those repeats are dropped for a file that already hasmedia_proxy_failed.ffmpeg exited with code 1now carries ffmpeg's last error-looking stderr line (falling back to the last line), not the closingConversion failed!.Why
A user reported a project with two HEVC videos where check printed
0/2 ready, 2 failedand passed. The rejection reason was thrown away, so neither the user nor we could tell what went wrong.Reproducing it: HDR HEVC sources (HLG or PQ, which is what phones record by default) need ffmpeg's
zscalefilter for the proxy's tone map. An ffmpeg built without libzimg rejects every HDR source withHDR proxying requires ffmpeg zscale/tonemap filters (libzimg). Homebrew's defaultffmpegformula has no zimg dependency, and Ubuntu 20.04's apt ffmpeg (4.2.7) has nozscaleeither. SDR HEVC (8-bit, 10-bit, 4:2:2, 4:4:4,hvc1andhev1tags, odd sizes) transcoded fine with every ffmpeg tried.A default
renderof the same project still succeeds with that ffmpeg (it decodes the original with ffmpeg and never uses the proxy), so this is a warning, not an error.publishdoes stop on a failed proxy, which the message says.Related work
Refs #3836 (moved the pre-resolve line to stderr).
How
proxyTranscoder.ts:resolveProxies(projectDir, sources)runs a small worker pool sized to the transcode slots, each request capped by the existing transcode timeout, and returns settled results. It bounds only its own requests; other callers in the same process can still fill the queue (none do today). The exit-code error message appends the last error-looking stderr line with trailing./!trimmed.FfmpegUnavailableErroris exported and now also covers spawn failures, so they are remembered only briefly like a missing ffmpeg.checkBrowser.ts:preResolveHostileMediaProxiesusesresolveProxiesand returns{ findings, failedPaths }: onemedia_proxy_failedwarning per failed file, or one for all files when ffmpeg is unusable.runBrowserCheckstarts its drafts from the findings;dropFailedProxyEchoesremoveshttp_error/request_faileddrafts for a failed file's?hf-proxy=URL (percent-decoded) and its runtime fallback/unavailable notes.publishProxyBake.ts: usesresolveProxies; per-file handling is unchanged.Test plan
resolveProxieswith 11 sources through the real queue (fake ffmpeg spawn): all fulfilled; with an unbounded batch, the 11th isrejected.FfmpegUnavailableError; an unusable ffmpeg gives one finding without the render sentence; red when reported per file.dropFailedProxyEchoeskeeps the warning plus unrelated errors and drops the 502s (including a percent-encodedmy%20clip.mov) and notes for the failed file; red without the filter or without the decode.runBrowserCheckcarries a rejected proxy intoruntimeFindingsas a warning naming file and reason; red on main.fallow audit --base origin/mainis clean on the changed files.checkruns on fixture projects):zscalehidden. Before:0/2 ready, 2 failed, Runtime0 errors, 0 warnings,Check passed. After:⚠ media_proxy_failed: Could not make a browser-playable copy of media/hlg.mp4: HDR proxying requires ffmpeg zscale/tonemap filters (libzimg); ...for each file, check passes.check --jsonstdout stays valid JSON. A defaultrenderwith the same ffmpeg completes.10/11 ready, 1 failedand⚠ media_proxy_failed: ... media/c11.mp4: media proxy queue is full; retry shortly. After:11/11 ready, 0 failed, no warning.⚠ media_proxy_failed: Could not make browser-playable copies of media/h8_hvc1.mp4, media/h10.mp4: ffmpeg binary not found. Publish stops on them ....✗ http_error: 502 loading media/clip.mov,Check failed. After: one⚠ media_proxy_failed: ... ffmpeg exited with code 1: <last stderr line>. ...,Check passed.