Skip to content

Commit

Permalink
be able to propagate available tracks to the UI
Browse files Browse the repository at this point in the history
  • Loading branch information
theScrabi committed Oct 15, 2024
1 parent 32a6c78 commit 5f6d69a
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 24 deletions.
4 changes: 2 additions & 2 deletions new-player/src/main/java/net/newpipe/newplayer/NewPlayer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ package net.newpipe.newplayer

import android.app.Activity
import androidx.core.graphics.drawable.IconCompat
import androidx.media3.common.Format
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -31,6 +30,7 @@ import kotlinx.coroutines.flow.StateFlow
import net.newpipe.newplayer.utils.Chapter
import net.newpipe.newplayer.utils.LanguageIdentifier
import net.newpipe.newplayer.utils.Stream
import net.newpipe.newplayer.utils.StreamTrack
import kotlin.Exception

enum class PlayMode {
Expand Down Expand Up @@ -74,7 +74,7 @@ interface NewPlayer {
val currentChapters: StateFlow<List<Chapter>>

val currentlyPlayingStream: StateFlow<Stream?>
val currentlyAvailableStreams: StateFlow<List<Stream>>
val currentlyAvailableTracks: StateFlow<List<StreamTrack>>

// callbacks

Expand Down
23 changes: 12 additions & 11 deletions new-player/src/main/java/net/newpipe/newplayer/NewPlayerImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ import net.newpipe.newplayer.utils.Stream
import net.newpipe.newplayer.utils.StreamExceptionResponse
import net.newpipe.newplayer.utils.StreamSelection
import net.newpipe.newplayer.utils.StreamSelectionResponse
import net.newpipe.newplayer.utils.StreamSelector
import net.newpipe.newplayer.utils.StreamTrack
import net.newpipe.newplayer.utils.TrackSelector
import kotlin.random.Random

private const val TAG = "NewPlayerImpl"
Expand Down Expand Up @@ -165,8 +166,8 @@ class NewPlayerImpl(
exoPlayer.value?.seekTo(value, 0)
}

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

private var mutableCurrentlyPlayingStream = MutableStateFlow<Stream?>(null)
override val currentlyPlayingStream = mutableCurrentlyPlayingStream.asStateFlow()
Expand Down Expand Up @@ -205,12 +206,12 @@ class NewPlayerImpl(
val streamSelection =
uniqueIdToStreamSelectionLookup[mediaItem.mediaId.toLong()]!!
launchJobAndCollectError {
mutableCurrentlyAvailableStreams.update {
repository.getStreams(streamSelection.item)
mutableCurrentlyAvailableTracks.update {
TrackSelector.getNonDynamicTracksNonDuplicated(repository.getStreams(streamSelection.item))
}
}
} else {
mutableCurrentlyAvailableStreams.update { emptyList() }
mutableCurrentlyAvailableTracks.update { emptyList() }
mutableCurrentlyPlayingStream.update { null }
}
}
Expand Down Expand Up @@ -342,8 +343,8 @@ class NewPlayerImpl(
@OptIn(UnstableApi::class)
override fun playStream(item: String, playMode: PlayMode) {
launchJobAndCollectError {
mutableCurrentlyAvailableStreams.update {
repository.getStreams(item)
mutableCurrentlyAvailableTracks.update {
TrackSelector.getNonDynamicTracksNonDuplicated(repository.getStreams(item))
}

val mediaSource = toMediaSource(item)
Expand Down Expand Up @@ -391,7 +392,7 @@ class NewPlayerImpl(
null
}
mediaController = null
mutableCurrentlyAvailableStreams.update { emptyList() }
mutableCurrentlyAvailableTracks.update { emptyList() }
mutableCurrentlyPlayingStream.update { null }
uniqueIdToStreamSelectionLookup = HashMap()
}
Expand All @@ -415,11 +416,11 @@ class NewPlayerImpl(
@OptIn(UnstableApi::class)
private suspend
fun toMediaSource(item: String): MediaSource {
val streamSelector = StreamSelector(
val trackSelector = TrackSelector(
preferredLanguages = preferredStreamLanguages
)

val selection = streamSelector.selectStream(
val selection = trackSelector.selectStreamAutomatically(
item,
availableStreams = repository.getStreams(item),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import androidx.media3.common.util.UnstableApi
import net.newpipe.newplayer.utils.Chapter
import net.newpipe.newplayer.RepeatMode
import net.newpipe.newplayer.ui.ContentScale
import net.newpipe.newplayer.utils.StreamTrack


@UnstableApi
Expand Down Expand Up @@ -58,7 +59,8 @@ data class NewPlayerUIState(
val availableSubtitles: List<String>,
val enteringPip: Boolean,
val currentSeekPreviewThumbnail: ImageBitmap?,
val seekPreviewVisible: Boolean
val seekPreviewVisible: Boolean,
val currentlyAvailableTracks: List<StreamTrack>
) {
companion object {
val DEFAULT = NewPlayerUIState(
Expand Down Expand Up @@ -89,7 +91,8 @@ data class NewPlayerUIState(
availableStreamVariants = emptyList(),
enteringPip = false,
currentSeekPreviewThumbnail = null,
seekPreviewVisible = false
seekPreviewVisible = false,
currentlyAvailableTracks = emptyList()
)

val DUMMY = DEFAULT.copy(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ class NewPlayerViewModelImpl @Inject constructor(
}

viewModelScope.launch {
newPlayer.currentlyAvailableStreams.collect { availableStreams ->
newPlayer.currentlyAvailableTracks.collect { availableStreams ->
if (availableStreams != null) {
/*TODO*/
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@

package net.newpipe.newplayer.utils

internal class StreamSelector(
internal class TrackSelector(
val preferredLanguages: List<LanguageIdentifier>,
) {
internal fun selectStream(
internal fun selectStreamAutomatically(
item: String,
availableStreams: List<Stream>,
): StreamSelection {
Expand All @@ -45,7 +45,7 @@ internal class StreamSelector(

// first: try and get a dynamic stream variant
val dynamicStreams = getDynamicStreams(availablesInPreferredLanguage)
if(dynamicStreams.isNotEmpty()) {
if (dynamicStreams.isNotEmpty()) {
return SingleSelection(dynamicStreams[0])
}

Expand Down Expand Up @@ -83,6 +83,18 @@ internal class StreamSelector(

companion object {

internal fun getAllAvailableTracksNonDuplicated(streams: List<Stream>): List<StreamTrack> {
val totalList = mutableListOf<StreamTrack>()
streams.forEach {
totalList.addAll(it.streamTracks)
}
totalList.sort()
return totalList.distinct()
}

internal fun getNonDynamicTracksNonDuplicated(streams: List<Stream>) =
getAllAvailableTracksNonDuplicated(streams.filter { !it.isDashOrHls })

private fun getBestLanguageFit(
availableStreams: List<Stream>, preferredLanguages: List<LanguageIdentifier>
): LanguageIdentifier? {
Expand Down Expand Up @@ -137,16 +149,17 @@ internal class StreamSelector(
private fun getDynamicStreams(availableStreams: List<Stream>) =
availableStreams.filter { it.isDashOrHls }

private fun getNonDynamicVideoStreams(availableStreams: List<Stream>) = availableStreams.filter {
!it.isDashOrHls && it.hasVideoTracks && !it.hasAudioTracks
}
private fun getNonDynamicVideoStreams(availableStreams: List<Stream>) =
availableStreams.filter {
!it.isDashOrHls && it.hasVideoTracks && !it.hasAudioTracks
}

private fun getNonDynamicAudioStreams(availableStreams: List<Stream>) =
availableStreams.filter { !it.isDashOrHls && !it.hasVideoTracks && it.hasAudioTracks }

private fun hasVideoStreams(availableStreams: List<Stream>) : Boolean {
private fun hasVideoStreams(availableStreams: List<Stream>): Boolean {
availableStreams.forEach {
if(it.hasVideoTracks)
if (it.hasVideoTracks)
return true
}
return false
Expand Down

0 comments on commit 5f6d69a

Please sign in to comment.