I built a cross-platform project using Kotlin Multiplatform targeting Android, Windows, and macOS. Now, I need to implement a media player that must support HLS. Because of this, I ruled out the JavaFX approach and opted for the following solution:
The Android version works perfectly. However, when running with VLCJ on macOS, the video just won’t render — there’s audio, and I’ve tried controlling playback via keyboard (play, pause, seek, volume, fullscreen, exit fullscreen), and all those functions work normally.
Here is the Gradle configuration and the relevant source code under /jvmMain/.
[versions]
vlcj = "4.11.0"
[libraries]
vlcj = { module = "uk.co.caprica:vlcj", version.ref = "vlcj" }
sourceSets {
// ...
jvmMain.dependencies {
implementation(compose.desktop.currentOs)
implementation(libs.kotlinx.coroutinesSwing)
implementation(libs.vlcj)
}
}
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
fun main() = application {
Window(
onCloseRequest = ::exitApplication,
title = "Media"
) {
App()
}
}
class JVMPlatform: Platform {
override val name: String = "Java ${System.getProperty("java.version")}"
}
actual fun getPlatform(): Platform = JVMPlatform()
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.awt.SwingPanel
import uk.co.caprica.vlcj.factory.MediaPlayerFactory
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer
import java.awt.Canvas
@Composable
actual fun Player(modifier: Modifier, url: String) {
val factory = MediaPlayerFactory()
val mediaPlayer: EmbeddedMediaPlayer = factory.mediaPlayers().newEmbeddedMediaPlayer()
SwingPanel(
factory = { Canvas() },
modifier = modifier.fillMaxSize(),
update = { canvas ->
mediaPlayer.videoSurface().set(factory.videoSurfaces().newVideoSurface(canvas))
mediaPlayer.media().play(url)
}
)
}
From V4LC github readme:
vlcj is primarily developed and therefore extensively tested on Linux - it does also work just fine on Windows and OSX, although there may be some limitations on OSX.
so it seems the OSX experience could be lacking in support. Notably,
On macOS, there are potentially critical limitations if you use any version of Java after the 1.6 version. This is because in Java 1.7 on macOS there is no longer any "heavyweight" window toolkit, everything is lightweight. This is a problem because VLC normally requires the window handle of a heavyweight window so it can be told where to render the video into.
From their version 4 tutorial:
It is possible to bundle up the VLC native libraries and the VLC plugins that you need and include them with your own application, but doing this is not as straightforward as you might think. If you're just starting out with vlcj, then just install VLC first.
Since you state you want multiplatform support, especially since you doing something like video you definitely are touching platform specific things like video/audio so it is wise to do verify.