-
Notifications
You must be signed in to change notification settings - Fork 0
Development
- JDK 17+
- Android SDK (if building the Android target)
-
libvlc-devandvlc(for desktop) - A Supabase project (see Configuration)
git clone https://github.com/blarns/NuvioForLinux.git
cd NuvioForLinux
# Run on Linux desktop
./gradlew composeApp:run
# Compile only (no launch)
./gradlew composeApp:jvmMainClasses
# Run tests
./gradlew composeApp:jvmTest
# Build Android APK
./gradlew composeApp:assembleFullDebugNuvioForLinux/
├── composeApp/
│ └── src/
│ ├── commonMain/ # Shared UI, features, repositories
│ ├── androidMain/ # Android-specific implementations
│ ├── iosMain/ # iOS-specific implementations
│ ├── desktopMain/ # Linux/JVM desktop implementations
│ └── jvmMain/
│ └── resources/ # Desktop resources (app icon, etc.)
├── iosApp/ # Native Xcode project
├── scripts/
│ └── install-desktop.sh # App menu integration
└── nuvio.desktop # Desktop entry file
| File | Purpose |
|---|---|
desktopMain/kotlin/.../Main.kt |
App entry point, window setup, MPRIS2 init |
desktopMain/kotlin/.../PlayerEngine.desktop.kt |
VLCJ video player, keyboard/scroll input |
desktopMain/kotlin/.../Mpris2Handler.kt |
MPRIS2 D-Bus interface |
desktopMain/kotlin/.../DesktopWindowState.kt |
Fullscreen toggle singleton |
desktopMain/kotlin/.../PlayerControlBridge.kt |
Bridge between MPRIS2 and player controller |
desktopMain/kotlin/.../DesktopPrefs.kt |
Persistent key-value storage (wraps java.util.prefs) |
The desktop player uses VLCJ's buffer callback API. VLC decodes each frame into a ByteBuffer, which is then converted to a Skia ImageBitmap and painted onto a Compose Canvas. This avoids AWT/Swing Z-ordering issues that would prevent the controls overlay from rendering correctly on top of the video.
With VA-API enabled, VLC still copies the final decoded frame from GPU to CPU for the buffer callback (this is a known trade-off of the current approach). CPU savings still come from offloading the actual decode work to the GPU's media engine.
Desktop player settings use java.util.prefs.Preferences (via DesktopPrefs). Values larger than the JVM's 8 KB preference limit automatically overflow to files in ~/.local/share/nuvio/prefs/.
MPRIS2 is implemented using dbus-java-core 4.3.1. The service is started in main() and wrapped in runCatching so D-Bus unavailability never crashes the app. Playback control flows through PlayerControlBridge which holds a reference to the active VlcjPlayerController.
GitHub Actions runs two jobs on every push to main and develop:
- build-linux-desktop — compiles the JVM target
-
test — compiles and runs
jvmTest
Both jobs install VLC dependencies and create a blank local.properties before building.
Pull requests, bug reports, and feature suggestions are welcome at github.com/blarns/NuvioForLinux.
Note: The upstream NuvioMobile project is currently being rewritten by the official team and is not accepting pull requests. Changes should be targeted at this fork only.
Please read CONTRIBUTING.md before submitting.