From 33c386e4cea0ed5a6f0623e33c5885a82c83ab2e Mon Sep 17 00:00:00 2001 From: Bnyro Date: Mon, 3 Feb 2025 18:33:53 +0100 Subject: [PATCH] refactor: encode player metadata as JSON string instead of parcelable --- .../github/libretube/extensions/SetMetadata.kt | 12 ++++++++---- .../libretube/services/OnlinePlayerService.kt | 4 +++- .../ui/fragments/AudioPlayerFragment.kt | 13 +++++++++---- .../libretube/ui/fragments/PlayerFragment.kt | 17 +++++++++++++---- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/github/libretube/extensions/SetMetadata.kt b/app/src/main/java/com/github/libretube/extensions/SetMetadata.kt index 2cd8ab42b..36eae0bc2 100644 --- a/app/src/main/java/com/github/libretube/extensions/SetMetadata.kt +++ b/app/src/main/java/com/github/libretube/extensions/SetMetadata.kt @@ -7,10 +7,12 @@ import androidx.core.os.bundleOf import androidx.media3.common.MediaItem import androidx.media3.common.MediaMetadata import androidx.media3.common.util.UnstableApi +import com.github.libretube.api.JsonHelper import com.github.libretube.api.obj.Streams import com.github.libretube.constants.IntentData import com.github.libretube.db.obj.DownloadChapter import com.github.libretube.db.obj.DownloadWithItems +import kotlinx.serialization.encodeToString @OptIn(UnstableApi::class) fun MediaItem.Builder.setMetadata(streams: Streams, videoId: String) = apply { @@ -18,8 +20,9 @@ fun MediaItem.Builder.setMetadata(streams: Streams, videoId: String) = apply { MediaMetadataCompat.METADATA_KEY_TITLE to streams.title, MediaMetadataCompat.METADATA_KEY_ARTIST to streams.uploader, IntentData.videoId to videoId, - IntentData.streams to streams, - IntentData.chapters to streams.chapters + // JSON-encode as work-around for https://github.com/androidx/media/issues/564 + IntentData.streams to JsonHelper.json.encodeToString(streams), + IntentData.chapters to JsonHelper.json.encodeToString(streams.chapters) ) setMediaMetadata( MediaMetadata.Builder() @@ -37,13 +40,14 @@ fun MediaItem.Builder.setMetadata(streams: Streams, videoId: String) = apply { @OptIn(UnstableApi::class) fun MediaItem.Builder.setMetadata(downloadWithItems: DownloadWithItems) = apply { - val (download, _, chapters) = downloadWithItems + val (download, _, downloadChapters) = downloadWithItems + val chapters = downloadChapters.map(DownloadChapter::toChapterSegment) val extras = bundleOf( MediaMetadataCompat.METADATA_KEY_TITLE to download.title, MediaMetadataCompat.METADATA_KEY_ARTIST to download.uploader, IntentData.videoId to download.videoId, - IntentData.chapters to chapters.map(DownloadChapter::toChapterSegment) + IntentData.chapters to JsonHelper.json.encodeToString(chapters) ) setMediaMetadata( MediaMetadata.Builder() diff --git a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt index 099895a1c..9f31d3dd6 100644 --- a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt +++ b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt @@ -207,7 +207,9 @@ open class OnlinePlayerService : AbstractPlayerService() { withContext(Dispatchers.Main) { updatePlaylistMetadata { - setExtras(bundleOf(IntentData.segments to ArrayList(sponsorBlockSegments))) + // JSON-encode as work-around for https://github.com/androidx/media/issues/564 + val segments = JsonHelper.json.encodeToString(sponsorBlockSegments) + setExtras(bundleOf(IntentData.segments to segments)) } checkForSegments() diff --git a/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt index 5b4cfba8a..d7f10b89a 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt @@ -25,14 +25,13 @@ import androidx.media3.common.Player import androidx.media3.common.util.UnstableApi import androidx.media3.session.MediaController import com.github.libretube.R +import com.github.libretube.api.JsonHelper import com.github.libretube.api.obj.ChapterSegment import com.github.libretube.constants.IntentData import com.github.libretube.databinding.FragmentAudioPlayerBinding import com.github.libretube.extensions.navigateVideo import com.github.libretube.extensions.normalize -import com.github.libretube.extensions.parcelableList import com.github.libretube.extensions.seekBy -import com.github.libretube.extensions.serializable import com.github.libretube.extensions.togglePlayPauseState import com.github.libretube.extensions.updateIfChanged import com.github.libretube.helpers.AudioHelper @@ -194,8 +193,11 @@ class AudioPlayerFragment : Fragment(R.layout.fragment_audio_player), AudioPlaye } binding.openChapters.setOnClickListener { + // JSON-encode as work-around for https://github.com/androidx/media/issues/564 chaptersModel.chaptersLiveData.value = - playerController?.mediaMetadata?.extras?.serializable(IntentData.chapters) + playerController?.mediaMetadata?.extras?.getString(IntentData.chapters)?.let { + JsonHelper.json.decodeFromString(it) + } ChaptersBottomSheet() .apply { @@ -430,7 +432,10 @@ class AudioPlayerFragment : Fragment(R.layout.fragment_audio_player), AudioPlaye super.onMediaMetadataChanged(mediaMetadata) updateStreamInfo(mediaMetadata) - val chapters: List? = mediaMetadata.extras?.parcelableList(IntentData.chapters) + // JSON-encode as work-around for https://github.com/androidx/media/issues/564 + val chapters: List? = mediaMetadata.extras?.getString(IntentData.chapters)?.let { + JsonHelper.json.decodeFromString(it) + } _binding?.openChapters?.isVisible = !chapters.isNullOrEmpty() } }) diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 3e152fbb6..c658bd99b 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -51,6 +51,7 @@ import androidx.media3.common.Player import androidx.media3.session.MediaController import androidx.recyclerview.widget.LinearLayoutManager import com.github.libretube.R +import com.github.libretube.api.JsonHelper import com.github.libretube.api.obj.ChapterSegment import com.github.libretube.api.obj.Segment import com.github.libretube.api.obj.Streams @@ -66,7 +67,6 @@ import com.github.libretube.enums.PlayerEvent import com.github.libretube.enums.ShareObjectType import com.github.libretube.extensions.formatShort import com.github.libretube.extensions.parcelable -import com.github.libretube.extensions.parcelableList import com.github.libretube.extensions.serializableExtra import com.github.libretube.extensions.toID import com.github.libretube.extensions.togglePlayPauseState @@ -308,7 +308,10 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions { override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) { super.onMediaMetadataChanged(mediaMetadata) - val maybeStreams: Streams? = mediaMetadata.extras?.parcelable(IntentData.streams) + // JSON-encode as work-around for https://github.com/androidx/media/issues/564 + val maybeStreams: Streams? = mediaMetadata.extras?.getString(IntentData.streams)?.let { + JsonHelper.json.decodeFromString(it) + } maybeStreams?.let { streams -> this@PlayerFragment.streams = streams viewModel.segments.postValue(emptyList()) @@ -332,7 +335,10 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions { } } - val segments: List? = mediaMetadata.extras?.parcelableList(IntentData.segments) + // JSON-encode as work-around for https://github.com/androidx/media/issues/564 + val segments: List? = mediaMetadata.extras?.getString(IntentData.segments)?.let { + JsonHelper.json.decodeFromString(it) + } viewModel.segments.postValue(segments.orEmpty()) } @@ -514,8 +520,11 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions { updatePlayPauseButton() if (!startNewSession) { + // JSON-encode as work-around for https://github.com/androidx/media/issues/564 val streams: Streams? = - playerController.mediaMetadata.extras?.parcelable(IntentData.streams) + playerController.mediaMetadata.extras?.getString(IntentData.streams)?.let { json -> + JsonHelper.json.decodeFromString(json) + } // reload the streams data and playback, metadata apparently no longer exists if (streams == null) {