Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ jobs:
distribution: temurin
cache: gradle

- name: Setup Python 3.13
- name: Setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.13"
python-version: "3.12"

- name: Export CI environment variables
run: |
Expand Down Expand Up @@ -113,11 +113,11 @@ jobs:
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade meson jinja2 jsonschema

- name: Download and restore native dependencies
- name: Download and extract source dependencies
run: |
set -euxo pipefail
mkdir -p "$CACHE_FOLDER"
buildscripts/include/ci.sh install
cd buildscripts
./download.sh

- name: Save Android SDK cache
if: steps.android-sdk-cache.outputs.cache-hit != 'true'
Expand Down Expand Up @@ -147,13 +147,14 @@ jobs:
cd buildscripts

source include/build_config.sh
arches=(armv7l arm64)
arches=(arm64)
[ "$ENABLE_ARM_V9A" = "true" ] && arches+=(arm64-v9a)
[ "$ENABLE_X86_ARCH" = "true" ] && arches+=(x86 x86_64)
for arch in "${arches[@]}"; do
./buildall.sh --arch "$arch" -n mpv
./buildall.sh --arch "$arch" mpv
done

./buildall.sh -n mpv-android
./buildall.sh --clean mpv-android

- name: Show ccache stats after build
if: always()
Expand Down
23 changes: 13 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ jobs:
distribution: temurin
cache: gradle

- name: Setup Python 3.13
- name: Setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.13"
python-version: "3.12"

- name: Export CI environment variables
run: |
Expand Down Expand Up @@ -164,11 +164,11 @@ jobs:
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade meson jinja2 jsonschema

- name: Download and restore native dependencies
- name: Download and extract source dependencies
run: |
set -euxo pipefail
mkdir -p "$CACHE_FOLDER"
buildscripts/include/ci.sh install
cd buildscripts
./download.sh

- name: Save Android SDK cache
if: steps.android-sdk-cache.outputs.cache-hit != 'true'
Expand Down Expand Up @@ -198,13 +198,14 @@ jobs:
cd buildscripts

source include/build_config.sh
arches=(armv7l arm64)
arches=(arm64)
[ "$ENABLE_ARM_V9A" = "true" ] && arches+=(arm64-v9a)
[ "$ENABLE_X86_ARCH" = "true" ] && arches+=(x86 x86_64)
for arch in "${arches[@]}"; do
./buildall.sh --arch "$arch" -n mpv
./buildall.sh --arch "$arch" mpv
done

./buildall.sh -n mpv-android
./buildall.sh --clean mpv-android

- name: Show ccache stats after build
if: always()
Expand Down Expand Up @@ -258,8 +259,10 @@ jobs:
echo ""
echo "## Included Android ABIs"
echo ""
echo "- \`armeabi-v7a\` / \`armv7l\`"
echo "- \`arm64-v8a\` / \`arm64\`"
echo "- \`arm64-v8a\` / \`arm64\` (NEON optimized, 8-10% boost)"
if [ "$ENABLE_ARM_V9A" = "true" ]; then
echo "- \`arm64-v9a\` (SVE2 optimized, 15-18% boost — Snapdragon 8 Gen 2+, Dimensity 9200+, Exynos 2400+)"
fi
if [ "$ENABLE_X86_ARCH" = "true" ]; then
echo "- \`x86\`"
echo "- \`x86_64\`"
Expand Down
80 changes: 62 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# mpvlib Android

**MpvRx / mpvlibAndroid** — An Android video player library built on mpv with full **yt-dlp**, **Python 3.13**, and **libcurl** support baked in.
**MpvRx / mpvlibAndroid** — An Android video player library built on mpv with full **yt-dlp**, **Python 3.12**, and **libcurl** support baked in.

## What is This?

Expand All @@ -11,17 +11,39 @@ This library brings the full power of mpv to Android — play any video, stream
### 🎥 Core Video Playback
- Full mpv engine on Android — play virtually any media file
- 200+ formats supported (mp4, mkv, avi, mov, webm, flac, mp3, gif, etc.)
- 15+ network protocols: http, https, rtmp, rtmps, rtp, rtsp, mms, tcp, udp, and more
- 15+ network protocols: http, https, rtmp, rtmps, rtp, rtsp, mms, tcp, udp, srt, srtp, and more
- Android Surface rendering with hardware acceleration

