Exporting without FFmpeg installed used to show "Server error (503). Check
the terminal for details." The server already knew the exact cause and sent
a per-platform install command in the response body; Studio discarded that
body and printed the status code. The user found out only after the
composition was finished.
Studio now asks the dev server on load whether this machine can encode, and
the Renders panel shows the cause plus a copyable install command when it
cannot, with a Recheck that avoids restarting Studio.
- New GET /api/environment/ffmpeg calls runEnvironmentChecks() with every
optional check off, which is exactly the FFmpeg and ffprobe pair `doctor`
runs, so Studio and the CLI cannot disagree. Only a passing result is
cached.
- The refusal lives in startRender, not in a button. Studio renders from
three places (the panel's Export, the header's, and each composition card
in the sidebar), so a per-button check would leave the others free to
queue a render that cannot finish. The header and sidebar controls reveal
the prompt rather than going dead.
- A null probe result means "no answer", not "missing", so an older or
unreachable dev server cannot lock a working setup.
- Failed render responses now surface the server's { error, hint }.
- getFFmpegInstallCommand() is the single owner of platform-to-command, with
the prose hint derived from it. Windows gains a winget command and keeps
the manual download route.
Accessibility: the prompt's explanatory line measured 2.2:1 on the card's
amber background against a 4.5:1 minimum, because the panel's usual grey for
secondary text does not survive the tint. Now 6.6:1. Keyboard focus was
invisible on all three controls and now matches the panel's focus ring.
Also folds in cleanups the repo's gates required: the Renders tab moves out
of StudioRightPanel (it was at the 600-line cap and every field it needed was
already on the shell context), StudioContextInput stops keeping a second copy
of the renderQueue shape, and the server tests share one temp-project helper.