From 66469ca418f850fb9048fe3b81df30ab3e1f012b Mon Sep 17 00:00:00 2001 From: "Claude (owner)" Date: Fri, 5 Jun 2026 16:05:44 +0900 Subject: [PATCH] =?UTF-8?q?fix(tools):=20ffmpeg=20=EC=9E=AC=EC=84=A4?= =?UTF-8?q?=EC=B9=98=EB=8F=84=20=EC=8B=A4=ED=96=89=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=ED=9B=84=20=EC=9B=90=EC=9E=90=EC=A0=81=20=EA=B5=90=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ffmpeg 재설치가 압축에서 찾은 바이너리를 검증 없이 바로 덮어써서, 실행 불가한 바이너리가 기존 정상 바이너리를 망가뜨리거나 ffprobe 누락 시 오래된 시스템 ffprobe 가 계속 쓰일 수 있었다. yt-dlp 와 동일하게: - ffmpeg/ffprobe 둘 다 필수로 찾고 - *.new 로 복사 후 각각 -version 실행 검증 - 둘 다 통과한 뒤에만 rename 으로 원자적 교체 Co-Authored-By: Claude Opus 4 --- src/tools.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/tools.ts b/src/tools.ts index c8eef98..4bc1ded 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -179,13 +179,26 @@ export async function updateFfmpeg(): Promise { } const found = await findBinaries(work, ['ffmpeg', 'ffprobe']) if (!found.ffmpeg) throw new Error('압축에서 ffmpeg 바이너리를 찾지 못했습니다.') + if (!found.ffprobe) throw new Error('압축에서 ffprobe 바이너리를 찾지 못했습니다.') + // 1) 임시 위치(*.new)로 복사 + 실행 검증. 둘 다 통과해야만 교체한다. + const staged: Array<{ name: 'ffmpeg' | 'ffprobe'; tmp: string; dest: string }> = [] for (const name of ['ffmpeg', 'ffprobe'] as const) { const src = found[name] if (!src) continue const dest = path.join(binDir, name) - await fs.copyFile(src, dest) - await fs.chmod(dest, 0o755) + const tmp = dest + '.new' + await fs.rm(tmp, { force: true }) + await fs.copyFile(src, tmp) + await fs.chmod(tmp, 0o755) + const v = spawnSync(tmp, ['-version'], { encoding: 'utf8' }) + if (v.status !== 0) { + await fs.rm(tmp, { force: true }) + throw new Error('내려받은 ' + name + ' 가 실행되지 않습니다.') + } + staged.push({ name, tmp, dest }) } + // 2) 검증을 모두 통과한 뒤에만 원자적 교체(rename). + for (const s of staged) await fs.rename(s.tmp, s.dest) } finally { await fs.rm(work, { recursive: true, force: true }) }