mirror of
https://gitlab.com/vyla-entertainment/TV.git
synced 2026-11-09 17:47:20 -05:00
Implemented automatic fallback for sources.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,3 +10,4 @@ android/.gradle/
|
||||
www/
|
||||
android/app/src/main/assets/
|
||||
release/
|
||||
android/app/src/main/res/raw/*.crt
|
||||
@@ -79,6 +79,7 @@ import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import tv.vyla.app.ui.components.VideoTintSampler
|
||||
import tv.vyla.app.ui.components.videoTint
|
||||
import android.util.Log
|
||||
|
||||
enum class ActivePlayerMenu {
|
||||
NONE, QUALITY, SUBTITLES, VOLUME, SETTINGS, MORE
|
||||
@@ -224,6 +225,33 @@ fun PlayerScreen(
|
||||
exoPlayer.play()
|
||||
resetHideTimer()
|
||||
}
|
||||
DisposableEffect(exoPlayer) {
|
||||
val errorListener = object : Player.Listener { // source auto-fallback
|
||||
override fun onPlayerError(error: androidx.media3.common.PlaybackException) {
|
||||
val currentIdx = resolvedStreams.indexOf(activeStream)
|
||||
if (currentIdx != -1 && currentIdx + 1 < resolvedStreams.size) {
|
||||
// android.widget.Toast.makeText(context, "Source failed. Trying next...", android.widget.Toast.LENGTH_SHORT).show()
|
||||
Log.e("vyla", "Source failed. Trying next...")
|
||||
|
||||
coroutineScope.launch {
|
||||
delay(1500) // follow rate limits
|
||||
val nextStream = resolvedStreams[currentIdx + 1]
|
||||
activeStream = nextStream
|
||||
playStream(nextStream.primaryUrl, nextStream.headers)
|
||||
}
|
||||
} else {
|
||||
isBuffering = false
|
||||
Log.e("vyla", "All Sources Failed")
|
||||
android.widget.Toast.makeText(context, "All available sources failed. Please disable any VPN or try again later", android.widget.Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
exoPlayer.addListener(errorListener)
|
||||
|
||||
onDispose {
|
||||
exoPlayer.removeListener(errorListener)
|
||||
}
|
||||
}
|
||||
suspend fun focusEpisodeCard() {
|
||||
var tries = 0
|
||||
while (tries < 15) {
|
||||
@@ -300,7 +328,9 @@ fun PlayerScreen(
|
||||
onFirstPlayable = { stream ->
|
||||
coroutineScope.launch {
|
||||
activeStream = stream
|
||||
resolvedStreams.add(stream)
|
||||
if (!resolvedStreams.any { it.provider == stream.provider }) {
|
||||
resolvedStreams.add(stream)
|
||||
}
|
||||
playStream(stream.primaryUrl, stream.headers)
|
||||
}
|
||||
},
|
||||
@@ -938,7 +968,7 @@ fun PlayerScreen(
|
||||
items(resolvedStreams) { stream ->
|
||||
MenuItemRow(
|
||||
label = stream.label,
|
||||
isSelected = activeStream?.provider == stream.provider,
|
||||
isSelected = ((activeStream?.provider == stream.provider) && (activeStream?.primaryUrl == stream.primaryUrl)),
|
||||
onClick = {
|
||||
activeStream = stream
|
||||
playStream(stream.primaryUrl, stream.headers)
|
||||
|
||||
0
android/gradlew
vendored
Normal file → Executable file
0
android/gradlew
vendored
Normal file → Executable file
Reference in New Issue
Block a user