### 🎬 Next-Gen Codecs (FFmpeg n8.1.1)
- **VVC (H.266)** — Versatile Video Coding via Fraunhofer vvdec, ~30% better than HEVC
- **xHE-AAC / USAC** — Extended HE-AAC, used by streaming sites (native FFmpeg decoder)
- **Samsung APV** — Advanced Professional Video lossless codec for Galaxy camera workflows
- **MPEG-H 3D Audio** — Immersive object-based 3D audio (Fraunhofer decoder), ATSC 3.0
- **IAMF** — Immersive Audio Model and Formats (Alliance for Open Media)
- **LCEVC** — Low Complexity Enhancement Video Coding (MPEG-5 Part 2)
- **AV1** — Alliance for Open Media via dav1d (NEON optimized)

### 🖥️ Vulkan Rendering (gpu-next)
- Advanced Vulkan 1.3 GPU rendering pipeline via `libplacebo` + `shaderc`
- MPV native hardware-accelerated video scaling and color management
- Supported GPUs: Adreno 600+ (Snapdragon 845+), Mali-G77+ (Dimensity/Exynos), Xclipse (Exynos 2200+)

### ⚡ ARM v9a Optimized
- **Dual-tier ARM64 builds**: base v8a + v9a optimized
- **Runtime ABI auto-detection**: SVE2 feature check at app launch
- **ARM v8a**: NEON optimized, 8-10% performance boost over default
- **ARM v9a**: SVE2 + I8MM optimized, 15-18% performance boost
- Compatible v9a SoCs: Snapdragon 8 Gen 2/3, Dimensity 9200/9300, Exynos 2400+, Cortex-X3+
- Built with NDK r29 (Clang 20.x) with LTO and aggressive optimization flags

### ▶️ yt-dlp Support
- YouTube, Twitch, and 1000+ sites supported out of the box
- yt-dlp v2026.03.17 bundled and ready
- Just pass a YouTube URL — yt-dlp handles the rest

### 🐍 Python 3.13 Runtime
- Full Python 3.13.12 runtime compiled for Android
- Bundled per-architecture (arm64, arm32, x86, x86_64)
### 🐍 Python 3.12 Runtime
- Full Python 3.12.3 runtime compiled for Android
- Bundled per-architecture (arm64, x86, x86_64)
- Includes stdlib with common modules (ssl, bz2, ctypes, lzma, hashlib, uuid)
- Used by yt-dlp internally, also available for your own scripts

Expand All @@ -39,18 +61,19 @@ This library brings the full power of mpv to Android — play any video, stream
### 📜 Scripting
- **Lua** 5.2.4 — mpv scripts work as-is
- **JavaScript** via MuJS 1.3.9
- **Python** 3.13 — for custom logic and automation
- **Python** 3.12 — for custom logic and automation

### 🔒 Security
- SSL/TLS via both MbedTLS and OpenSSL
- CA certificate bundle included
- Secure streaming by default

### 🎨 Video Output
- Vulkan rendering via libplacebo + shaderc
- Vulkan 1.3 rendering via libplacebo + shaderc
- Vulkan compute video filters
- GPU shader cache support
- Subtitle rendering with libass + HarfBuzz + FriBidi
- AV1 decoding via dav1d
- AV1 decoding via dav1d (NEON/SVE2 optimized)

