diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-05 08:43:11 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-05 08:43:11 +0200 |
| commit | 301c8998bfdcac80ad3302e2d2ebe853e2ea6de1 (patch) | |
| tree | 36b0606919f7fb1a7e2ace92d40d8f3e5a6d9d8d /packaging/win/build-node-runtime.ps1 | |
| parent | 171a36984feff5247786b32958b52673e13cc8f0 (diff) | |
| download | meshbay-301c8998bfdcac80ad3302e2d2ebe853e2ea6de1.tar.gz | |
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 <noreply@anthropic.com>
Diffstat (limited to 'packaging/win/build-node-runtime.ps1')
| -rw-r--r-- | packaging/win/build-node-runtime.ps1 | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/packaging/win/build-node-runtime.ps1 b/packaging/win/build-node-runtime.ps1 index 5097b37..20eacc8 100644 --- a/packaging/win/build-node-runtime.ps1 +++ b/packaging/win/build-node-runtime.ps1 @@ -13,17 +13,22 @@ console-script wrapper bakes in an absolute interpreter path and does not survive being installed somewhere else). - ffmpeg/ffprobe are NOT bundled by default. Pass -FfmpegDir (or set - MESHBAY_FFMPEG_DIR) to copy them in beside the daemon; otherwise the node - resolves them from PATH at startup (meshbay_node.platform.check_media_tools) - and streaming needs ffmpeg installed separately. + ffmpeg/ffprobe are bundled by DEFAULT (fetch-ffmpeg.ps1) -- a real, silent + Windows install cannot ask an end user to separately run + `winget install ffmpeg`, and video streaming needs a genuine H.264 + encoder (libx264, GPL; no LGPL-only build has one), so there is no + smaller "it'll resolve from PATH" fallback worth defaulting to. Pass + -SkipFfmpeg for a smaller, streaming-less build for local iteration. .PARAMETER Python Interpreter used to build. Must be 3.12+ and able to install the packages. Default: a throwaway venv this script creates under build/_node-build-venv. -.PARAMETER FfmpegDir - Directory containing ffmpeg.exe and ffprobe.exe to bundle. Optional. +.PARAMETER SkipFfmpeg + Skip bundling ffmpeg. The node then resolves it from PATH at startup + (meshbay_node.platform.check_media_tools), and streaming needs ffmpeg + installed separately -- fine for a quick local iteration, not for a build + anyone else will install. .PARAMETER KeepBuildVenv Do not delete the throwaway build venv on success (faster re-runs). @@ -31,7 +36,7 @@ [CmdletBinding()] param( [string]$Python = "", - [string]$FfmpegDir = $env:MESHBAY_FFMPEG_DIR, + [switch]$SkipFfmpeg, [switch]$KeepBuildVenv ) @@ -104,17 +109,13 @@ if (-not (Test-Path (Join-Path $frozen "meshbay-node.exe"))) { throw "PyInstaller did not produce meshbay-node.exe at $frozen" } -# --- 4. optional ffmpeg ---------------------------------------------- -if ($FfmpegDir) { - foreach ($tool in @("ffmpeg.exe", "ffprobe.exe")) { - $src = Join-Path $FfmpegDir $tool - if (-not (Test-Path $src)) { throw "$tool not found in $FfmpegDir" } - Copy-Item $src (Join-Path $frozen $tool) - Step "bundled $tool" - } +# --- 4. ffmpeg (bundled by default) ----------------------------------- +if ($SkipFfmpeg -or $env:MESHBAY_SKIP_FFMPEG -eq "1") { + Write-Host " !! ffmpeg not bundled (-SkipFfmpeg) -- the node will look for it on PATH, and streaming needs it installed separately" -ForegroundColor Yellow } else { - Write-Host " ffmpeg not bundled -- the node will look for it on PATH" -ForegroundColor Yellow + Step "fetching ffmpeg (verified against a pinned checksum; cached after the first build)" + & (Join-Path $WinDir "fetch-ffmpeg.ps1") -OutDir $frozen } # --- 5. default.env (shared TMDB token) ------------------------------ @@ -174,12 +175,28 @@ if ($createdVenv -and -not $KeepBuildVenv) { # --- 7. smoke test ----------------------------------------------- # Capture, do NOT pipe to Select-Object -First: that stops the native process -# mid-write and reports a spurious non-zero exit. +# mid-write and reports a spurious non-zero exit. `& exe ... 2>&1` returns an +# ARRAY of lines once the output wraps past one line (which --help's now does, +# with autostart/service added) -- `$array -notmatch X` is a FILTER, not a +# boolean test: it returns the *non-matching* lines, and any non-empty array +# is truthy in `if()` regardless of what is in it. Almost every help line +# lacks the literal string "meshbay-node", so this threw unconditionally the +# moment --help grew past one line, having never actually been exercised +# against multi-line output before. Join to one string first, so this is a +# real substring test again. One retry after a short pause too: right after +# extracting ~180 MB of freshly-written DLLs (ffmpeg) an antivirus real-time +# scan can transiently slow or interfere with the very next process launch -- +# print the actual captured output on a genuine failure instead of a bare +# assertion, so it is diagnosable from the log rather than needing a re-run. Step "smoke test: meshbay-node --help" $exe = Join-Path $OutDir "meshbay-node.exe" -$help = & $exe --help 2>&1 -if ($LASTEXITCODE -ne 0) { throw "frozen meshbay-node --help exited $LASTEXITCODE" } -if ($help -notmatch "meshbay-node") { throw "frozen --help output looks wrong" } +$help = (& $exe --help 2>&1) -join "`n" +if ($LASTEXITCODE -ne 0 -or $help -notmatch "meshbay-node") { + Start-Sleep -Seconds 3 + $help = (& $exe --help 2>&1) -join "`n" +} +if ($LASTEXITCODE -ne 0) { throw "frozen meshbay-node --help exited $LASTEXITCODE`n$help" } +if ($help -notmatch "meshbay-node") { throw "frozen --help output looks wrong:`n$help" } $mb = (Get-ChildItem $OutDir -Recurse | Measure-Object Length -Sum).Sum / 1MB Write-Host "" |