perf: run yt-dlp from a zipapp on a portable Python
Replaces the official yt-dlp_macos sidecar. That build is PyInstaller one-file and unpacks 37MB on every invocation, costing ~8s per call on this machine — ruled out signing, xattrs and thinning the universal binary as causes, and it is 8% CPU over 8s, so it is the unpack itself. Every stream resolve paid it. The 3MB zipapp on a trimmed portable CPython starts in ~0.45s, a 17x improvement; a real stream resolve goes from ~10s to ~2.4s. macOS ships only Python 3.9 and yt-dlp needs 3.10+, hence bundling an interpreter. yt-dlp is now resolved as an argv prefix rather than a path, so a system install (a plain script, instant) still takes precedence. Bundle grows 153MB -> 219MB, which buys back the responsiveness.
This commit is contained in:
+45
-21
@@ -1,35 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fetches the helper binaries FlightTube ships as Tauri sidecars.
|
||||
# Fetches the helper tools FlightTube ships inside its bundle.
|
||||
#
|
||||
# They are not in git — together they are about 140MB. Run this once before
|
||||
# building, or after changing the target architecture.
|
||||
# They are not in git (~130MB together). Run this once before building.
|
||||
#
|
||||
# ffmpeg / ffprobe static arm64 binaries, shipped as Tauri sidecars
|
||||
# python + yt-dlp a portable interpreter plus the yt-dlp zipapp
|
||||
#
|
||||
# yt-dlp is deliberately NOT the official yt-dlp_macos build: that is a
|
||||
# PyInstaller one-file binary which unpacks ~37MB on every invocation, costing
|
||||
# about eight seconds per call. The 3MB zipapp on a portable interpreter starts
|
||||
# in under half a second. macOS ships only Python 3.9 and yt-dlp needs 3.10+,
|
||||
# which is why the interpreter has to come along.
|
||||
set -euo pipefail
|
||||
|
||||
TRIPLE="${1:-aarch64-apple-darwin}"
|
||||
DEST="$(cd "$(dirname "$0")/.." && pwd)/src-tauri/binaries"
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
BIN="$ROOT/src-tauri/binaries"
|
||||
RES="$ROOT/src-tauri/resources"
|
||||
TMP="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP"' EXIT
|
||||
mkdir -p "$DEST"
|
||||
mkdir -p "$BIN" "$RES"
|
||||
|
||||
echo "Fetching yt-dlp (official GitHub release)…"
|
||||
curl -fsSL -o "$TMP/yt-dlp" \
|
||||
https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos
|
||||
|
||||
# Static arm64 builds; Homebrew's ffmpeg links a dozen dylibs and cannot be
|
||||
# relocated into an app bundle.
|
||||
echo "Fetching ffmpeg and ffprobe (static arm64)…"
|
||||
# Homebrew's ffmpeg links a dozen dylibs and cannot be relocated into a bundle.
|
||||
for tool in ffmpeg ffprobe; do
|
||||
echo "Fetching $tool (static, osxexperts.net)…"
|
||||
curl -fsSL -A "Mozilla/5.0" -o "$TMP/$tool.zip" "https://www.osxexperts.net/${tool}9arm.zip"
|
||||
unzip -o -q "$TMP/$tool.zip" -d "$TMP"
|
||||
install -m 0755 "$TMP/$tool" "$BIN/$tool-$TRIPLE"
|
||||
done
|
||||
|
||||
for tool in yt-dlp ffmpeg ffprobe; do
|
||||
install -m 0755 "$TMP/$tool" "$DEST/$tool-$TRIPLE"
|
||||
echo " -> $DEST/$tool-$TRIPLE"
|
||||
done
|
||||
echo "Fetching the yt-dlp zipapp…"
|
||||
curl -fsSL -o "$RES/yt-dlp.pyz" \
|
||||
https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp
|
||||
|
||||
echo "Done. Verifying they run:"
|
||||
for tool in yt-dlp ffmpeg ffprobe; do
|
||||
"$DEST/$tool-$TRIPLE" -version 2>/dev/null | head -1 || \
|
||||
"$DEST/$tool-$TRIPLE" --version 2>/dev/null | head -1
|
||||
done
|
||||
echo "Fetching a portable Python…"
|
||||
PY_TAG="$(curl -fsSL -H 'User-Agent: flighttube-build' \
|
||||
https://api.github.com/repos/astral-sh/python-build-standalone/releases/latest \
|
||||
| python3 -c 'import json,sys; print(json.load(sys.stdin)["tag_name"])')"
|
||||
PY_ASSET="cpython-3.12.14+${PY_TAG}-${TRIPLE}-install_only_stripped.tar.gz"
|
||||
curl -fsSL -o "$TMP/python.tar.gz" \
|
||||
"https://github.com/astral-sh/python-build-standalone/releases/download/${PY_TAG}/${PY_ASSET// /%20}"
|
||||
rm -rf "$RES/python"
|
||||
tar -xzf "$TMP/python.tar.gz" -C "$TMP"
|
||||
mv "$TMP/python" "$RES/python"
|
||||
|
||||
echo "Trimming the interpreter to what yt-dlp needs…"
|
||||
P="$RES/python"
|
||||
rm -rf "$P/include" "$P/share" "$P/lib/pkgconfig" \
|
||||
"$P/lib/python3.12/test" "$P/lib/python3.12/idlelib" \
|
||||
"$P/lib/python3.12/tkinter" "$P/lib/python3.12/lib2to3" \
|
||||
"$P/lib/python3.12/ensurepip" "$P/lib/python3.12/turtledemo" \
|
||||
"$P/lib/python3.12/config-3.12-darwin"
|
||||
find "$P" -name "libpython*.a" -delete
|
||||
find "$P" -name "__pycache__" -type d -prune -exec rm -rf {} + 2>/dev/null || true
|
||||
|
||||
echo "Verifying:"
|
||||
"$BIN/ffmpeg-$TRIPLE" -version | head -1
|
||||
"$P/bin/python3.12" "$RES/yt-dlp.pyz" --version
|
||||
|
||||
Reference in New Issue
Block a user