summaryrefslogtreecommitdiffstats
path: root/packaging/win/build-node-runtime.ps1
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-05 08:43:11 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-05 08:43:11 +0200
commit301c8998bfdcac80ad3302e2d2ebe853e2ea6de1 (patch)
tree36b0606919f7fb1a7e2ace92d40d8f3e5a6d9d8d /packaging/win/build-node-runtime.ps1
parent171a36984feff5247786b32958b52673e13cc8f0 (diff)
downloadmeshbay-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.ps157
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 ""