import { execFile } from 'child_process' import { existsSync } from 'fs' import { getFfmpegPath, getFfprobePath } from './binaries' import type { FfmpegVersionResult } from '@shared/ipc' /** * Read the version token from an ffmpeg/ffprobe binary. Both print a first line * of the form " version Copyright ..." (e.g. * "ffmpeg version 6.1.1-full_build-www.gyan.dev Copyright ..."), so we return the * token after "version". Resolves null if the binary is absent, errors, times * out, or the line doesn't parse — Settings then shows "not found" instead of * failing. Unlike yt-dlp these are never self-updated, so there's no update path. */ function readToolVersion(path: string): Promise { if (!existsSync(path)) return Promise.resolve(null) return new Promise((resolve) => { execFile(path, ['-version'], { windowsHide: true, timeout: 15_000 }, (err, stdout) => { if (err) { resolve(null) return } const firstLine = stdout.split('\n', 1)[0] ?? '' const m = firstLine.match(/version\s+(\S+)/i) resolve(m?.[1] ?? null) }) }) } /** Versions of the bundled ffmpeg + ffprobe, read in parallel for the Settings panel. */ export async function getFfmpegVersions(): Promise { const [ffmpeg, ffprobe] = await Promise.all([ readToolVersion(getFfmpegPath()), readToolVersion(getFfprobePath()) ]) return { ffmpeg, ffprobe } }