Commit e947b9b8 authored by Geoffrey Métais's avatar Geoffrey Métais
Browse files

Confine mediaplayer events in a Channel for safety

parent d98539a3
......@@ -7,6 +7,8 @@ import android.support.v4.media.session.PlaybackStateCompat
import android.widget.Toast
import kotlinx.coroutines.experimental.*
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.channels.actor
import org.videolan.libvlc.*
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.vlc.BuildConfig
......@@ -65,8 +67,8 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
it.release()
}
private var mediaplayerEventListener: MediaPlayer.EventListener? = null
internal fun startPlayback(media: Media, listener: MediaPlayer.EventListener) {
private var mediaplayerEventListener: MediaPLayerEventListener? = null
internal fun startPlayback(media: Media, listener: MediaPLayerEventListener) {
mediaplayerEventListener = listener
seekable = true
pausable = true
......@@ -274,24 +276,29 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
}
private var lastTime = 0L
override fun onEvent(event: MediaPlayer.Event?) {
if (event === null) return
when(event.type) {
MediaPlayer.Event.Playing -> playbackState = PlaybackStateCompat.STATE_PLAYING
MediaPlayer.Event.Paused -> playbackState = PlaybackStateCompat.STATE_PAUSED
MediaPlayer.Event.EncounteredError -> setPlaybackStopped()
MediaPlayer.Event.PausableChanged -> pausable = event.pausable
MediaPlayer.Event.SeekableChanged -> seekable = event.seekable
MediaPlayer.Event.LengthChanged -> length = event.lengthChanged
MediaPlayer.Event.TimeChanged -> {
val time = event.timeChanged
if (time - lastTime > 950L) {
currentTime.value = time
lastTime = time
private val eventActor = actor<MediaPlayer.Event>(UI, Channel.UNLIMITED) {
for (event in channel) {
when (event.type) {
MediaPlayer.Event.Playing -> playbackState = PlaybackStateCompat.STATE_PLAYING
MediaPlayer.Event.Paused -> playbackState = PlaybackStateCompat.STATE_PAUSED
MediaPlayer.Event.EncounteredError -> setPlaybackStopped()
MediaPlayer.Event.PausableChanged -> pausable = event.pausable
MediaPlayer.Event.SeekableChanged -> seekable = event.seekable
MediaPlayer.Event.LengthChanged -> length = event.lengthChanged
MediaPlayer.Event.TimeChanged -> {
val time = event.timeChanged
if (time - lastTime > 950L) {
currentTime.value = time
lastTime = time
}
}
}
mediaplayerEventListener?.onEvent(event)
}
mediaplayerEventListener?.onEvent(event)
}
override fun onEvent(event: MediaPlayer.Event?) {
if (event != null) eventActor.offer(event)
}
private fun setPlaybackStopped() {
......@@ -307,4 +314,8 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
// Toast.makeText(VLCApplication.getAppContext(), VLCApplication.getAppContext().getString(R.string.feedback_player_crashed), Toast.LENGTH_LONG).show()
// }
// }
}
internal interface MediaPLayerEventListener {
suspend fun onEvent(event: MediaPlayer.Event)
}
\ No newline at end of file
......@@ -660,42 +660,42 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
}
}
private val mediaplayerEventListener = MediaPlayer.EventListener { event ->
when (event.type) {
MediaPlayer.Event.Playing -> {
medialibrary.pauseBackgroundOperations()
videoBackground = false
val mw = medialibrary.findMedia(getCurrentMedia())
if (newMedia) {
loadMediaMeta(mw)
if (mw.type == MediaWrapper.TYPE_STREAM) medialibrary.addToHistory(mw.location, mw.title)
saveMediaList()
savePosition(true)
saveCurrentMedia()
newMedia = false
if (player.hasRenderer|| !player.isVideoPlaying()) showAudioPlayer.value = true
}
}
MediaPlayer.Event.Paused -> medialibrary.resumeBackgroundOperations()
MediaPlayer.Event.EndReached -> {
if (currentIndex != nextIndex) {
saveMediaMeta()
if (isBenchmark) player.setPreviousStats()
if (nextIndex == -1) savePosition(true)
private val mediaplayerEventListener = object : MediaPLayerEventListener {
override suspend fun onEvent(event: MediaPlayer.Event) {
when (event.type) {
MediaPlayer.Event.Playing -> {
medialibrary.pauseBackgroundOperations()
videoBackground = false
val mw = withContext(VLCIO) { medialibrary.findMedia(getCurrentMedia()) }
if (newMedia) {
loadMediaMeta(mw)
if (mw.type == MediaWrapper.TYPE_STREAM) medialibrary.addToHistory(mw.location, mw.title)
saveMediaList()
savePosition(true)
saveCurrentMedia()
newMedia = false
if (player.hasRenderer || !player.isVideoPlaying()) showAudioPlayer.value = true
}
}
launch(UI, CoroutineStart.UNDISPATCHED) {
MediaPlayer.Event.Paused -> medialibrary.resumeBackgroundOperations()
MediaPlayer.Event.EndReached -> {
if (currentIndex != nextIndex) {
saveMediaMeta()
if (isBenchmark) player.setPreviousStats()
if (nextIndex == -1) savePosition(true)
}
determinePrevAndNextIndices(true)
next()
}
MediaPlayer.Event.EncounteredError -> {
service.showToast(service.getString(
R.string.invalid_location,
getCurrentMedia()?.getLocation() ?: ""), Toast.LENGTH_SHORT)
if (currentIndex != nextIndex) next() else stop(true)
}
}
MediaPlayer.Event.EncounteredError -> {
service.showToast(service.getString(
R.string.invalid_location,
getCurrentMedia()?.getLocation() ?: ""), Toast.LENGTH_SHORT)
if (currentIndex != nextIndex) next() else stop(true)
}
service.onMediaPlayerEvent(event)
}
service.onMediaPlayerEvent(event)
}
private fun isAudioList() = !player.canSwitchToVideo() && mediaList.isAudioList
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment