Files
iptvnator/tools/embedded-mpv/README.md
T

186 lines
7.5 KiB
Markdown

# Embedded MPV Runtime
This directory owns the source builders, staging, manifests, and archive
helpers for IPTVnator's experimental Embedded MPV runtime.
The Linux architecture has a strict process boundary:
- Electron, `embedded_mpv.node`, and `embedded_mpv_frame_reader.node` must not
load or link libmpv.
- Native-view starts a separate system `mpv --wid` process.
- Frame-copy starts `iptvnator_mpv_helper`; only that helper may link libmpv.
Do not weaken this boundary to simplify packaging. A missing helper/runtime
must make frame-copy unavailable and leave native-view as the safe x64
fallback.
## Runtime Policy
Release builds use an LGPL-compatible, dynamically linked runtime:
- FFmpeg is built without `--enable-gpl` and `--enable-nonfree`.
- mpv is built with `-Dlibmpv=true` and `-Dgpl=false`.
- Bundled libraries remain individually replaceable under `native/lib`.
- Exact source URLs, versions, checksums or git commits, submodules, licenses,
build flags, local patches, and build scripts are published with the release.
Homebrew mpv is local-development-only. It requires
`IPTVNATOR_EMBEDDED_MPV_ALLOW_HOMEBREW=1`, and release validation rejects it.
## Generated Layout
```text
vendor/embedded-mpv/
darwin-arm64/
include/mpv/client.h
lib/*.dylib
runtime-manifest.json
darwin-x64/
include/mpv/client.h
lib/*.dylib
runtime-manifest.json
win32-x64/
include/mpv/client.h
lib/libmpv-2.dll # accepted basename variants are preserved
lib/libmpv.dll.a # or an MSVC import library
runtime-manifest.json
linux-x64/
include/mpv/client.h
lib/libmpv.so
lib/libmpv.so.2
lib/<declared closure>
runtime-manifest.json
```
These directories are generated release inputs and are ignored by git.
`runtime-manifest.json` is the profile-neutral source/build manifest. Packaging
writes a normalized `embedded-mpv-runtime.json` beside the native artifacts.
## Building And Staging
Stage an existing compatible prefix with:
```bash
pnpm embedded-mpv:stage-runtime -- darwin arm64 /path/to/prefix
pnpm embedded-mpv:stage-runtime -- darwin x64 /path/to/prefix
pnpm embedded-mpv:stage-runtime -- win32 x64 /path/to/prefix
pnpm embedded-mpv:stage-runtime -- linux x64 /path/to/prefix
```
Build the pinned macOS or Linux source runtime first when no prefix exists:
```bash
pnpm embedded-mpv:build-runtime -- arm64 /tmp/macos-prefix
pnpm embedded-mpv:stage-runtime -- darwin arm64 /tmp/macos-prefix
pnpm embedded-mpv:build-runtime:linux -- /tmp/linux-prefix
pnpm embedded-mpv:stage-runtime -- linux x64 /tmp/linux-prefix
```
The Linux builder runs only on Linux x64. It requires the tool versions and
system development interfaces declared in `build-linux-runtime.cjs`, including
Meson 1.6 or newer, Ninja, CMake, NASM, pkg-config, patchelf, and `readelf`.
It builds into an owned staging directory and publishes atomically, so it will
not delete or overwrite an arbitrary destination.
The pinned Linux source stack currently includes FFmpeg 8.1, mpv 0.41.0,
libplacebo 7.360.1, libass 0.17.3, FreeType 2.13.3, FriBidi 1.0.16,
HarfBuzz 8.5.0, Expat 2.8.2, Fontconfig 2.16.0, OpenSSL 3.5.7, hwdata
0.409, and libdisplay-info 0.1.1. The builder stages a private pinned
`pnp.ids`/`hwdata.pc`; libdisplay-info is not allowed to consume the build
host's `/usr/share/hwdata`.
Before publication, the Linux builder verifies:
- every archive digest and git/submodule commit;
- the exact FFmpeg/mpv flags and LGPL policy;
- an exact `libmpv.so.2` SONAME and complete reachable shared-library closure;
- `$ORIGIN` RUNPATHs with no build-prefix paths or undeclared host fallback;
- the external system-library allowlist;
- `GLIBC_2.35` and `GLIBCXX_3.4.30` ABI ceilings;
- file hashes, byte sizes, build inputs, licenses, and source obligations.
## Linux Package Profiles
Set one exact `IPTVNATOR_LINUX_FRAME_COPY_PROFILE` per packaging pass:
| Profile | Formats | Runtime handling |
| ---------- | ---------------- | ------------------------------------------------------------ |
| `system` | DEB, RPM, Pacman | Remove `native/lib`; require `libmpv2`, `mpv-libs`, or `mpv` |
| `portable` | AppImage, Snap | Retain the pinned LGPL closure under `native/lib` |
| `flatpak` | Flatpak | Retain the same pinned LGPL closure under `native/lib` |
Profiles cannot share one Electron Builder pass because its targets reuse the
same unpacked application directory. A missing or unsupported profile, or a
target from another profile, fails packaging.
Linux frame-copy release artifacts are x64-only. Non-x64 packages are always
marker-only even if environment variables point at the x64 staged runtime.
## Build Integration
`apps/electron-backend/build-embedded-mpv.js` builds the addon, frame reader,
and helper against the staged inputs. On Linux it links the helper to the
verified staged libmpv path rather than a generic host `-lmpv`, then checks
with `readelf` that:
- the helper has exactly the declared libmpv `DT_NEEDED`;
- the helper RUNPATH is `$ORIGIN/lib`;
- the addon and frame reader have no libmpv dependency;
- no runtime dependency contains an absolute/build-prefix loader path.
The package hook copies native artifacts into
`app.asar.unpacked/electron-backend/native/`, selects the system or bundled
layout, restores exact file modes, and writes the packaged manifest. Package
validation also scans the Electron executable and all shipped Electron
libraries for a direct libmpv dependency.
At startup, Linux x64 frame-copy is advertised only after the main process
validates that manifest/files and successfully executes:
```bash
iptvnator_mpv_helper --runtime-probe
```
The bounded probe initializes idle libmpv plus EGL/OpenGL and mpv render
contexts without media or shared memory. A timeout, loader failure, malformed
protocol, missing file, hash mismatch, or unusable graphics path returns a
stable reason and keeps the BrowserWindow sandbox enabled.
## CI And Source Distribution
Linux CI builds or restores the pinned source runtime once, then packages and
verifies `system`, `portable`, and `flatpak` independently. Every artifact is
extracted for manifest, mode, package-metadata, ELF-isolation, and helper-probe
checks. System formats are probed after their declared dependency is installed;
Snap and Flatpak also require a sandboxed probe where the runner supports it.
The binary release must include a source-compliance bundle containing the exact
downloaded archives (including hwdata), the recorded libplacebo checkout or git
bundle and submodules, builder/stager/manifest code, generated runtime manifest,
and local patches. A cache hit does not remove this obligation.
Windows CI stages a checksum-pinned x64 LGPL archive. The DLL basename encoded
in its import library is preserved and must be present beside
`iptvnator_mpv_helper.exe`. Tagged releases require explicit repository
configuration; the public fallback is for non-tag artifacts only.
## Local Development
Linux can use distribution development packages for an unshipped local build
(`libmpv-dev`, EGL/OpenGL/GBM development files, and X11 headers). Overrides:
`LIBMPV_INCLUDE_DIR` and `LINUX_NATIVE_LIBRARY_DIR`. Required/release package
builds must use the pinned staged runtime and manifest.
On macOS:
```bash
pnpm run serve:backend:embedded-mpv
```
This explicitly permits Homebrew for the local native build and enables the
experiment. It is not a release path.
See `docs/architecture/embedded-mpv-native.md` for the runtime capability,
fallback, controls, and packaged-release contracts.