refactor: encode player metadata as JSON string instead of parcelable

This commit is contained in:
Bnyro 2025-02-03 18:33:53 +01:00
parent a1cb16b07a
commit 33c386e4ce
4 changed files with 33 additions and 13 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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<ChapterSegment>? = mediaMetadata.extras?.parcelableList(IntentData.chapters)
// JSON-encode as work-around for https://github.com/androidx/media/issues/564
val chapters: List<ChapterSegment>? = mediaMetadata.extras?.getString(IntentData.chapters)?.let {
JsonHelper.json.decodeFromString(it)
}
_binding?.openChapters?.isVisible = !chapters.isNullOrEmpty()
}
})

View File

@ -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<Segment>? = mediaMetadata.extras?.parcelableList(IntentData.segments)
// JSON-encode as work-around for https://github.com/androidx/media/issues/564
val segments: List<Segment>? = 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) {