diff --git a/app/src/main/java/dev/brahmkshatriya/echo/playback/loading/StreamableLoader.kt b/app/src/main/java/dev/brahmkshatriya/echo/playback/loading/StreamableLoader.kt index 6f6f4162..9fd839ad 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/playback/loading/StreamableLoader.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/playback/loading/StreamableLoader.kt @@ -16,6 +16,7 @@ import dev.brahmkshatriya.echo.playback.MediaItemUtils.isLoaded import dev.brahmkshatriya.echo.playback.MediaItemUtils.sourcesIndex import dev.brahmkshatriya.echo.playback.MediaItemUtils.subtitleIndex import dev.brahmkshatriya.echo.playback.MediaItemUtils.track +import dev.brahmkshatriya.echo.ui.exception.AppException.Companion.toAppException import dev.brahmkshatriya.echo.viewmodels.ExtensionViewModel.Companion.noClient import dev.brahmkshatriya.echo.viewmodels.ExtensionViewModel.Companion.trackNotSupported import kotlinx.coroutines.Dispatchers @@ -53,7 +54,9 @@ class StreamableLoader( val client = extension.instance.value.getOrNull() if (client !is TrackClient) throw Exception(context.trackNotSupported(extension.metadata.name).message) - return block(client) + return runCatching { block(client) }.getOrElse { + throw it.toAppException(extension) + } } private suspend fun loadTrack(item: MediaItem) = withClient(item) { diff --git a/app/src/main/java/dev/brahmkshatriya/echo/playback/loading/StreamableMediaSource.kt b/app/src/main/java/dev/brahmkshatriya/echo/playback/loading/StreamableMediaSource.kt index 07045d9d..d56d5cca 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/playback/loading/StreamableMediaSource.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/playback/loading/StreamableMediaSource.kt @@ -37,6 +37,7 @@ import dev.brahmkshatriya.echo.utils.saveToCache import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch +import java.io.IOException @UnstableApi class StreamableMediaSource( @@ -63,7 +64,7 @@ class StreamableMediaSource( private var error: Throwable? = null override fun maybeThrowSourceInfoRefreshError() { - error?.let { throw it } + error?.let { throw IOException(it) } super.maybeThrowSourceInfoRefreshError() } @@ -88,7 +89,11 @@ class StreamableMediaSource( val sources = streamable.sources actualSource = when (sources.size) { - 0 -> throw Exception(context.getString(R.string.streamable_not_found)) + 0 -> { + error = Exception(context.getString(R.string.streamable_not_found)) + return@launch + } + 1 -> create(new, 0, sources.first()) else -> { if (streamable.merged) MergingMediaSource( diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/item/ItemFragment.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/item/ItemFragment.kt index 00cfc50b..f5e9645e 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/ui/item/ItemFragment.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/item/ItemFragment.kt @@ -167,7 +167,7 @@ class ItemFragment : Fragment() { }) fun concatAdapter(item: EchoMediaItem, itemsAdapter: ConcatAdapter): ConcatAdapter { - trackAdapter = TrackAdapter(clientId, view.transitionName, listener, item) + trackAdapter = TrackAdapter(clientId, view.transitionName, listener, item, true) return when (item) { is AlbumItem -> ConcatAdapter(albumHeaderAdapter, trackAdapter, itemsAdapter) diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerUiListener.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerUiListener.kt index 696a857d..2aeb0aeb 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerUiListener.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerUiListener.kt @@ -7,9 +7,11 @@ import androidx.media3.common.PlaybackException import androidx.media3.common.Player import androidx.media3.common.Timeline import androidx.media3.exoplayer.ExoPlayer +import dev.brahmkshatriya.echo.ui.exception.AppException import dev.brahmkshatriya.echo.ui.exception.ExceptionFragment.Companion.toExceptionDetails import dev.brahmkshatriya.echo.viewmodels.PlayerViewModel import kotlinx.coroutines.launch +import java.io.IOException class PlayerUiListener( val player: Player, @@ -36,7 +38,7 @@ class PlayerUiListener( private fun updateNavigation() { viewModel.nextEnabled.value = player.hasNextMediaItem() - viewModel.previousEnabled.value = player.currentMediaItemIndex >= 0 + viewModel.previousEnabled.value = player.currentMediaItemIndex >= 0 } private val delay = 500L @@ -45,6 +47,7 @@ class PlayerUiListener( private val handler = Handler(Looper.getMainLooper()).also { it.post(updateProgressRunnable) } + private fun updateProgress() { viewModel.progress.value = player.currentPosition.toInt() to player.bufferedPosition.toInt() @@ -108,6 +111,12 @@ class PlayerUiListener( } override fun onPlayerError(error: PlaybackException) { - viewModel.createException(error.toExceptionDetails(viewModel.app)) + var cause = error.cause ?: error + if (cause is IOException) { + cause = cause.cause ?: cause + } + if (cause is AppException) { + viewModel.apply { viewModelScope.launch { throwableFlow.emit(cause) } } + } else viewModel.createException(cause.toExceptionDetails(viewModel.app)) } } \ No newline at end of file