diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-10-07 09:41:18 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-10-07 09:41:18 +0200 |
| commit | c1f9b0e324c2c47d832e21e5086f09e000d77eb5 (patch) | |
| tree | 3191cb484619dc2fb3b030f59069fda8f8a885bc /packages/meshbay-node/src | |
| parent | 0572bbde72514a9584b19fe031a03d4c9b23d74c (diff) | |
| download | meshbay-c1f9b0e324c2c47d832e21e5086f09e000d77eb5.tar.gz | |
fix(node): prefer the bundled ffmpeg over PATH in the frozen build
shutil.which never looks beside meshbay-node.exe, and node-runtime is
appended to the user PATH, so any earlier ffmpeg.exe on PATH ran instead
of the pinned copy. Log the resolved media tools at startup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src')
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/platform.py | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/platform.py b/packages/meshbay-node/src/meshbay_node/platform.py index 2255036..88db83d 100644 --- a/packages/meshbay-node/src/meshbay_node/platform.py +++ b/packages/meshbay-node/src/meshbay_node/platform.py @@ -171,25 +171,46 @@ _ffmpeg_path: str = "ffmpeg" _ffprobe_path: str = "ffprobe" +def _resolve_media_tool(name: str) -> str | None: + """ + The copy shipped next to a frozen meshbay-node.exe first, then PATH. + + ``shutil.which`` alone never looks in the executable's own directory: it + tries the current directory, then PATH, where the installer appends + node-runtime to the *user* PATH, which Windows places after the system one. + So any ffmpeg.exe earlier on PATH, from whatever application put it there, + ran instead of the pinned, checksummed copy we ship. + A name with a directory in it is the user's explicit choice and is left alone. + """ + if getattr(sys, "frozen", False) and os.path.basename(name) == name: + exe = name if name.lower().endswith(".exe") or sys.platform != "win32" \ + else f"{name}.exe" + bundled = Path(sys.executable).parent / exe + if bundled.is_file(): + return str(bundled) + return shutil.which(name) + + def check_media_tools( ffmpeg: str = "ffmpeg", ffprobe: str = "ffprobe", ) -> None: """Resolve ffmpeg/ffprobe at daemon startup. Raises RuntimeError if not found.""" global _ffmpeg_path, _ffprobe_path - resolved = shutil.which(ffmpeg) + resolved = _resolve_media_tool(ffmpeg) if not resolved: raise RuntimeError( f"{ffmpeg!r} not found in PATH. " "Install ffmpeg or set [node] ffmpeg_path in node.toml." ) _ffmpeg_path = resolved - resolved = shutil.which(ffprobe) + resolved = _resolve_media_tool(ffprobe) if not resolved: raise RuntimeError( f"{ffprobe!r} not found in PATH. " "Install ffmpeg or set [node] ffprobe_path in node.toml." ) _ffprobe_path = resolved + log.info("media tools: ffmpeg=%s ffprobe=%s", _ffmpeg_path, _ffprobe_path) def ffmpeg_cmd() -> str: |