From 568fc1b83762636d382c269be4a6295a229e4d71 Mon Sep 17 00:00:00 2001 From: hehua2008 Date: Fri, 22 Dec 2023 02:56:57 +0800 Subject: [PATCH] Fix replay issue in DesktopVideoPlayer.kt (#4048) See https://github.com/caprica/vlcj/tree/vlcj-4.x#threading-model # Threading Model This section is very important. With vlcj-4, every native event coming from LibVLC is processed on the native callback thread. This should give some small performance gains when compared with vlcj-3. The critical issue is that it is generally not permitted to call back into LibVLC from the event callback thread. Doing so may cause subtle failures or outright hard JVM crashes. A prime example of the sort of trap waiting for you is the very common case of handling a media player "finished" event so that you can then play the next item in a play-list: ```java mediaPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() { @Override public void finished(MediaPlayer mediaPlayer) { mediaPlayer.media().play(nextMrl); // <-- This is VERY BAD INDEED } }); ``` In this example, the finished method is being invoked on a native callback thread owned by LibVLC. The implementation of this method is calling back into LibVLC when it invokes play. This is very likely to cause a JVM crash and kill your application. In cases such as this, you should make use of an asynchronous task-executor queue conveniently provided by the MediaPlayer object passed to the listener method: ```java mediaPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() { @Override public void finished(final MediaPlayer mediaPlayer) { mediaPlayer.submit(new Runnable() { @Override public void run() { mediaPlayer.media().play(nextMrl); } }); } }); ``` --- .../org/jetbrains/compose/videoplayer/DesktopVideoPlayer.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experimental/components/VideoPlayer/library/src/desktopMain/kotlin/org/jetbrains/compose/videoplayer/DesktopVideoPlayer.kt b/experimental/components/VideoPlayer/library/src/desktopMain/kotlin/org/jetbrains/compose/videoplayer/DesktopVideoPlayer.kt index c5f999c161..9fa10b590d 100644 --- a/experimental/components/VideoPlayer/library/src/desktopMain/kotlin/org/jetbrains/compose/videoplayer/DesktopVideoPlayer.kt +++ b/experimental/components/VideoPlayer/library/src/desktopMain/kotlin/org/jetbrains/compose/videoplayer/DesktopVideoPlayer.kt @@ -90,9 +90,9 @@ private fun initializeMediaPlayerComponent(): Component { private fun MediaPlayer.setupVideoFinishHandler(onFinish: (() -> Unit)?) { DisposableEffect(onFinish) { val listener = object : MediaPlayerEventAdapter() { - override fun stopped(mediaPlayer: MediaPlayer) { + override fun finished(mediaPlayer: MediaPlayer) { onFinish?.invoke() - mediaPlayer.controls().play() + mediaPlayer.submit { mediaPlayer.controls().play() } } } events().addMediaPlayerEventListener(listener)