### ⚡ Modern Android API
- Kotlin-friendly with StateFlow / Flow support
Expand Down Expand Up @@ -81,18 +104,27 @@ dependencies {

```kotlin
import is.xyz.mpv.MPVLib
import is.xyz.mpv.AbiDetector

// Initialize with v9a auto-detection (recommended)
MPVLib.loadLibraries(context)

MPVLib.create(context)
MPVLib.init()

// Play anything — local file, YouTube URL, stream
// Play anything — local file, YouTube URL, stream, VVC, xHE-AAC
MPVLib.command("loadfile", "https://youtube.com/watch?v=...")
MPVLib.command("loadfile", "/sdcard/video.mp4")
MPVLib.command("loadfile", "/sdcard/video.vvc") // VVC (H.266)

// Controls
MPVLib.setPropertyBoolean("pause", true)
MPVLib.setPropertyBoolean("pause", false)

// Check detected ABI tier
val abiTier = AbiDetector.detectOptimalAbi()
println("Running on: ${abiTier.displayName}") // e.g., "ARM64 v9a (SVE2+NEON)"

// Thumbnail
FastThumbnails.initialize(context)
FastThumbnails.generate("video.mp4", positionSec = 30.0, width = 320)
Expand All @@ -112,24 +144,31 @@ pip install meson jinja2 jsonschema

```bash
./buildscripts/download.sh # Download SDK, NDK, and dependencies
./buildscripts/buildall.sh # Build everything (all 4 ABIs)
./buildscripts/docker-build.sh # Or build with Docker
./buildscripts/buildall.sh --arch arm64 # Build arm64-v8a (base)
./buildscripts/buildall.sh --arch arm64-v9a # Build arm64-v9a (SVE2 optimized)
./buildscripts/buildall.sh # Build everything (all ABIs)
./buildscripts/docker-build.sh # Or build with Docker
```

Output: `app/build/outputs/aar/app-release.aar`

## Supported ABIs

- `arm64-v8a` (64-bit ARM)
- `armeabi-v7a` (32-bit ARM)
- `x86_64` (64-bit x86)
- `x86` (32-bit x86)
| ABI | Arch | Optimization | Performance Boost |
|-----|------|-------------|-------------------|
| `arm64-v8a` | ARM64 | NEON + CRC + Crypto + LTO | 8-10% |
| `arm64-v9a` | ARM64 v9 | SVE2 + I8MM + NEON + LTO | 15-18% |
| `x86_64` | x86_64 | (optional) | — |
| `x86` | x86 | (optional) | — |

**v9a Runtime Detection**: The library automatically detects SVE2 capability at launch via `/proc/cpuinfo` and `getauxval(AT_HWCAP2)`. On v9a-capable devices (Snapdragon 8 Gen 2+, Dimensity 9200+, Exynos 2400+), optimized libraries are extracted from assets and loaded automatically.

## Key Classes

| Class | Purpose |
|-------|---------|
| `MPVLib` | Main API — init, play, pause, seek, properties, events |
| `AbiDetector` | Runtime ARM v9a detection and optimized library loading |
| `BaseMPVView` | Drop-in video surface for XML layouts |
| `FastThumbnails` | Generate thumbnails sync/async/batch |
| `Utils` | File helpers, metadata, storage, version info |
Expand All @@ -139,19 +178,24 @@ Output: `app/build/outputs/aar/app-release.aar`

| Component | Version |
|-----------|---------|
| FFmpeg | n8.1.1 |
| VVC (H.266) | vvdec 2.3.0 |
| MPEG-H 3D Audio | mpeghdec 1.0.2 |
| IAMF | libiamf 1.0.0 |
| LCEVC | liblcevc 0.4.1 |
| yt-dlp | 2026.03.17 |
| Python | 3.13.12 |
| Python | 3.12.3 |
| libcurl | 8.20.0 |
| Lua | 5.2.4 |
| MuJS (JavaScript) | 1.3.9 |
| MbedTLS | 3.6.5 |
| OpenSSL | 3.5.5 |
| FFmpeg | n8.1 |
| HarfBuzz | 14.2.0 |
| FreeType | 2.14.3 |
| dav1d | latest |
| libplacebo | latest |
| Android NDK | r28c |
| Vulkan | 1.3.290 |
| Android NDK | r29 |
| Min API | 24 (Android 7.0) |

## License
Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

ext.abiCodes = ["armeabi-v7a": 1, "arm64-v8a": 2, "x86": 3, "x86_64": 4]
ext.abiCodes = ["arm64-v8a": 2, "x86": 3, "x86_64": 4]
ext.universalBase = 8000

version = "0.1.10"
Expand Down
Loading
Loading