Skip to content

Commit

Permalink
add replace current item response
Browse files Browse the repository at this point in the history
  • Loading branch information
theScrabi committed Oct 16, 2024
1 parent dea4d9a commit b8e6a66
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 33 deletions.
92 changes: 62 additions & 30 deletions new-player/src/main/java/net/newpipe/newplayer/NewPlayerImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ import net.newpipe.newplayer.data.Chapter
import net.newpipe.newplayer.logic.MediaSourceBuilder
import net.newpipe.newplayer.data.NewPlayerException
import net.newpipe.newplayer.logic.NoResponse
import net.newpipe.newplayer.data.Stream
import net.newpipe.newplayer.logic.StreamExceptionResponse
import net.newpipe.newplayer.data.StreamSelection
import net.newpipe.newplayer.logic.StreamSelectionResponse
import net.newpipe.newplayer.logic.ReplaceStreamSelectionResponse
import net.newpipe.newplayer.data.StreamTrack
import net.newpipe.newplayer.logic.ReloadItemResponse
import net.newpipe.newplayer.logic.ReplaceItemResponse
import net.newpipe.newplayer.logic.StreamSelector
import net.newpipe.newplayer.logic.TrackUtils
import kotlin.random.Random
Expand Down Expand Up @@ -170,10 +171,12 @@ class NewPlayerImpl(
}

private var mutableCurrentlyAvailableTracks = MutableStateFlow<List<StreamTrack>>(emptyList())
override val currentlyAvailableTracks: StateFlow<List<StreamTrack>> = mutableCurrentlyAvailableTracks.asStateFlow()
override val currentlyAvailableTracks: StateFlow<List<StreamTrack>> =
mutableCurrentlyAvailableTracks.asStateFlow()

private var mutableCurrentlyPlayingTracks = MutableStateFlow<List<StreamTrack>>(emptyList())
override val currentlyPlayingTracks: StateFlow<List<StreamTrack>> = mutableCurrentlyPlayingTracks.asStateFlow()
override val currentlyPlayingTracks: StateFlow<List<StreamTrack>> =
mutableCurrentlyPlayingTracks.asStateFlow()

