replace first callbacks with mutablestate/shareflow
This commit is contained in:
parent
32075dec73
commit
ea099253a1
|
@ -30,7 +30,14 @@ import androidx.media3.exoplayer.source.MediaSource
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import net.newpipe.newplayer.model.UIModeState
|
||||
import net.newpipe.newplayer.utils.PlayList
|
||||
import kotlin.Exception
|
||||
|
||||
|
@ -56,16 +63,13 @@ interface NewPlayer {
|
|||
var currentPosition: Long
|
||||
var fastSeekAmountSec: Int
|
||||
var playBackMode: PlayMode
|
||||
var playMode: PlayMode?
|
||||
var playMode : MutableStateFlow<PlayMode?>
|
||||
|
||||
var playlist: PlayList
|
||||
|
||||
// calbacks
|
||||
// callbacks
|
||||
|
||||
interface Listener {
|
||||
fun playModeChange(playMode: PlayMode) {}
|
||||
fun onError(exception: Exception) {}
|
||||
}
|
||||
val errorFlow : SharedFlow<Exception>
|
||||
|
||||
// methods
|
||||
fun prepare()
|
||||
|
@ -74,7 +78,6 @@ interface NewPlayer {
|
|||
fun addToPlaylist(item: String)
|
||||
fun playStream(item: String, playMode: PlayMode)
|
||||
fun playStream(item: String, streamVariant: String, playMode: PlayMode)
|
||||
fun addCallbackListener(listener: Listener?)
|
||||
|
||||
data class Builder(val app: Application, val repository: MediaRepository) {
|
||||
private var mediaSourceFactory: MediaSource.Factory? = null
|
||||
|
@ -111,6 +114,9 @@ class NewPlayerImpl(
|
|||
override val repository: MediaRepository,
|
||||
) : NewPlayer {
|
||||
|
||||
var mutableErrorFlow = MutableSharedFlow<Exception>()
|
||||
override val errorFlow = mutableErrorFlow.asSharedFlow()
|
||||
|
||||
override val bufferedPercentage: Int
|
||||
get() = internalPlayer.bufferedPercentage
|
||||
override var currentPosition: Long
|
||||
|
@ -122,16 +128,9 @@ class NewPlayerImpl(
|
|||
override var fastSeekAmountSec: Int = 10
|
||||
override var playBackMode: PlayMode = PlayMode.EMBEDDED_VIDEO
|
||||
|
||||
private var callbackListener: ArrayList<NewPlayer.Listener?> = ArrayList()
|
||||
private var playerScope = CoroutineScope(Dispatchers.Default + Job())
|
||||
|
||||
override var playMode: PlayMode? = null
|
||||
set(value) {
|
||||
field = value
|
||||
if (field != null) {
|
||||
callbackListener.forEach { it?.playModeChange(field!!) }
|
||||
}
|
||||
}
|
||||
override var playMode = MutableStateFlow<PlayMode?>(null)
|
||||
|
||||
override var playWhenReady: Boolean
|
||||
set(value) {
|
||||
|
@ -154,9 +153,7 @@ class NewPlayerImpl(
|
|||
if (newUri != null) {
|
||||
TODO("Implement handing new uri on fixed error")
|
||||
} else {
|
||||
callbackListener.forEach {
|
||||
it?.onError(error)
|
||||
}
|
||||
mutableErrorFlow.emit(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -204,7 +201,7 @@ class NewPlayerImpl(
|
|||
if (internalPlayer.playbackState == Player.STATE_IDLE) {
|
||||
internalPlayer.prepare()
|
||||
}
|
||||
this.playMode = playMode
|
||||
this.playMode.update { playMode }
|
||||
}
|
||||
|
||||
private suspend fun toMediaItem(item: String, streamVariant: String): MediaItem {
|
||||
|
@ -232,13 +229,7 @@ class NewPlayerImpl(
|
|||
try {
|
||||
task()
|
||||
} catch (e: Exception) {
|
||||
callbackListener.forEach {
|
||||
it?.onError(e)
|
||||
mutableErrorFlow.emit(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun addCallbackListener(listener: NewPlayer.Listener?) {
|
||||
callbackListener.add(listener)
|
||||
}
|
||||
}
|
|
@ -21,7 +21,9 @@
|
|||
|
||||
package net.newpipe.newplayer.utils
|
||||
|
||||
import androidx.media3.common.MediaMetadata
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.Player.Listener
|
||||
|
||||
|
||||
// TODO: This is cool, but it might still contains all raceconditions since two actors are mutating the
|
||||
|
@ -32,6 +34,8 @@ import androidx.media3.common.Player
|
|||
// due to this reason some functions force the user to handle elements out of bounds exceptions.
|
||||
|
||||
|
||||
|
||||
|
||||
class PlayListIterator(
|
||||
val exoPlayer: Player,
|
||||
val fromIndex: Int,
|
||||
|
@ -83,6 +87,7 @@ class PlayList(val exoPlayer: Player, val fromIndex: Int = 0, val toIndex: Int =
|
|||
override val size: Int
|
||||
get() = minOf(exoPlayer.mediaItemCount, toIndex) - fromIndex
|
||||
|
||||
// TODO: This contains a race condition. When the player might change the playlist while this function runns
|
||||
override fun contains(element: String): Boolean {
|
||||
for (i in fromIndex..minOf(exoPlayer.mediaItemCount, toIndex)) {
|
||||
try {
|
||||
|
@ -95,6 +100,7 @@ class PlayList(val exoPlayer: Player, val fromIndex: Int = 0, val toIndex: Int =
|
|||
return false
|
||||
}
|
||||
|
||||
// TODO: This contains a race condition. When the player might change the playlist while this function runns
|
||||
override fun containsAll(elements: Collection<String>): Boolean {
|
||||
for (element in elements) {
|
||||
if (!this.contains(element)) {
|
||||
|
@ -106,10 +112,10 @@ class PlayList(val exoPlayer: Player, val fromIndex: Int = 0, val toIndex: Int =
|
|||
|
||||
@Throws(IndexOutOfBoundsException::class)
|
||||
override fun get(index: Int) =
|
||||
if (index < fromIndex || toIndex < index)
|
||||
throw IndexOutOfBoundsException("Accessed playlist item outside of permitted Playlist ListWindow: $index")
|
||||
if (index < 0 || toIndex < index + fromIndex)
|
||||
throw IndexOutOfBoundsException("Accessed playlist item outside of permitted Playlist ListWindow: $index with [$fromIndex;$toIndex[")
|
||||
else
|
||||
exoPlayer.getMediaItemAt(index).mediaId
|
||||
exoPlayer.getMediaItemAt(index + fromIndex).mediaId
|
||||
|
||||
override fun isEmpty() = exoPlayer.mediaItemCount == 0 || fromIndex == toIndex
|
||||
|
||||
|
@ -127,20 +133,27 @@ class PlayList(val exoPlayer: Player, val fromIndex: Int = 0, val toIndex: Int =
|
|||
)
|
||||
|
||||
override fun lastIndexOf(element: String): Int {
|
||||
var mediaItemCount = 0
|
||||
var newMediaItemCount = minOf(toIndex, exoPlayer.mediaItemCount)
|
||||
|
||||
// this while loop is there to catch raceconditions
|
||||
while(mediaItemCount != newMediaItemCount) {
|
||||
mediaItemCount = newMediaItemCount
|
||||
for (i in minOf(toIndex, exoPlayer.mediaItemCount) downTo fromIndex) {
|
||||
try {
|
||||
if (exoPlayer.getMediaItemAt(i).mediaId == element) {
|
||||
return i - fromIndex
|
||||
}
|
||||
} catch (e: IndexOutOfBoundsException) {
|
||||
return -1
|
||||
} catch (_: IndexOutOfBoundsException) {}
|
||||
|
||||
}
|
||||
newMediaItemCount = minOf(toIndex, exoPlayer.mediaItemCount)
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun indexOf(element: String): Int {
|
||||
for (i in fromIndex.. minOf(toIndex, exoPlayer.mediaItemCount)) {
|
||||
for (i in fromIndex..minOf(toIndex, exoPlayer.mediaItemCount)) {
|
||||
try {
|
||||
if (exoPlayer.getMediaItemAt(i).mediaId == element) {
|
||||
return i - fromIndex
|
||||
|
|
|
@ -34,6 +34,7 @@ import androidx.media3.common.MediaItem
|
|||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import net.newpipe.newplayer.ActivityBrainSlug
|
||||
import net.newpipe.newplayer.NewPlayer
|
||||
import net.newpipe.newplayer.PlayMode
|
||||
import net.newpipe.newplayer.VideoPlayerView
|
||||
import net.newpipe.newplayer.model.VideoPlayerViewModel
|
||||
import net.newpipe.newplayer.model.VideoPlayerViewModelImpl
|
||||
|
@ -63,7 +64,7 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
startStreamButton.setOnClickListener {
|
||||
newPlayer.playWhenReady = true
|
||||
newPlayer.setStream(MediaItem.fromUri(getString(R.string.ccc_6502_video)))
|
||||
newPlayer.playStream(getString(R.string.ccc_6502_video), PlayMode.EMBEDDED_VIDEO)
|
||||
}
|
||||
|
||||
videoPlayerViewModel.newPlayer = newPlayer
|
||||
|
|
Loading…
Reference in New Issue