Files
Filip131311 5a3f896652 fix(screen-recording): pick an ffmpeg that can actually encode, not just one that exists
Resolution trusted the first `command -v ffmpeg` hit unconditionally and only
consulted the fallback list when ffmpeg was ABSENT. A conda-forge build
(`--disable-gpl`, so no libx264) ahead of Homebrew on PATH therefore won every
time, and every recording died with `Unrecognized option 'preset'` — `-preset`
being a libx264-private option — while a working build sat in the fallback list,
unreachable.

Each candidate is now asked whether it can encode, and the first that says yes
wins.

The probe has to read ffmpeg's OUTPUT: `-h encoder=libx264` exits 0 whether or
not the encoder exists, so the obvious implementation — try/catch around
execFile — would look like a fix and change nothing. It matches the success
header rather than the failure sentence, because the header comes from ffmpeg's
help formatter and has been stable for a decade while the failure text is prose
any release may reword; keying on the failure string would silently re-break
recording, and in the direction that breaks setups which currently work.
`-hide_banner` is load-bearing rather than cosmetic: without it the build banner
goes to stderr carrying the literal `--enable-libx264`.

Everything inconclusive — a timeout, a kill, no output at all — is treated as
usable, so the probe can only ever demote a build that positively said it lacks
libx264. On any host where recording works today, ffmpeg still gets to speak for
itself.

Two things the failure path was getting wrong:

- "ffmpeg was not found on PATH. Install it" was shown to someone with three
  ffmpegs installed, which is what sent the reporter looking in the wrong place.
  That case now has its own message and its own failure code, since the code is
  rendered to the user verbatim. An EACCES binary counts as found, not missing,
  for the same reason.
- There was no way to override the choice. ARGENT_FFMPEG adds one, and the probe
  is deliberately ADVISORY for it: the probe's one new failure mode is a false
  negative on a build whose help output we don't recognise, and an escape hatch
  subject to the filter it exists to escape would rescue nobody. A pinned binary
  is never silently swapped for a different one either — it fails loudly instead.

`resolveBinary` is deleted rather than extended. Its generic half duplicated
`commandOnPath`, worse: the hand-rolled `/bin/sh -c command -v` could never match
on Windows, where Android recording is reachable. Going through `commandOnPath`
also means the binary we validate is the binary we spawn, instead of resolving
PATH twice and proving nothing.

Not cached on purpose — the tool-server has no idle shutdown by default, so a
cached "no usable ffmpeg" would outlive the user acting on our own error message.
One ~33ms probe per recording start, against a path that already waits ~800ms.

`resolveFfmpeg` keeps its name and stays reachable from ./watermark so the
existing test mock seam still disarms it.

Verified end to end on a host in the reported state (conda's ffmpeg first on
PATH): recording now produces a valid 87KB h264 mp4 at native resolution where it
previously failed instantly.

Fixes #621
2026-08-03 09:50:35 +02:00
..
2026-07-31 15:49:05 +02:00
2026-07-31 15:49:05 +02:00
2026-07-31 15:49:05 +02:00
2026-07-31 15:49:05 +02:00
2026-07-31 15:49:05 +02:00
2026-07-31 15:49:05 +02:00
2026-07-31 15:49:05 +02:00