feat(setup): fetch ffmpeg on first run instead of bundling it
Ship a smaller installer that no longer carries ffmpeg.exe/ffprobe.exe (the bulk of its size). On first run they are downloaded from a pinned upstream archive (gyan 8.1.2), verified against a pinned SHA-256, and unpacked with the OS tar.exe into the managed userData/bin dir -- the same place as the self-updating yt-dlp, so they survive app updates and portable re-extraction. A hard onboarding gate blocks the app until they are present, with a "locate existing ffmpeg" folder-picker fallback for offline machines and a Repair action in Settings > About. The updater's streaming/checksum/redirect/idle-timeout download loop is extracted to lib/verifiedDownload.streamVerifiedFile and shared by both the app-installer download and the ffmpeg fetch; the updater's public behaviour and error strings are unchanged (its boundary tests still pass). No new npm dependency: extraction uses the System32 bsdtar resolved by absolute path (audit F3). Note: this commit also carries pre-existing, in-progress aria2c/network and updater-token work that was already uncommitted in the working tree and is entangled with the above in shared files (updater.ts, ipc.ts, preload/index.ts, mockApi.ts, shared/ipc.ts, plus the settings/network files and aria2c.exe). It was not cleanly separable by path, so it is included here rather than split out. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import { join, parse } from 'path'
|
||||
import { BrowserWindow, Notification, type WebContents } from 'electron'
|
||||
import {
|
||||
getYtdlpPath,
|
||||
getBinDir,
|
||||
getFfmpegDir,
|
||||
getAria2cPath,
|
||||
getFfmpegPath,
|
||||
getFfprobePath,
|
||||
@@ -243,7 +243,9 @@ export function buildCommand(opts: StartDownloadOptions, cookiesFile?: string):
|
||||
youtubePoToken: settings.youtubePoToken
|
||||
}
|
||||
const extraArgs = resolveExtraArgs(opts, settings)
|
||||
return buildArgs({ opts, outputTemplate, options, binDir: getBinDir(), access, extraArgs })
|
||||
// binDir feeds only `--ffmpeg-location`, so it's the managed ffmpeg dir (userData/bin),
|
||||
// where the first-run download / dev seed places ffmpeg.exe + ffprobe.exe.
|
||||
return buildArgs({ opts, outputTemplate, options, binDir: getFfmpegDir(), access, extraArgs })
|
||||
}
|
||||
|
||||
/** Build the exact command line for the current form state, without running it. */
|
||||
@@ -285,9 +287,11 @@ export function startDownload(wc: WebContents, opts: StartDownloadOptions): Star
|
||||
if (!existsSync(getFfmpegPath())) missingBins.push('ffmpeg.exe')
|
||||
if (!existsSync(getFfprobePath())) missingBins.push('ffprobe.exe')
|
||||
if (missingBins.length > 0) {
|
||||
// The first-run setup gate normally guarantees these are present; this backstops a
|
||||
// mid-session loss (AV quarantine, a cleared userData/bin) with a clear repair path.
|
||||
return {
|
||||
ok: false,
|
||||
error: `${missingBins.join(' and ')} not found in ${getBinDir()}. Add the ffmpeg build's binaries to resources/bin/ (see the README there).`
|
||||
error: `${missingBins.join(' and ')} not found. Open Settings → About and choose "Repair ffmpeg" to reinstall the media tools.`
|
||||
}
|
||||
}
|
||||
// Reject anything that isn't an http(s) URL before it reaches yt-dlp's argv,
|
||||
|
||||
Reference in New Issue
Block a user