fix(engine): hide ffmpeg console windows on Windows (#3381)

ffmpeg and ffprobe are console-subsystem binaries and Node defaults
windowsHide to false, so every spawn opened a visible console window on
Windows. A render shells out dozens of times across parallel workers,
which flashed a burst of windows across the user's desktop.

Applied at every production spawn site rather than only the two named in
the report, since they all share the cause: runFfmpeg, both gpuEncoder
probes, ffprobe, streamingEncoder, audioExtractor and the distributed
version check. windowsHide is a no-op on macOS and Linux.

The dev-only parity and regression harnesses are left alone; they never
run on a user's desktop.

Closes #3379
This commit is contained in:
Miguel Ángel
2026-08-21 11:37:21 -04:00
committed by GitHub
parent a9ea07edde
commit 315a7b758c
7 changed files with 59 additions and 3 deletions
@@ -88,7 +88,8 @@ export function parseAudioElements(html: string): AudioElement[] {
*/
function runFFmpeg(args: string[]): Promise<void> {
return new Promise((resolve, reject) => {
const ffmpeg = spawn(getFfmpegBinary(), args);
// See runFfmpeg.ts: keeps a console window off the user's desktop on Windows.
const ffmpeg = spawn(getFfmpegBinary(), args, { windowsHide: true });
trackChildProcess(ffmpeg);
let stderr = "";
@@ -333,7 +333,11 @@ let cachedFfmpegVersion: string | null = null;
*/
export async function readFfmpegVersion(): Promise<string> {
if (cachedFfmpegVersion !== null) return cachedFfmpegVersion;
const { stdout } = await execFile("ffmpeg", ["-version"], { maxBuffer: 1024 * 1024 });
const { stdout } = await execFile("ffmpeg", ["-version"], {
maxBuffer: 1024 * 1024,
// See runFfmpeg.ts: keeps a console window off the user's desktop on Windows.
windowsHide: true,
});
const firstLine = stdout.split(/\r?\n/)[0]?.trim() ?? "";
if (!firstLine) {
throw new Error("ffmpeg -version returned empty output");