From 301c8998bfdcac80ad3302e2d2ebe853e2ea6de1 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Sat, 5 Sep 2026 08:43:11 +0200 Subject: feat(packaging): bundle ffmpeg in the Windows installer by default winget install ffmpeg was considered and rejected as the mechanism: it needs network access and winget/App Installer present at the exact moment setup runs, and its failure mode is silent -- video just does not stream, with nothing pointing back at ffmpeg. Not viable for a non-technical install. MeshBay transcodes browser-incompatible video to H.264 (-c:v libx264, webrtc_server.py) -- a real encode, not remux -- so this needs a genuine GPL ffmpeg build; no LGPL-only build includes an H.264 encoder, since libx264 itself is GPL. packaging/win/fetch-ffmpeg.ps1 (new) Downloads, checksum-verifies and stages ffmpeg for the build. Source: BtbN/FFmpeg-Builds' Windows x86_64 gpl-shared preset -- shared DLLs rather than two independent static binaries, which is what nearly tripled this: the "full" static build many devs already have via winget is ~220 MB *per executable*. Pinned to one dated release tag (immutable once published) and its own sha256, not the "latest" alias BtbN repoints on every auto-build -- verified by hand first (downloaded, hash matched, ran a real encode+probe with libx264) before pinning. ffplay.exe (an SDL2 player, ~17 MB) is dropped; MeshBay never invokes it. Cached after the first build. Runs its own smoke test (encode + probe a real clip) so a broken fetch fails at build time, not for the first user who tries to watch something. packaging/win/LICENSE-ffmpeg.txt (new) GPLv3 notice + where the corresponding source is, required because this redistributes a GPL binary even though it is unmodified and only ever invoked as a subprocess. Ships alongside ffmpeg.exe in the installer. build-node-runtime.ps1 / build-win.ps1 Bundling is now the DEFAULT, replacing the old opt-in -FfmpegDir (which copied from a local directory and left most builds without ffmpeg at all). -SkipFfmpeg opts out for a smaller, streaming-less local-iteration build. Also fixes a real bug the ffmpeg change exposed rather than caused: the final `--help` smoke test did `$help -notmatch "meshbay-node"` against $help captured as a PowerShell ARRAY (one element per line) -- -notmatch on a collection is a FILTER, not a boolean test, and returns the non-matching elements; any non-empty array is truthy in if() regardless of content. Once --help wrapped past one line (it now does, with autostart/service in the verb list) this threw unconditionally. Fixed by joining to one string before matching, and pinned by a new test so a future edit cannot silently reintroduce the collection-vs-scalar trap. Verified: downloaded and hashed the pinned release by hand (matches), ran a real libx264 encode + ffprobe against the extracted build, fetch-ffmpeg.ps1 end to end (161 MB staged), a full build-node-runtime.ps1 run (308 MB node-runtime/) and a full installer build (MeshBay-Setup- 1.0.0.exe, 210.8 MB with ffmpeg bundled). Node suite 850 pass / 25 skip. Co-Authored-By: Claude Sonnet 5 --- packaging/win/README.md | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'packaging/win/README.md') diff --git a/packaging/win/README.md b/packaging/win/README.md index 7bbec13..b5ab1cd 100644 --- a/packaging/win/README.md +++ b/packaging/win/README.md @@ -17,7 +17,9 @@ Linux). `meshbay-common` rides along inside the node runtime. │ └─ node-runtime\ │ ├─ meshbay-node.exe frozen daemon (PyInstaller onedir) │ ├─ _internal\ … its Python + deps (aiortc, av, aioquic, …) -│ └─ ffmpeg.exe, ffprobe.exe only if built with -FfmpegDir +│ ├─ ffmpeg.exe, ffprobe.exe bundled by default, see Video (ffmpeg) below +│ ├─ av*.dll, swscale/swresample*.dll what those two link against +│ └─ LICENSE-ffmpeg.txt GPLv3 notice + where the source is └─ Uninstall MeshBay.exe ``` @@ -91,18 +93,35 @@ That runs [`build-win.ps1`](build-win.ps1): | 5 | [`build-node-runtime.ps1`](build-node-runtime.ps1) — PyInstaller freeze → `packages/meshbay-client/node-runtime/` | | 6 | `electron-builder --win nsis` → `packages/meshbay-client/dist/MeshBay-Setup-.exe` | -### ffmpeg - -Not bundled by default — the node resolves `ffmpeg`/`ffprobe` from `PATH` at -startup, and video streaming needs them. To make the installer self-contained: +### Video (ffmpeg) + +**Bundled by default** — [`fetch-ffmpeg.ps1`](fetch-ffmpeg.ps1) downloads, +checksum-verifies and stages it into `node-runtime/` on every build, ~161 MB. +Not optional in practice: MeshBay transcodes browser-incompatible video to +H.264 (`-c:v libx264`, a real encode, not remux), and no LGPL-only ffmpeg +build includes an H.264 *encoder* — libx264 itself is GPL. Asking an end user +to separately run `winget install ffmpeg` was considered and rejected: it +needs network access and `winget`/App Installer present at that exact moment, +and its failure mode is silent — video just does not stream, with nothing +pointing back at ffmpeg. + +Source: [BtbN/FFmpeg-Builds](https://github.com/BtbN/FFmpeg-Builds), the +Windows x86_64 **gpl-shared** preset — `ffmpeg.exe`/`ffprobe.exe` plus the +DLLs they both link against, rather than two independent static binaries +(the "full" static build many devs already have via `winget install ffmpeg` +is ~220 MB *per executable*; the equivalent Linux install used a shared +build for the same reason). `ffplay.exe` (an SDL2 player, ~17 MB) is dropped +— the daemon never invokes it. Pinned to one dated release tag, not the +`latest` alias BtbN repoints on every auto-build; both the tag and the sha256 +are hardcoded in the script and re-pinning is a deliberate edit, not +automatic. `LICENSE-ffmpeg.txt` (GPLv3 notice + where the source is) rides +along in the same directory — required, since this redistributes a GPL +binary even though it is unmodified and invoked only as a subprocess. ```powershell -npm run dist:win -- -FfmpegDir "C:\path\to\ffmpeg\bin" -# or: $env:MESHBAY_FFMPEG_DIR = "C:\path\to\ffmpeg\bin"; npm run dist:win +npm run dist:win -- -SkipFfmpeg # smaller, streaming-less build for local iteration only ``` -They are copied beside `meshbay-node.exe`, which is on the daemon's search path. - ### Iterating ```powershell -- cgit v1.2.3