private fun setupNewExoplayer() {
val newExoPlayer = ExoPlayer.Builder(app)
Expand Down Expand Up @@ -210,7 +213,11 @@ class NewPlayerImpl(
uniqueIdToStreamSelectionLookup[mediaItem.mediaId.toLong()]!!
launchJobAndCollectError {
mutableCurrentlyAvailableTracks.update {
TrackUtils.getNonDynamicTracksNonDuplicated(repository.getStreams(streamSelection.item))
TrackUtils.getNonDynamicTracksNonDuplicated(
repository.getStreams(
streamSelection.item
)
)
}
}
} else {
Expand All @@ -221,8 +228,15 @@ class NewPlayerImpl(
@OptIn(UnstableApi::class)
override fun onTracksChanged(tracks: Tracks) {
super.onTracksChanged(tracks)
mutableCurrentlyPlayingTracks.update {
val streamTracks =
TrackUtils.streamTracksFromMedia3Tracks(tracks, onlySelectedTracks = true)
streamTracks.joinToString("\n") { it.toString() }
Log.d(
TAG,
"currently playing tracks: \n ${streamTracks.joinToString("\n") { it.toString() }}"
)
mutableCurrentlyPlayingTracks.update {
streamTracks
}
}
})
Expand All @@ -249,8 +263,12 @@ class NewPlayerImpl(
response.action()
}

is StreamSelectionResponse -> {
replaceCurrentStream(response.streamSelection)
is ReplaceStreamSelectionResponse -> {
replaceCurrentStreamSelection(response.streamSelection)
}

is ReplaceItemResponse -> {
replaceCurrentItem(response.newItem)
}

is NoResponse -> {
Expand Down Expand Up @@ -397,6 +415,42 @@ class NewPlayerImpl(
this.exoPlayer.value?.play()
}

/**
* Replaces the current stream and continues playing at the position the previous stream stopped.
* This can be used to replace a faulty stream or change to a stream with a different language/quality.
*/
@OptIn(UnstableApi::class)
private suspend fun replaceCurrentStreamSelection(streamSelection: StreamSelection) {
val item =
uniqueIdToStreamSelectionLookup[this.currentlyPlaying.value?.mediaId?.toLong()]!!.item
val mediaSource = toMediaSource(streamSelection, item)
replaceCurrentMediaSource(mediaSource)
}

@OptIn(UnstableApi::class)
private fun replaceCurrentMediaSource(mediaSource: MediaSource) {
val currentPosition = this.currentPosition
val currentlyPlayingPlaylistItem = this.currentlyPlayingPlaylistItem

this.exoPlayer.value?.removeMediaItem(currentlyPlayingPlaylistItem)
this.exoPlayer.value?.addMediaSource(currentlyPlayingPlaylistItem, mediaSource)
if (this.exoPlayer.value?.playbackState == Player.STATE_IDLE) {
prepare()
}
this.currentlyPlayingPlaylistItem = currentlyPlayingPlaylistItem
this.exoPlayer.value?.seekTo(currentPosition)
this.exoPlayer.value?.play()
}

private suspend fun replaceCurrentItem(item: String) {
mutableCurrentlyAvailableTracks.update {
TrackUtils.getNonDynamicTracksNonDuplicated(repository.getStreams(item))
}

val mediaSource = toMediaSource(item)
replaceCurrentMediaSource(mediaSource)
}

@OptIn(UnstableApi::class)
private suspend
fun toMediaSource(item: String): MediaSource {
Expand Down Expand Up @@ -426,28 +480,6 @@ class NewPlayerImpl(
return mediaSource
}

/**
* Replaces the current stream and continues playing at the position the previous stream stopped.
* This can be used to replace a faulty stream or change to a stream with a different language/quality.
*/
@OptIn(UnstableApi::class)
private suspend fun replaceCurrentStream(streamSelection: StreamSelection) {
val currentPosition = this.currentPosition
val currentlyPlayingPlaylistItem = this.currentlyPlayingPlaylistItem
val item =
uniqueIdToStreamSelectionLookup[this.currentlyPlaying.value?.mediaId?.toLong()]!!.item

val mediaSource = toMediaSource(streamSelection, item)
this.exoPlayer.value?.removeMediaItem(currentlyPlayingPlaylistItem)
this.exoPlayer.value?.addMediaSource(currentlyPlayingPlaylistItem, mediaSource)
if (this.exoPlayer.value?.playbackState == Player.STATE_IDLE) {
prepare()
}
this.currentlyPlayingPlaylistItem = currentlyPlayingPlaylistItem
this.exoPlayer.value?.seekTo(currentPosition)
this.exoPlayer.value?.play()
}

private fun launchJobAndCollectError(task: suspend () -> Unit) =
playerScope.launch {
try {
Expand Down
17 changes: 17 additions & 0 deletions new-player/src/main/java/net/newpipe/newplayer/data/StreamTrack.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ data class VideoStreamTrack(
1
}

override fun toString() = """
VideoStreamTrack {
width = $width
height = $height
frameRate = $frameRate
fileFormat = $fileFormat
}
""".trimIndent()

}

data class AudioStreamTrack(
Expand Down Expand Up @@ -92,4 +101,12 @@ data class AudioStreamTrack(
result = 31 * result + fileFormat.hashCode()
return result
}

override fun toString() = """
AudioStreamTrack {
bitrate = $bitrate
language = $language
fileFormat = $fileFormat
}
""".trimIndent()
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ interface StreamExceptionResponse

data class ActionResponse(val action: () -> Unit) : StreamExceptionResponse

data class StreamSelectionResponse(val streamSelection: StreamSelection) :
data class ReplaceStreamSelectionResponse(val streamSelection: StreamSelection) :
StreamExceptionResponse

data class ReplaceItemResponse(val newItem: String) : StreamExceptionResponse

class NoResponse : StreamExceptionResponse
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import net.newpipe.newplayer.MediaRepository
import net.newpipe.newplayer.logic.NoResponse
import net.newpipe.newplayer.data.SingleSelection
import net.newpipe.newplayer.logic.StreamExceptionResponse
import net.newpipe.newplayer.logic.StreamSelectionResponse
import net.newpipe.newplayer.logic.ReplaceStreamSelectionResponse
import java.lang.Exception

suspend fun streamErrorHandler(
Expand All @@ -15,7 +15,7 @@ suspend fun streamErrorHandler(
repository: MediaRepository
): StreamExceptionResponse {
return if (item == "faulty") {
StreamSelectionResponse(SingleSelection(repository.getStreams("6502")[0]))
ReplaceStreamSelectionResponse(SingleSelection(repository.getStreams("6502")[0]))
} else {
NoResponse()
}
Expand Down

0 comments on commit b8e6a66

Please sign in to comment.