Repository navigation
fix(linux): ship the shared ffmpeg CLI so transcription works over MCP and the CLI - #1222
Conversation
Linux packages carried the libav shared objects but no ffmpeg executable, so native STT extraction threw FfmpegUnavailableError over MCP and the CLI. build-linux-pipewire-helper.mjs now stages the SDK's shared CLI at linux-<arch>/ffmpeg with its RUNPATH on helper-ffmpeg/ (plus libavdevice), probes it, and before-pack refuses a Linux payload without it.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Summary
Linux packages now ship an ffmpeg executable, so native transcription works in the editor, over MCP (both transports) and through the CLI.
Root cause.
build:linuxrunsfetch:ffmpeg:sdk, which vendors the shared SDK but skips the CLI. The package carried the libav shared objects and noffmpeg, soresolveFfmpeg()returned null andextractMono16kPcmthrewFfmpegUnavailableError(stt:native-extraction-unavailable).Fix.
build-linux-pipewire-helper.mjsstages the SDK's shared ffmpeg CLI atlinux-<arch>/ffmpeg, the pathffmpegCandidates()already resolves.helper-ffmpeg/, which now also getslibavdevice(the CLI's one extra dependency).-Wl:../lib), so patchelf sets its RUNPATH to$ORIGIN/helper-ffmpeg, the helper's own scheme.-versionprobe fails the build if the staged CLI cannot start.before-pack.cjsrefuses a Linux payload withoutffmpeg, like the macOS guard from [Bug]: packaged macOS build ships ffmpeg libraries but no ffmpeg binary, so on-device transcription always fails #616.Why this option.
ffmpeg-shared.exe, macOS stages the SDK's CLI beside its dylibs. Every entry point already goes throughresolveFfmpeg(), so no runtime code changes.extractAudio.tsin Rust. Fixing the renderer fallback's path approval would only make the slow path work, and the editor would stay on it.fetch-ffmpeg.mjs.Packaging consistency.
linux-*/**from the same directory, so all four get it. libavdevice needs only libc, so nodependschange.OPENSCREEN_FFMPEG_PATHto an LGPLffmpeg-headless, the first candidate.--disable-programs, nocrates/thirdparty). The script warns and skips there, asstageFfmpegalready does.Out of scope. The renderer fallback still cannot read an unapproved path in the CLI and MCP runners. That path is no longer hit on a packaged build. It is worth a separate issue if a no-ffmpeg dev setup matters.
Related issue
Fixes #1221
Type of change
Release impact
Desktop impact
Screenshots / video
Not applicable.
Testing
patchelf --set-rpath '$ORIGIN/helper-ffmpeg'. Result:RUNPATH [$ORIGIN/helper-ffmpeg],-versionstarts from/withoutLD_LIBRARY_PATH,-Lreports LGPL, and the STT extraction args (-vn -af aresample=first_pts=0 -ac 1 -ar 16000 -f s16le) decode a 2 s AAC clip to 64,644 bytes. GLIBC ceiling of the CLI and libavdevice is 2.28.before-pack.test.mjs(Linux payload withoutffmpegis refused),audioPeaks.test.ts(platform pinned to linux: the candidate list containslinux-x64/ffmpeg, and thelinux-*/**filter ships it).npx tsc --noEmit,npx tsc -p tsconfig.test.json --noEmit,npm run lint: clean.npx vitest --run electron/stt electron/mcp electron/cli src/cli electron/media scripts/before-pack.test.mjs: 407 passed.build.ymlon this branch, run 38597935774. The Linux job logsStaged …/linux-x64/ffmpeg: ffmpeg version n8.1.2-34-g9b6c8969e0, then passes before-pack, the symbol floor and the clean-container check for deb, rpm and pacman.transcribeon that artifact is the remaining check.🤖 Generated with Claude Code