mirror of
https://github.com/software-mansion/argent.git
synced 2026-09-14 19:27:14 +08:00
filip/ffmpeg-capability-probe
2 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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 |
||
|
|
7400179b5b |
Windows support: Android + Chromium host control plane (#421)
## What Makes Argent run on Windows. iOS Simulator is macOS-only (Apple), so on Windows that means the **Android + Chromium** host control plane. The blocker was twofold: (1) no Windows `simulator-server` binary, and (2) POSIX-only assumptions in the tool-server. Companion radon PR builds the binary and runs the Android emulator E2E on Windows: software-mansion/radon#134. ## Changes **Windows-aware tool-server / resolver / bundling** - New shared `commandOnPath()` helper — `where` on Windows, `command -v` via `/bin/sh` on POSIX. `android-binary`, `check-deps`, and `vega-cli` previously hardcoded `/bin/sh`, which never matches on Windows. - `android-binary`: append `.exe` to `adb`/`emulator` in the `$ANDROID_HOME` fallback; probe `%LOCALAPPDATA%\Android\Sdk` (Android Studio's Windows default). - simulator-server resolver + dispatcher + `bundle-tools` + `download-simulator-server.sh`: ship and resolve `simulator-server.exe` on `win32` (new `simulatorServerBinaryName()`), add `win32` to the bundled host keys, add the `simulator-server-argent-windows.exe` download target with PE arch validation. - `stop-metro`: resolve listening PIDs via `netstat -ano` on Windows (`lsof` is POSIX-only and threw ENOENT). - `adb.ts`: AVD root resolution used `$HOME` + `startsWith("/")` (rejects `C:\…`); now `os.homedir()` + `path.isAbsolute()`. - **`boot-device`**: the emulator was spawned `detached` with `stdio:"ignore"`; on Windows a detached emulator with NUL stdout/stderr never reaches `sys.boot_completed` (verified on `windows-latest`: the identical flag set boots fine with real handles, hangs with NUL). Redirect the detached emulator's output to a temp log file on win32. POSIX keeps `"ignore"`. **Tests** — cross-platform unit coverage for `commandOnPath` (both branches), win32 `.exe` Android resolution, win32 `.exe` simulator-server resolution, and a win32 AVD drive-path case; dep-gate tests now mock at the `commandOnPath` boundary so they're platform-agnostic. **CI** — `windows-e2e.yml` (`windows-chromium` on `windows-latest`): runs the resolver/dep unit tests natively on Windows, confirms `adb.exe` resolution via the SDK root, then drives a **real headless Chrome over CDP** through the tool-server (discover → screenshot → describe → tap → observe the DOM mutation). Flow in `scripts/ci/windows-chromium-e2e.mjs` (also runnable locally / in Docker). The `simulator-server.exe` build + the full **Android-emulator E2E on Windows** live in radon CI (the binary's source is the private radon repo). ## Verification (all green) - **Chromium control plane on real Windows** (`windows-latest`): `✓ discovered chromium-cdp-9222 → ✓ screenshot → ✓ describe → ✓ gesture-tap → ✓ DOM mutation observed`. Resolver/dep unit tests run natively; `adb.exe` resolves via the SDK root (it's *not* on PATH on the runner — the gap the resolver closes). - **Android emulator on real Windows** (radon#134, `windows-latest` / WHPX): the real Argent path — `boot-device` → `{ booted: true }` → screenshot via `simulator-server.exe` → gesture-tap — all green. (The boot-device fix above is what makes the detached emulator reach `boot_completed`.) - **Local clean-room E2E**: the Chromium flow runs green in a headless Linux Docker container (fresh `npm ci`, no host pollution). - **No regressions**: full tool-server suite (1624) + native-devtools-ios (16); ESLint/Prettier/typecheck clean; **Wayland E2E** (Linux AVD boot) and **Vega VVD E2E** still pass (they exercise the changed `adb.ts` / `boot-device.ts` / `vega-cli.ts` paths). ## Notes Android-emulator E2E needs WHPX nested virtualization — confirmed available on the current hosted `windows-latest` image (Server 2025); the emulator boots hardware-accelerated in ~3 min. --------- Co-authored-by: Ignacy Łątka <claude-hubert.gancarczyk@swmansion.com> Co-authored-by: Ignacy Łątka <latekvo@users.noreply.github.com> |