mirror of
https://gitlab.com/vyla-entertainment/TV.git
synced 2026-11-14 12:07:21 -05:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
97c45f14c2
|
|||
|
3d59612d6e
|
|||
|
bd7d443f21
|
|||
|
|
8cd9ec3671 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -9,3 +9,5 @@ android/.gradle/
|
|||||||
.build
|
.build
|
||||||
www/
|
www/
|
||||||
android/app/src/main/assets/
|
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 kotlinx.coroutines.withTimeoutOrNull
|
||||||
import tv.vyla.app.ui.components.VideoTintSampler
|
import tv.vyla.app.ui.components.VideoTintSampler
|
||||||
import tv.vyla.app.ui.components.videoTint
|
import tv.vyla.app.ui.components.videoTint
|
||||||
|
import android.util.Log
|
||||||
|
|
||||||
enum class ActivePlayerMenu {
|
enum class ActivePlayerMenu {
|
||||||
NONE, QUALITY, SUBTITLES, VOLUME, SETTINGS, MORE
|
NONE, QUALITY, SUBTITLES, VOLUME, SETTINGS, MORE
|
||||||
@@ -224,6 +225,33 @@ fun PlayerScreen(
|
|||||||
exoPlayer.play()
|
exoPlayer.play()
|
||||||
resetHideTimer()
|
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() {
|
suspend fun focusEpisodeCard() {
|
||||||
var tries = 0
|
var tries = 0
|
||||||
while (tries < 15) {
|
while (tries < 15) {
|
||||||
@@ -300,7 +328,9 @@ fun PlayerScreen(
|
|||||||
onFirstPlayable = { stream ->
|
onFirstPlayable = { stream ->
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
activeStream = stream
|
activeStream = stream
|
||||||
resolvedStreams.add(stream)
|
if (!resolvedStreams.any { it.provider == stream.provider }) {
|
||||||
|
resolvedStreams.add(stream)
|
||||||
|
}
|
||||||
playStream(stream.primaryUrl, stream.headers)
|
playStream(stream.primaryUrl, stream.headers)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -520,7 +550,7 @@ fun PlayerScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val seg = activeSegment
|
val seg = activeSegment
|
||||||
val showNextPrompt = isNextEpAvailable && durationMs > 0 && (durationMs - currentPositionMs) in 1..300000
|
val showNextPrompt = isNextEpAvailable && durationMs > 0 && (durationMs - currentPositionMs) in 1..30000
|
||||||
if ((seg != null || showNextPrompt) && activeMenu == ActivePlayerMenu.NONE && !isEpisodesDrawerOpen) {
|
if ((seg != null || showNextPrompt) && activeMenu == ActivePlayerMenu.NONE && !isEpisodesDrawerOpen) {
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.End,
|
horizontalAlignment = Alignment.End,
|
||||||
@@ -938,7 +968,7 @@ fun PlayerScreen(
|
|||||||
items(resolvedStreams) { stream ->
|
items(resolvedStreams) { stream ->
|
||||||
MenuItemRow(
|
MenuItemRow(
|
||||||
label = stream.label,
|
label = stream.label,
|
||||||
isSelected = activeStream?.provider == stream.provider,
|
isSelected = ((activeStream?.provider == stream.provider) && (activeStream?.primaryUrl == stream.primaryUrl)),
|
||||||
onClick = {
|
onClick = {
|
||||||
activeStream = stream
|
activeStream = stream
|
||||||
playStream(stream.primaryUrl, stream.headers)
|
playStream(stream.primaryUrl, stream.headers)
|
||||||
|
|||||||
0
android/gradlew
vendored
Normal file → Executable file
0
android/gradlew
vendored
Normal file → Executable file
2
package-lock.json
generated
2
package-lock.json
generated
@@ -9,7 +9,7 @@
|
|||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vyla-entertainment/sdk": "^1.18.0",
|
"@vyla-entertainment/sdk": "^1.20.0",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"hls.js": "^1.7.3"
|
"hls.js": "^1.7.3"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"android": "node scripts/build-android.mjs"
|
"android": "node scripts/build-android.mjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vyla-entertainment/sdk": "^1.18.0",
|
"@vyla-entertainment/sdk": "^1.20.0",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"hls.js": "^1.7.3"
|
"hls.js": "^1.7.3"
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Vyla TV",
|
|
||||||
"version": "1.0.6",
|
|
||||||
"package": "Vyla-TV_1.0.6.apk",
|
|
||||||
"releaseDate": "2026-10-06T03:41:56.445Z"
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user