fix: auto-fix ffmpeg binary execute permission on startup

The bundled ffmpeg-static binary may lose execute permission after npm
install on some platforms, causing EACCES errors during playback. Now
checks and fixes the permission automatically before spawning ffmpeg.

https://claude.ai/code/session_01CqfKgV8GuCmWNpfx86H62X
This commit is contained in:
Claude committed 2026-03-31 15:58:54 +00:00
1 parent 455476ff72
commit 58caff3209
1 file changed
+17 -1
+17 -1
View File
@@ -1,6 +1,7 @@
import { spawn, type ChildProcess } from "node:child_process"; import { spawn, type ChildProcess } from "node:child_process";
import { EventEmitter } from "node:events"; import { EventEmitter } from "node:events";
import { createRequire } from "node:module"; import { createRequire } from "node:module";
import { accessSync, chmodSync, constants } from "node:fs";
import { createOpusEncoder, PCM_FRAME_BYTES, type Encoder } from "./encoder.js"; import { createOpusEncoder, PCM_FRAME_BYTES, type Encoder } from "./encoder.js";
import type { Logger } from "../logger.js"; import type { Logger } from "../logger.js";
@@ -8,9 +9,24 @@ import type { Logger } from "../logger.js";
const require = createRequire(import.meta.url); const require = createRequire(import.meta.url);
const ffmpegPath: string | null = require("ffmpeg-static"); const ffmpegPath: string | null = require("ffmpeg-static");
/** Ensure the bundled ffmpeg binary has execute permission. */
function ensureExecutable(binPath: string): boolean {
try {
accessSync(binPath, constants.X_OK);
return true;
} catch {
try {
chmodSync(binPath, 0o755);
return true;
} catch {
return false;
}
}
}
/** Resolve ffmpeg binary: prefer bundled ffmpeg-static, fall back to system PATH. */ /** Resolve ffmpeg binary: prefer bundled ffmpeg-static, fall back to system PATH. */
function getFfmpegCommand(): string { function getFfmpegCommand(): string {
if (ffmpegPath) return ffmpegPath; if (ffmpegPath && ensureExecutable(ffmpegPath)) return ffmpegPath;
return "ffmpeg"; // fallback to system-installed ffmpeg return "ffmpeg"; // fallback to system-installed ffmpeg
} }