Skip to content

Commit 8908ea6

Browse files
fix: unexpected play error not handled correctly
1 parent 2efb430 commit 8908ea6

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

android/src/main/kotlin/project/pipepipe/app/mediasource/CustomMediaSourceFactory.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,12 @@ class LazyUrlMediaSource(
235235

236236
override fun maybeThrowSourceInfoRefreshError() {
237237
prepareError?.let { throw it }
238-
actualMediaSource?.maybeThrowSourceInfoRefreshError()
238+
// Only delegate to actual media source if it's been initialized
239+
// If it's still null, the prepare job is still running and there's no error yet
240+
val source = actualMediaSource
241+
if (source != null) {
242+
source.maybeThrowSourceInfoRefreshError()
243+
}
239244
}
240245

241246
override fun getMediaItem(): MediaItem = mediaItem
@@ -251,7 +256,8 @@ class LazyUrlMediaSource(
251256

252257
override fun releasePeriod(mediaPeriod: MediaPeriod) {
253258
actualMediaSource?.releasePeriod(mediaPeriod)
254-
coroutineScope.cancel()
259+
// Note: Don't cancel coroutineScope here - it should only be cancelled in releaseSource
260+
// because releasePeriod might be called multiple times
255261
}
256262

257263
override fun releaseSource(caller: MediaSource.MediaSourceCaller) {
@@ -260,6 +266,7 @@ class LazyUrlMediaSource(
260266
actualMediaSource = null
261267
mediaSourceCaller = null
262268
eventListeners.clear()
269+
coroutineScope.cancel()
263270
}
264271

265272
override fun enable(caller: MediaSource.MediaSourceCaller) {

android/src/main/kotlin/project/pipepipe/app/service/PlaybackService.kt

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,27 @@ class PlaybackService : MediaLibraryService() {
506506
}
507507
}
508508
}
509+
510+
private fun extractMediaIdFromError(error: PlaybackException): String? {
511+
val prefix = "Failed to prepare media: "
512+
513+
// Check cause message first
514+
error.cause?.message?.let { msg ->
515+
if (msg.contains(prefix)) {
516+
return msg.substringAfter(prefix)
517+
}
518+
}
519+
520+
// Check error message
521+
error.message?.let { msg ->
522+
if (msg.contains(prefix)) {
523+
return msg.substringAfter(prefix)
524+
}
525+
}
526+
527+
// Return null if prefix not found - don't return the whole error message
528+
return null
529+
}
509530
private fun createPlayerListener(): Player.Listener {
510531
return object : Player.Listener {
511532
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
@@ -556,8 +577,8 @@ class PlaybackService : MediaLibraryService() {
556577
}
557578

558579
// Extract failed mediaId from error message
559-
val failedMediaId = error.cause?.message?.substringAfter("Failed to prepare media: ")
560-
?: error.message?.substringAfter("Failed to prepare media: ")
580+
// Use helper function to properly parse the mediaId
581+
val failedMediaId = extractMediaIdFromError(error)
561582

562583
MainScope().launch {
563584
DatabaseOperations.insertErrorLog(
@@ -569,16 +590,22 @@ class PlaybackService : MediaLibraryService() {
569590
}
570591
ToastManager.show(MR.strings.playback_error.desc().toString(this@PlaybackService))
571592

572-
// Find and remove the failed item by mediaId
573-
if (failedMediaId != null) {
574-
for (i in 0 until player.mediaItemCount) {
575-
if (player.getMediaItemAt(i).mediaId == failedMediaId) {
576-
player.removeMediaItem(i)
577-
break
578-
}
593+
// Find and remove the failed item
594+
// If we found a specific failed mediaId, remove that item
595+
// Otherwise, remove the current item to prevent infinite retry loop
596+
val itemToRemove = if (failedMediaId != null) {
597+
// Try to find the specific failed item by mediaId
598+
(0 until player.mediaItemCount).firstOrNull { i ->
599+
player.getMediaItemAt(i).mediaId == failedMediaId
579600
}
601+
} else {
602+
// Couldn't extract mediaId from error, remove current item as fallback
603+
player.currentMediaItemIndex.takeIf { it != C.INDEX_UNSET }
604+
}
605+
606+
itemToRemove?.let { index ->
607+
player.removeMediaItem(index)
580608
}
581-
// If no mediaId found, don't remove anything to avoid removing wrong item
582609

583610
// Continue playback if there are items left
584611
if (player.mediaItemCount > 0) {

0 commit comments

Comments
 (0)