Astrape: FFmpeg and dav1d source offer ====================================== Published at https://astrape.app/ffmpeg/. Generated 2026-10-13 by Scripts/ffmpeg-source-bundle.sh. This folder is the corresponding source for the FFmpeg and dav1d code in Astrape's FFmpeg.framework: the exact source archives the framework is built from, the build script as it was used, and the licence texts. The written offer at the end covers the object files of those two libraries, and only those two. Versions -------- FFmpeg 7.1 LGPL v2.1 or later, built with --disable-gpl and --disable-nonfree dav1d 1.5.1 BSD 2-Clause, built as a static library into FFmpeg.framework Files ----- Each file's size and SHA-256: ffmpeg-7.1.tar.bz2 13260188 bytes SHA-256 fd59e6160476095082e94150ada5a6032d7dcc282fe38ce682a00c18e7820528 FFmpeg 7.1 source, from https://ffmpeg.org/releases/ffmpeg-7.1.tar.bz2 dav1d-1.5.1.tar.xz 1020760 bytes SHA-256 401813f1f89fa8fd4295805aa5284d9aed9bc7fc1fdbe554af4292f64cbabe21 dav1d 1.5.1 source, from https://downloads.videolan.org/pub/videolan/dav1d/1.5.1/dav1d-1.5.1.tar.xz build_ffmpeg.sh 23477 bytes SHA-256 32b76494eaec11f22951679d6d1f5575e0660477e1eaaf2867bc40d86f766203 the build script, copied exactly as used FFmpeg.PrivacyInfo.xcprivacy 817 bytes SHA-256 8f564a0be42e1bd1c0f9b2b89c5a72dbdbeaadb1e284bce8b855fa5bb99a1881 the privacy manifest that build_ffmpeg.sh copies into the framework COPYING.LGPLv2.1 26526 bytes SHA-256 b634ab5640e258563c536e658cad87080553df6f34f62269a21d554844e58bfe FFmpeg's licence, LGPL v2.1, from inside the FFmpeg tarball dav1d-COPYING 1317 bytes SHA-256 b327887de263238deaa80c34cdd2ff3e0ba1d35db585ce14a37ce3e74ee389e9 dav1d's licence, BSD 2-Clause, from inside the dav1d tarball SHA256SUMS lists every file here except index.html. Check them with: shasum -a 256 -c SHA256SUMS How the app uses them --------------------- Astrape links FFmpeg as a dynamic framework, FFmpeg.framework, and embeds it in the app bundle. FFmpeg's code is in that framework, not in the app binary: Astrape.app/Frameworks/FFmpeg.framework/FFmpeg FFmpeg and dav1d are built as static libraries and linked into that one dynamic library, whose install name is @rpath/FFmpeg.framework/FFmpeg. There is a device slice (tvos-arm64) and a simulator slice (tvos-arm64-simulator), both arm64, with a minimum tvOS of 18.0. FFmpeg demuxes the containers and decodes the codecs the Apple TV has no hardware decoder for; dav1d decodes AV1. The system libraries the framework uses (libz, libiconv, and the Apple frameworks CoreFoundation, CoreMedia, CoreVideo, AudioToolbox and VideoToolbox) come from the tvOS SDK. They are not in this folder. Licences -------- FFmpeg is built with --disable-gpl and --disable-nonfree, so the framework is licensed under the LGPL v2.1 or later (COPYING.LGPLv2.1). dav1d is licensed under the BSD 2-Clause licence (dav1d-COPYING). Configure flags --------------- build_ffmpeg.sh passes these flags to FFmpeg's configure for both slices. They are the script's COMMON_FLAGS array, copied from it; --disable-gpl and --disable-nonfree are in the list. --disable-everything --disable-programs --disable-doc --disable-avdevice --enable-avfilter # only the deinterlacer, below --disable-postproc --disable-network --disable-gpl --disable-nonfree --enable-pic --enable-cross-compile --target-os=darwin --arch=arm64 # Containers we need to demux --enable-demuxer=matroska # MKV / WebM --enable-demuxer=mov # MP4 / MOV / M4V --enable-demuxer=mpegts # TS --enable-demuxer=mpegps # PS / VOB --enable-demuxer=avi --enable-demuxer=flv --enable-demuxer=ogg --enable-demuxer=asf --enable-demuxer=rm --enable-demuxer=concat # virtual concat for segmented files # Raw elementary-stream probes: MPEG-PS (VOB/MPG) identifies an H.264 / # HEVC video stream only by probing its payload with these demuxers. --enable-demuxer=h264 --enable-demuxer=hevc --enable-demuxer=mpegvideo --enable-demuxer=ivf # raw AV1 / VP9 / VP8 --enable-demuxer=obu # raw AV1 # Video the Apple TV can't decode in hardware: decoded here, encoded to # HEVC by VideoToolbox (Core/Engine/Transcode). --enable-libdav1d --enable-decoder=libdav1d # AV1 --enable-decoder=vp9 --enable-decoder=vp8 --enable-decoder=mpeg1video --enable-decoder=mpeg2video --enable-decoder=mpeg4 # MPEG-4 Part 2 (Xvid, DivX 4+) --enable-decoder=msmpeg4v1 --enable-decoder=msmpeg4v2 --enable-decoder=msmpeg4v3 # DivX 3 --enable-decoder=h263 --enable-decoder=flv # Sorenson H.263 --enable-decoder=vc1 --enable-decoder=wmv1 --enable-decoder=wmv2 --enable-decoder=wmv3 --enable-decoder=vp3 --enable-decoder=theora --enable-decoder=mjpeg --enable-decoder=prores --enable-parser=av1 --enable-parser=vp9 --enable-parser=vp8 --enable-parser=mpegvideo --enable-parser=mpeg4video --enable-parser=h263 --enable-parser=vc1 --enable-parser=mjpeg --enable-bsf=vp9_superframe_split # the VP9 decoder needs it # Audio decoders --enable-decoder=ac3 # Dolby Digital --enable-decoder=eac3 # Dolby Digital Plus (E-AC-3 + JOC/Atmos) --enable-decoder=truehd # TrueHD / MLP (see §8 license note) --enable-decoder=mlp --enable-decoder=dca # DTS (see §8 license note — defer for App Store) --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=mp3 --enable-decoder=mp2 # MPEG-1 Layer II: DVB recordings, VOB/MPG --enable-decoder=mp2float --enable-decoder=mp1 --enable-decoder=flac --enable-decoder=opus --enable-decoder=vorbis --enable-decoder=alac --enable-decoder=pcm_s16le --enable-decoder=pcm_s16be --enable-decoder=pcm_s24le --enable-decoder=pcm_s24be --enable-decoder=pcm_s32le --enable-decoder=pcm_bluray # lpcm in remux MKVs --enable-decoder=pcm_dvd # lpcm in VOB --enable-decoder=pcm_u8 # old AVI --enable-decoder=pcm_f32le --enable-decoder=pcm_alaw --enable-decoder=pcm_mulaw --enable-decoder=adpcm_ms # old AVI --enable-decoder=adpcm_ima_wav --enable-decoder=wmav1 # ASF / WMV audio --enable-decoder=wmav2 --enable-decoder=wmapro # Subtitle decoders --enable-decoder=pgssub # PGS (Blu-ray) — ubiquitous in remux MKVs --enable-decoder=dvdsub # VOBSUB --enable-decoder=dvbsub --enable-decoder=ass --enable-decoder=ssa --enable-decoder=srt --enable-decoder=subrip --enable-decoder=webvtt --enable-decoder=mov_text --enable-decoder=microdvd --enable-decoder=text # Parsers for audio + HEVC bitstream (NAL boundary detection, DTS detect) --enable-parser=hevc # HEVC NAL splitter — needed for RPU work --enable-parser=h264 --enable-parser=ac3 --enable-parser=eac3 --enable-parser=dca --enable-parser=aac --enable-parser=aac_latm --enable-parser=flac --enable-parser=opus --enable-parser=vorbis --enable-parser=mpegaudio --enable-parser=mlp # Muxers — Path B remuxes demuxed packets into fragmented MP4 via movenc # (DEMUX_ENGINE_PLAN.md §6.2 / Revision 2). Without these, the # avformat_alloc_output_context2(..., "mp4") call returns NULL and the whole # Path B muxer fails to initialise. movenc is LGPL-clean. --enable-muxer=mov # shared movenc core --enable-muxer=mp4 # fragmented MP4 output (dvcC / dec3 / dac3) # Bitstream filters. # hevc_mp4toannexb / h264_mp4toannexb — Path A's VTDecompressionSession # needs Annex-B; Path B keeps the native length-prefixed (MP4) framing. # extract_extradata — pull in-band VPS/SPS/PPS into codecpar->extradata. --enable-bsf=hevc_mp4toannexb --enable-bsf=h264_mp4toannexb --enable-bsf=extract_extradata # Encoders — TrueHD / DTS have no Apple TV passthrough path, so Path B # decodes them to PCM and re-encodes to E-AC-3 (Revision 2 audio decision), # which movenc then muxes with a dec3 box like native Dolby Digital Plus. # Both encoders are FFmpeg-native and LGPL-clean (no GPL/libfdk dependency). --enable-encoder=ac3 --enable-encoder=eac3 # Protocols — only file + custom (AVIOBridge). No network stacks from FFmpeg. --enable-protocol=file --enable-protocol=pipe --enable-protocol=custom # avio_alloc_context (our AVIOBridge) # swresample for audio decode → PCM conversion --enable-swresample # Disable bitcode (dead since Xcode 14) --disable-bzlib # avoid dependency; unused # Interlaced sources (DVD, broadcast MPEG-2 and VC-1) are deinterlaced # before they are encoded: bwdif, one frame out per frame in. --enable-filter=buffer --enable-filter=buffersink --enable-filter=bwdif Each slice also passes the following (build_slice in build_ffmpeg.sh). SLICE_DIR is the slice's build folder, CC and AR are the SDK's clang and ar, SYSROOT is the SDK, and CFLAGS and LDFLAGS are "-arch arm64 -target TARGET_TRIPLE -isysroot SYSROOT". TARGET_TRIPLE is arm64-apple-tvos18.0 for the device and arm64-apple-tvos18.0-simulator for the simulator. ./configure \ "${COMMON_FLAGS[@]}" \ --pkg-config-flags="--static" \ --prefix="${SLICE_DIR}/install" \ --cc="${CC}" \ --ar="${AR}" \ --sysroot="${SYSROOT}" \ --extra-cflags="${CFLAGS}" \ --extra-ldflags="${LDFLAGS}" \ --enable-static \ --disable-shared \ 2>&1 | tail -20 dav1d is built as a static library with meson, using the options that build_dav1d in build_ffmpeg.sh passes. The same function writes the meson cross file, which sets the C compiler to clang with the same -arch, -target and -isysroot flags. meson setup "${BUILD_DIR}/${SLICE}/dav1d-build" "${BUILD_DIR}/src/${DAV1D_SRC}" \ --cross-file "${CROSS}" --prefix "${PREFIX}" --libdir lib \ --buildtype release -Ddebug=true --default-library static \ -Denable_tools=false -Denable_tests=false -Denable_examples=false How to rebuild the framework ---------------------------- You need a Mac with Xcode 15 or later, the tvOS platform and SDKs installed in Xcode, the Command Line Tools, and four Homebrew packages (build_ffmpeg.sh checks for the tools): brew install nasm pkg-config meson ninja 1. Make a folder called Scripts, put build_ffmpeg.sh and FFmpeg.PrivacyInfo.xcprivacy in it, and run the script from the folder above Scripts: bash Scripts/build_ffmpeg.sh The script downloads both archives (the dav1d one is checked against its SHA-256), builds the device and simulator slices, and writes build/xcframeworks/FFmpeg.xcframework with a tvos-arm64 slice and a tvos-arm64-simulator slice, each with its dSYM. 2. To build from the archives in this folder instead of downloading them, extract them first into $TMPDIR/HDP_FFmpeg_Build/src/, so that ffmpeg-7.1/ and dav1d-1.5.1/ are there. The script uses a folder that already exists and skips the download. To change FFmpeg, change the extracted ffmpeg-7.1/ folder before you run the script. How to replace the framework (relinking) ---------------------------------------- Astrape loads FFmpeg from the framework embedded in it. To run Astrape with your own build: 1. Build your FFmpeg.framework as above, from the same FFmpeg version (7.1) and the same ABI: the same library versions as in the framework's Headers folder, the same install name (@rpath/FFmpeg.framework/FFmpeg), and a minimum tvOS of 18.0. 2. Replace Astrape.app/Frameworks/FFmpeg.framework with your framework. 3. Re-sign the framework, then the app, with your own signing identity, because the app's signature covers the framework. For example: codesign --force --sign "" Astrape.app/Frameworks/FFmpeg.framework codesign --force --sign "" --preserve-metadata=entitlements Astrape.app 4. Install the re-signed app on your Apple TV with your own provisioning. The written offer ----------------- For FFmpeg and dav1d as built into FFmpeg.framework, we will give you the object files of those two libraries on request (the .o files of the static FFmpeg and dav1d libraries that the framework is linked from), for at least three years from the release of the Astrape version that contains this framework. The source, the build script and the licence texts are already in this folder. To ask, write to the contact address on the Contact page of Astrape (the last item in the sidebar). The address is not written in this file. The Astrape version is shown in Settings > About.