From 2dd1c1792a4387cff148e085cd90414da4b183ca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Apr 2026 08:06:07 +0000 Subject: [PATCH 1/2] fix: correct URL cache expiry, remove double unbind, guard null NPEs, fix lyrics cache Agent-Logs-Url: https://github.com/nakchwalabhi/InnerTune/sessions/66166913-4599-485a-b5af-bb4679476562 Co-authored-by: nakchwalabhi <118037101+nakchwalabhi@users.noreply.github.com> --- .../java/com/zionhuang/music/MainActivity.kt | 1 - .../zionhuang/music/lyrics/LyricsHelper.kt | 6 ++-- .../zionhuang/music/playback/MusicService.kt | 35 +++++++++++-------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/com/zionhuang/music/MainActivity.kt b/app/src/main/java/com/zionhuang/music/MainActivity.kt index dcf544ddc..d60d7398f 100644 --- a/app/src/main/java/com/zionhuang/music/MainActivity.kt +++ b/app/src/main/java/com/zionhuang/music/MainActivity.kt @@ -196,7 +196,6 @@ class MainActivity : ComponentActivity() { super.onDestroy() if (dataStore.get(StopMusicOnTaskClearKey, false) && playerConnection?.isPlaying?.value == true && isFinishing) { stopService(Intent(this, MusicService::class.java)) - unbindService(serviceConnection) playerConnection = null } } diff --git a/app/src/main/java/com/zionhuang/music/lyrics/LyricsHelper.kt b/app/src/main/java/com/zionhuang/music/lyrics/LyricsHelper.kt index cc42e45d3..62d0d1f27 100644 --- a/app/src/main/java/com/zionhuang/music/lyrics/LyricsHelper.kt +++ b/app/src/main/java/com/zionhuang/music/lyrics/LyricsHelper.kt @@ -27,6 +27,7 @@ class LyricsHelper @Inject constructor( mediaMetadata.artists.joinToString { it.name }, mediaMetadata.duration ).onSuccess { lyrics -> + cache.put(mediaMetadata.id, listOf(LyricsResult(provider.name, lyrics))) return lyrics }.onFailure { reportException(it) @@ -43,8 +44,7 @@ class LyricsHelper @Inject constructor( duration: Int, callback: (LyricsResult) -> Unit, ) { - val cacheKey = "$songArtists-$songTitle".replace(" ", "") - cache.get(cacheKey)?.let { results -> + cache.get(mediaId)?.let { results -> results.forEach { callback(it) } @@ -60,7 +60,7 @@ class LyricsHelper @Inject constructor( } } } - cache.put(cacheKey, allResult) + cache.put(mediaId, allResult) } companion object { diff --git a/app/src/main/java/com/zionhuang/music/playback/MusicService.kt b/app/src/main/java/com/zionhuang/music/playback/MusicService.kt index dbae89d14..15b5a074d 100644 --- a/app/src/main/java/com/zionhuang/music/playback/MusicService.kt +++ b/app/src/main/java/com/zionhuang/music/playback/MusicService.kt @@ -630,7 +630,7 @@ class MusicService : MediaLibraryService(), return@Factory dataSpec } - songUrlCache[mediaId]?.takeIf { it.second < System.currentTimeMillis() }?.let { + songUrlCache[mediaId]?.takeIf { it.second > System.currentTimeMillis() }?.let { scope.launch(Dispatchers.IO) { recoverSong(mediaId) } return@Factory dataSpec.withUri(it.first.toUri()) } @@ -675,24 +675,29 @@ class MusicService : MediaLibraryService(), } } ?: throw PlaybackException(getString(R.string.error_no_stream), null, ERROR_CODE_NO_STREAM) - database.query { - upsert( - FormatEntity( - id = mediaId, - itag = format.itag, - mimeType = format.mimeType.split(";")[0], - codecs = format.mimeType.split("codecs=")[1].removeSurrounding("\""), - bitrate = format.bitrate, - sampleRate = format.audioSampleRate, - contentLength = format.contentLength!!, - loudnessDb = playerResponse.playerConfig?.audioConfig?.loudnessDb + val streamUrl = format.url + ?: throw PlaybackException(getString(R.string.error_no_stream), null, ERROR_CODE_NO_STREAM) + + if (format.contentLength != null) { + database.query { + upsert( + FormatEntity( + id = mediaId, + itag = format.itag, + mimeType = format.mimeType.split(";")[0], + codecs = format.mimeType.split("codecs=")[1].removeSurrounding("\""), + bitrate = format.bitrate, + sampleRate = format.audioSampleRate, + contentLength = format.contentLength, + loudnessDb = playerResponse.playerConfig?.audioConfig?.loudnessDb + ) ) - ) + } } scope.launch(Dispatchers.IO) { recoverSong(mediaId, playerResponse) } - songUrlCache[mediaId] = format.url!! to playerResponse.streamingData!!.expiresInSeconds * 1000L - dataSpec.withUri(format.url!!.toUri()).subrange(dataSpec.uriPositionOffset, CHUNK_LENGTH) + songUrlCache[mediaId] = streamUrl to System.currentTimeMillis() + playerResponse.streamingData!!.expiresInSeconds * 1000L + dataSpec.withUri(streamUrl.toUri()).subrange(dataSpec.uriPositionOffset, CHUNK_LENGTH) } } From e560a88bdc4e762ac427ed55e2f72a217c7f33be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Apr 2026 08:06:53 +0000 Subject: [PATCH 2/2] fix: guard against IndexOutOfBoundsException in mimeType codecs parsing Agent-Logs-Url: https://github.com/nakchwalabhi/InnerTune/sessions/66166913-4599-485a-b5af-bb4679476562 Co-authored-by: nakchwalabhi <118037101+nakchwalabhi@users.noreply.github.com> --- .../zionhuang/music/playback/MusicService.kt | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/zionhuang/music/playback/MusicService.kt b/app/src/main/java/com/zionhuang/music/playback/MusicService.kt index 15b5a074d..4a6523d86 100644 --- a/app/src/main/java/com/zionhuang/music/playback/MusicService.kt +++ b/app/src/main/java/com/zionhuang/music/playback/MusicService.kt @@ -679,19 +679,22 @@ class MusicService : MediaLibraryService(), ?: throw PlaybackException(getString(R.string.error_no_stream), null, ERROR_CODE_NO_STREAM) if (format.contentLength != null) { - database.query { - upsert( - FormatEntity( - id = mediaId, - itag = format.itag, - mimeType = format.mimeType.split(";")[0], - codecs = format.mimeType.split("codecs=")[1].removeSurrounding("\""), - bitrate = format.bitrate, - sampleRate = format.audioSampleRate, - contentLength = format.contentLength, - loudnessDb = playerResponse.playerConfig?.audioConfig?.loudnessDb + val codecs = format.mimeType.split("codecs=").getOrNull(1)?.removeSurrounding("\"") + if (codecs != null) { + database.query { + upsert( + FormatEntity( + id = mediaId, + itag = format.itag, + mimeType = format.mimeType.split(";")[0], + codecs = codecs, + bitrate = format.bitrate, + sampleRate = format.audioSampleRate, + contentLength = format.contentLength, + loudnessDb = playerResponse.playerConfig?.audioConfig?.loudnessDb + ) ) - ) + } } } scope.launch(Dispatchers.IO) { recoverSong(mediaId, playerResponse) }