build: bundle playback and YouTube dependencies

Build pinned LGPL playback libraries and package standalone YouTube helpers inside the signed native app. Keep the CLI inside the app and relocate private library links for installation without runtime Homebrew dependencies.

Record adaptive fixture completion in its EXIT trap: cancellation can exit with status 143 before the TERM trap writes its marker, while native pause and quality preservation remain correct.
This commit is contained in:
2026-10-12 01:17:22 +02:00
parent 8eba97579f
commit 31c4759c1d
13 changed files with 911 additions and 113 deletions
+96
View File
@@ -0,0 +1,96 @@
#!/usr/bin/env python3
"""Exercise relocated runtime payloads with Homebrew and original build inputs denied."""
import json
import os
from pathlib import Path
import shutil
import subprocess
import sys
import tempfile
PROBE = r'''
import ctypes
import json
import sys
from pathlib import Path
app, movie = map(Path, sys.argv[1:])
frameworks = app / "Contents/Frameworks"
names = (app / "Contents/Resources/ffmpeg-libraries.txt").read_text().splitlines()
libraries = {name.split(".")[0]: ctypes.CDLL(str(frameworks / name)) for name in names}
format = libraries["libavformat"]
codec = libraries["libavcodec"]
codec.avcodec_license.restype = ctypes.c_char_p
assert codec.avcodec_license() == b"LGPL version 2.1 or later", codec.avcodec_license()
codec.avcodec_find_decoder_by_name.argtypes = [ctypes.c_char_p]
codec.avcodec_find_decoder_by_name.restype = ctypes.c_void_p
assert codec.avcodec_find_decoder_by_name(b"libdav1d"), "software AV1 decoder absent"
context = ctypes.c_void_p()
format.avformat_open_input.argtypes = [ctypes.POINTER(ctypes.c_void_p), ctypes.c_char_p, ctypes.c_void_p, ctypes.c_void_p]
format.avformat_find_stream_info.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
format.avformat_close_input.argtypes = [ctypes.POINTER(ctypes.c_void_p)]
assert format.avformat_open_input(ctypes.byref(context), bytes(movie), None, None) == 0
try:
assert format.avformat_find_stream_info(context, None) >= 0
finally:
format.avformat_close_input(ctypes.byref(context))
print(json.dumps({"media_read": True, "software_av1": True, "license": codec.avcodec_license().decode()}))
'''
def main():
source, fixtures, dependency_root = map(lambda value: Path(value).resolve(), sys.argv[1:])
with tempfile.TemporaryDirectory(prefix="terebi-bundle-") as directory:
root = Path(directory)
app = root / "relocated player.app"
shutil.copytree(source, app)
movie = root / "media with spaces.mp4"
shutil.copy2(fixtures / "av.mp4", movie)
macOS = app / "Contents/MacOS"
cli = root / "terebi"
cli.symlink_to(macOS / "terebi-cli")
profile = '(version 1)(allow default)' + ''.join(
'(deny file-read* (subpath ' + json.dumps(str(path)) + '))'
for path in (Path("/opt/homebrew"), Path("/usr/local"), source, dependency_root))
environment = {key: value for key, value in os.environ.items()
if not key.startswith(("DYLD_", "PYTHON"))}
environment.update(PATH="/usr/bin:/bin", XDG_CONFIG_HOME=str(root / "xdg"), PYTHONNOUSERSITE="1")
def invoke(arguments, expected=0):
result = subprocess.run(["/usr/bin/sandbox-exec", "-p", profile, *map(str, arguments)],
env=environment, capture_output=True, text=True, timeout=45)
if result.returncode != expected:
raise RuntimeError(f"Relocated command {arguments} returned {result.returncode}, expected {expected}:\n{result.stdout}{result.stderr}")
return result
invoke([cli, "--help"])
invoke([cli, "--default-config"])
native = invoke(["/usr/bin/python3", "-c", PROBE, app, movie])
print("PASS relocated private codec libraries:", native.stdout.strip())
deno = invoke([macOS / "deno", "eval", "--no-config", "--no-remote", "--no-npm",
'console.log(JSON.stringify([1,2,3].map(n => n * n)))'])
assert json.loads(deno.stdout) == [1, 4, 9], "bundled JavaScript runtime did not execute"
metadata = root / "youtube.json"
metadata.write_text(json.dumps({
"id": "jNQXAC9IVRw", "title": "Offline bundle fixture", "duration": 4,
"webpage_url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"extractor": "youtube", "extractor_key": "Youtube", "formats": [{
"format_id": "360", "height": 360, "width": 640, "ext": "mp4",
"url": "https://media.example/fixture.mp4", "protocol": "https", "vcodec": "h264", "acodec": "aac"}]}))
extracted = invoke([macOS / "yt-dlp", "--ignore-config", "--no-plugin-dirs", "--no-cache-dir",
"--no-remote-components", "--no-js-runtimes", "--js-runtimes", "deno:" + str(macOS / "deno"),
"--verbose", "--simulate", "--skip-download", "--dump-single-json", "--no-check-formats",
"--load-info-json", metadata])
video = json.loads(extracted.stdout)
assert video["url"] == "https://media.example/fixture.mp4" and video["height"] == 360
assert "yt_dlp_ejs" in extracted.stderr and "deno-" in extracted.stderr, extracted.stderr
print("PASS relocated standalone yt-dlp, packaged Python/EJS and Deno without host tools")
missing = next((app / "Contents/Frameworks").glob("libdav1d.*.dylib"))
missing.rename(root / "removed-dav1d.dylib")
failure = invoke([cli, "--new-instance", "--no-config"], expected=69)
print("PASS missing bundled transitive library blocks launch:", failure.stderr.strip())
invoke([cli, "--help"])
if __name__ == "__main__":
main()