Skip to content

Shusek/KMediaMpv

Repository files navigation

KMediaMpv

KMediaMpv is the optional MPV client used by KMediaPlayer. Since 0.3.0, it does not ship a private FFmpeg or libass stack. It links to the exact public ABI published by Shusek/KMediaFfmpegRuntime, so an application using KMediaMpv and KMediaBridge loads one shared native runtime.

The published clients contain only:

  • Android: libkmediampv_mpv.so, libkmediampv_placebo.so, and libkmediampv_jni.so;
  • desktop: the MPV and libplacebo client libraries;
  • iOS: KMediaMpv.xcframework and KMediaMpvPlacebo.xcframework.

There are no Git submodules and no runtime downloads by the library. Release builds fetch a versioned KMediaFfmpegRuntime SDK, verify its SHA-256 and runtime ID, and link the client against that ABI.

Published artifacts

dependencies {
    implementation("io.github.shusek:kmedia-mpv-runtime-android:0.3.0-rc.3")
    // or, for JVM desktop:
    implementation("io.github.shusek:kmedia-mpv-runtime-desktop:0.3.0-rc.3")
}

Both artifacts declare an exact transitive dependency on the matching io.github.shusek:kmedia-ffmpeg-runtime-* artifact. That runtime in turn declares the exact matching io.github.shusek:kmedia-ass-runtime-* dependency, so MPV never packages a second libass stack. Applications normally add composemediaplayer-mpv instead; the KMediaPlayer adapter brings this client and both runtime layers transitively.

KMediaMpv.podspec contains only the two client XCFrameworks and declares an exact dependency on KMediaFfmpegRuntime. Both device and simulator slices are ARM64.

Platform matrix

Platform Supported architecture Minimum
Android arm64-v8a, armeabi-v7a API 28
Linux x86_64, ARM64 release manifest
Windows x86_64 release manifest
macOS ARM64 macOS 13
iOS device/simulator ARM64 iOS 16.2

Android x86/x86_64 and Intel macOS are deliberately absent. Hosted GitHub runners build and inspect Android artifacts but do not pretend to run an accelerated ARM emulator. The release dispatch requires an attestation from the local API 28/API 35 ARM matrix described in the release workflow. An RC may instead carry the runtime repository's path-free pure-ARMv7 native graph report when no API 28 ARMv7 device is available. That exception never permits x86 and never satisfies the stable-release device gate.

Android decode policy

MpvAndroidDecodeMode.MEDIA_CODEC_COPY is the default. MPV first attempts MediaCodec copy-back and falls back to software decoding if hardware decoding cannot be initialized. SOFTWARE_ONLY disables hardware decoding for deterministic testing or compatibility workarounds. Official Android emulator images are selected as software-only automatically: their virtual MediaCodec can accept a stream and then stall indefinitely instead of reporting a decoder failure. Physical ARM devices continue to use MediaCodec copy-back by default.

MpvAndroidPlayer player = MpvAndroidPlayer.create(
    context,
    appPrivateSubtitleFontDirectory,
    MpvAndroidDecodeMode.MEDIA_CODEC_COPY
);

The runtime accepts local paths and file: URIs only. ASS/SSA rendering and embedded fonts are supplied by the shared libass stack.

Runtime identity

Before loading MPV, the Android and desktop clients call KMediaFfmpegRuntime.initialize(...) and compare the returned runtime ID with the ID embedded in their immutable client manifest. A second client requesting a different ID fails before its native library is loaded. Reports contain component versions, licenses, ABI and configuration hashes, but no filesystem paths.

Desktop packaging uses $ORIGIN on ELF, @rpath on Apple platforms, and explicit dependency-first loading on Windows. Native clients and shared runtime files may be materialized beside one another, but the shared runtime is initialized once per process.

Building a client

The canonical builder is native/build-client.py:

python3 native/build-client.py \
  --target macos-aarch64 \
  --runtime-sdk /path/to/runtime/sdk/macos-aarch64 \
  --runtime-version 0.1.0-rc.3 \
  --version 0.3.0-rc.3 \
  --revision 0123456789abcdef0123456789abcdef01234567 \
  --work /tmp/kmediampv-work \
  --output /tmp/kmediampv-client

Android additionally requires the pinned NDK and CMake paths. Output is rejected if it contains a private FFmpeg/libass library, a static archive, an unexpected architecture, a dependency outside the shared ABI, or a manifest whose runtime ID differs.

Release contents

Every immutable release includes:

  • Android and desktop Maven publications;
  • client SDK/evidence archives for every supported target;
  • the ARM-only Apple archive and exact-runtime podspec;
  • corresponding source for MPV, libplacebo and their build inputs;
  • a CycloneDX SBOM and SHA-256 manifest.

The release sequence is KMediaFfmpegRuntime first, then KMediaMpv. Existing versions are never overwritten.

Licensing boundary

KMediaMpv is mixed-license software. Java/Kotlin APIs, the Android JNI bridge, loaders and application integration retain the repository's private license. Build, verification and relinking machinery marked LGPL-2.1-or-later remains under that license. MPV, libplacebo and all other third-party inputs retain their own upstream terms and notices.

Moving FFmpeg/libass into KMediaFfmpegRuntime does not relicense KMediaMpv. The shared runtime is distributed independently under LGPL-2.1-or-later with its corresponding source and replacement instructions. See docs/LICENSING.md and docs/RELINKING.md.

Local checks

./gradlew check complianceCheck
python3 scripts/verify_source_compliance.py --root .

Real native integration additionally supplies a built runtime SDK and client output to the desktop test. The Android playback matrix runs on local ARM emulators or devices; no x86 emulator is part of this project.

About

Reproducible, fail-closed LGPL libmpv runtimes for KMediaPlayer

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages