feat: bundle yt-dlp and ffmpeg as sidecars

The app is now self-contained: yt-dlp, ffmpeg and ffprobe ship inside
the bundle and are resolved beside the executable, so a fresh Mac needs
nothing installed. A system copy still wins when present, which is how
to run a newer yt-dlp than the bundled one. yt-dlp is pointed at the
bundled ffmpeg explicitly, since a bundled app has no reason to have one
on PATH.

The binaries stay out of git (~140MB); scripts/fetch-binaries.sh pulls
them. Homebrew's ffmpeg cannot be used — it links a dozen dylibs and
does not relocate — so the static arm64 build is used instead.

Version checks moved to the async Command. yt-dlp is a PyInstaller
bundle that unpacks ~37MB on first run, and the blocking call was
stalling a runtime worker for roughly twenty seconds.

Bundle size goes from 19MB to 153MB.
This commit is contained in:
vincent
2026-08-29 11:41:14 +02:00
parent 9bb7b71225
commit 3296b5436a
6 changed files with 114 additions and 18 deletions
+9 -4
View File
@@ -216,14 +216,19 @@ export default function Settings({
</div>
</div>
<p className={`mt-2 ${HELP}`}>
yt-dlp and ffmpeg ship inside the app, so nothing needs installing. A copy
on your system is used instead if one is present, which is how you can run
a newer yt-dlp than the bundled one.
</p>
{missing && (
<div className="mt-2 rounded-lg border border-red-500/30 bg-red-500/5 p-3">
<p className="text-[11px] leading-snug text-red-700 dark:text-red-300">
Downloads need both tools. Install them with:
A bundled tool is missing, which should not happen. Reinstalling the app
will restore it; meanwhile <code>brew install yt-dlp ffmpeg</code> also
works.
</p>
<code className="mt-1.5 block rounded bg-slate-100 px-2 py-1 text-[11px] dark:bg-slate-800">
brew install yt-dlp ffmpeg
</code>
</div>
)}
</section>