
Libmpv bindings exposing player state, declarative video rendering controls, playback ownership/media-session handling, PiP and artwork URI loader, plus a build plugin to embed native mpv/FFmpeg libraries.
Kotlin Multiplatform bindings for mpv (libmpv), targeting Android, iOS, and Desktop (JVM).
| Module | Description |
|---|---|
mpv/core |
Reusable multiplatform libmpv interop layer; the Android target packages a Kotlin/Native JNI bridge for arm64-v8a and x86_64 directly in the AAR. |
mpv/compose |
Compose player state and platform video rendering controls. |
mpv/service |
Application-level playback ownership, platform media sessions, and interruption handling. |
mpv/pip |
Picture-in-picture integration. |
mpv/loader-coil |
Playback artwork URI resolution with Coil on all platforms. |
mpv-gradle-plugin |
Gradle plugin that wires native mpv/FFmpeg libraries into Desktop and iOS consumers. |
Sample apps live in example/ (shared Compose UI, Android, Desktop) and iosApp/ (iOS).
./gradlew :example:androidApp:assembleDebug
./gradlew :example:desktopApp:run
iosApp in Xcode and run from there(On Windows use .\gradlew.bat ….)
The first stable release is prepared as 0.1.0. Release notes are in CHANGELOG.md.
Resolve the Gradle plugin from Maven Central in settings.gradle.kts:
pluginManagement {
repositories {
mavenCentral()
google()
gradlePluginPortal()
}
}Also include mavenCentral() and google() in your dependency repositories.
plugins {
id("com.guyuuan.kmp.mpv") version "0.1.0"
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.guyuuan.kmp.mpv:core:0.1.0")
}
}
}Desktop: the plugin extracts the host's mpv native libraries, passes the directory to run, and bundles them into Compose Desktop app resources. Runtime search order: -Dmpv.kmp.native.dir → Compose resources (mpv-kmp/<platform>) → legacy mpv JARs → system mpv. Override with mpvKmp.desktopNativeDirectoryOverride.
iOS: the plugin resolves the ios-native-libs ZIP, links the framework against libmpv.dylib, and embeds/signs the mpv & FFmpeg dylibs. Add to the Kotlin framework Run Script phase:
./gradlew :shared:mpvKmpEmbedAndSignAppleFrameworkForXcodePublished under group com.guyuuan.kmp.mpv:
| Module | Artifact |
|---|---|
| Core player bindings | com.guyuuan.kmp.mpv:core |
| Compose integration | com.guyuuan.kmp.mpv:compose |
| Playback service | com.guyuuan.kmp.mpv:service |
| Picture-in-picture | com.guyuuan.kmp.mpv:pip |
| Coil artwork loader | com.guyuuan.kmp.mpv:loader-coil |
| Gradle plugin | com.guyuuan.kmp.mpv:mpv-gradle-plugin |
Kotlin APIs use the com.guyuuan.kmp.mpv package; platform artifacts (core-android, core-jvm, core-iosarm64, …) are resolved automatically from the root module metadata.
The Publish Maven packages workflow publishes branch pushes as dev-SNAPSHOT.
Pushing a version tag such as v0.1.0 publishes and releases both the Gradle plugin
and libraries to Maven Central as 0.1.0. The tag must point to the verified release
commit; creating it locally does not publish packages.
The workflow requires Maven Central credentials and an in-memory signing key in repository secrets. Before pushing the release tag, verify the release build and platform samples. After the workflow succeeds, confirm that the plugin, all five library modules, and their native archives are available on Maven Central.
Diagnostics go through Kermit. The default platform logger works without setup; add Kermit as a direct dependency to configure custom log writers before creating a player.
libavdevice, and device I/O support.arm64-v8a and x86_64; use splits.abi (as the example does) so each APK carries only one ABI set.iphoneos/arm64 and iphonesimulator/arm64; rebuild the simulator bundle with ./buildscripts/buildall.sh --platform ios --arch arm64-simulator mpv.After publishing a plugin version containing the useLocalNativeLibraries option, run ./gradlew -PusePublishedMpv=true --refresh-dependencies :example:desktopApp:run. This switches the example libraries and Gradle plugin to published dependencies and disables automatic discovery of repository native libraries. The configured version in the version catalog must refer to that publication.
Consumers can set mpvKmp { useLocalNativeLibraries.set(false) } to disable automatic local native discovery for Desktop and iOS. It defaults to true; explicit native directory overrides still take precedence. Desktop native ZIPs contain root-level libraries and META-INF/ legal resources, which are retained in application resources. Archives without the platform's main mpv library fail.
Kotlin Multiplatform bindings for mpv (libmpv), targeting Android, iOS, and Desktop (JVM).
| Module | Description |
|---|---|
mpv/core |
Reusable multiplatform libmpv interop layer; the Android target packages a Kotlin/Native JNI bridge for arm64-v8a and x86_64 directly in the AAR. |
mpv/compose |
Compose player state and platform video rendering controls. |
mpv/service |
Application-level playback ownership, platform media sessions, and interruption handling. |
mpv/pip |
Picture-in-picture integration. |
mpv/loader-coil |
Playback artwork URI resolution with Coil on all platforms. |
mpv-gradle-plugin |
Gradle plugin that wires native mpv/FFmpeg libraries into Desktop and iOS consumers. |
Sample apps live in example/ (shared Compose UI, Android, Desktop) and iosApp/ (iOS).
./gradlew :example:androidApp:assembleDebug
./gradlew :example:desktopApp:run
iosApp in Xcode and run from there(On Windows use .\gradlew.bat ….)
The first stable release is prepared as 0.1.0. Release notes are in CHANGELOG.md.
Resolve the Gradle plugin from Maven Central in settings.gradle.kts:
pluginManagement {
repositories {
mavenCentral()
google()
gradlePluginPortal()
}
}Also include mavenCentral() and google() in your dependency repositories.
plugins {
id("com.guyuuan.kmp.mpv") version "0.1.0"
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.guyuuan.kmp.mpv:core:0.1.0")
}
}
}Desktop: the plugin extracts the host's mpv native libraries, passes the directory to run, and bundles them into Compose Desktop app resources. Runtime search order: -Dmpv.kmp.native.dir → Compose resources (mpv-kmp/<platform>) → legacy mpv JARs → system mpv. Override with mpvKmp.desktopNativeDirectoryOverride.
iOS: the plugin resolves the ios-native-libs ZIP, links the framework against libmpv.dylib, and embeds/signs the mpv & FFmpeg dylibs. Add to the Kotlin framework Run Script phase:
./gradlew :shared:mpvKmpEmbedAndSignAppleFrameworkForXcodePublished under group com.guyuuan.kmp.mpv:
| Module | Artifact |
|---|---|
| Core player bindings | com.guyuuan.kmp.mpv:core |
| Compose integration | com.guyuuan.kmp.mpv:compose |
| Playback service | com.guyuuan.kmp.mpv:service |
| Picture-in-picture | com.guyuuan.kmp.mpv:pip |
| Coil artwork loader | com.guyuuan.kmp.mpv:loader-coil |
| Gradle plugin | com.guyuuan.kmp.mpv:mpv-gradle-plugin |
Kotlin APIs use the com.guyuuan.kmp.mpv package; platform artifacts (core-android, core-jvm, core-iosarm64, …) are resolved automatically from the root module metadata.
The Publish Maven packages workflow publishes branch pushes as dev-SNAPSHOT.
Pushing a version tag such as v0.1.0 publishes and releases both the Gradle plugin
and libraries to Maven Central as 0.1.0. The tag must point to the verified release
commit; creating it locally does not publish packages.
The workflow requires Maven Central credentials and an in-memory signing key in repository secrets. Before pushing the release tag, verify the release build and platform samples. After the workflow succeeds, confirm that the plugin, all five library modules, and their native archives are available on Maven Central.
Diagnostics go through Kermit. The default platform logger works without setup; add Kermit as a direct dependency to configure custom log writers before creating a player.
libavdevice, and device I/O support.arm64-v8a and x86_64; use splits.abi (as the example does) so each APK carries only one ABI set.iphoneos/arm64 and iphonesimulator/arm64; rebuild the simulator bundle with ./buildscripts/buildall.sh --platform ios --arch arm64-simulator mpv.After publishing a plugin version containing the useLocalNativeLibraries option, run ./gradlew -PusePublishedMpv=true --refresh-dependencies :example:desktopApp:run. This switches the example libraries and Gradle plugin to published dependencies and disables automatic discovery of repository native libraries. The configured version in the version catalog must refer to that publication.
Consumers can set mpvKmp { useLocalNativeLibraries.set(false) } to disable automatic local native discovery for Desktop and iOS. It defaults to true; explicit native directory overrides still take precedence. Desktop native ZIPs contain root-level libraries and META-INF/ legal resources, which are retained in application resources. Archives without the platform's main mpv library fail.