From 6bbf315d76c5c929c8d1106e73c71493422856da Mon Sep 17 00:00:00 2001 From: Niels van Velzen Date: Wed, 12 Jun 2024 21:44:56 +0200 Subject: [PATCH] Move media session implementation to exoplayer module --- .../org/jellyfin/androidtv/di/PlaybackModule.kt | 15 ++++++--------- playback/core/build.gradle.kts | 7 ------- playback/core/src/main/AndroidManifest.xml | 14 +------------- .../kotlin/mediasession/MediaSessionPlugin.kt | 11 ----------- .../main/kotlin/mediastream/MediaStreamState.kt | 1 - playback/exoplayer/build.gradle.kts | 6 +++++- playback/exoplayer/src/main/AndroidManifest.xml | 16 +++++++++++++++- .../exoplayer/src/main/kotlin/ExoPlayerPlugin.kt | 8 +++++++- .../main/kotlin/session}/AndroidMediaService.kt | 2 +- .../main/kotlin/session}/MediaSessionOptions.kt | 2 +- .../main/kotlin/session}/MediaSessionPlayer.kt | 2 +- .../main/kotlin/session}/MediaSessionService.kt | 2 +- .../main/kotlin/session}/MetadataExtensions.kt | 4 ++-- 13 files changed, 40 insertions(+), 50 deletions(-) delete mode 100644 playback/core/src/main/kotlin/mediasession/MediaSessionPlugin.kt rename playback/{core/src/main/kotlin/mediasession => exoplayer/src/main/kotlin/session}/AndroidMediaService.kt (84%) rename playback/{core/src/main/kotlin/mediasession => exoplayer/src/main/kotlin/session}/MediaSessionOptions.kt (82%) rename playback/{core/src/main/kotlin/mediasession => exoplayer/src/main/kotlin/session}/MediaSessionPlayer.kt (99%) rename playback/{core/src/main/kotlin/mediasession => exoplayer/src/main/kotlin/session}/MediaSessionService.kt (98%) rename playback/{core/src/main/kotlin/mediasession => exoplayer/src/main/kotlin/session}/MetadataExtensions.kt (91%) diff --git a/app/src/main/java/org/jellyfin/androidtv/di/PlaybackModule.kt b/app/src/main/java/org/jellyfin/androidtv/di/PlaybackModule.kt index 91ddc2bdff..7ae88e8924 100644 --- a/app/src/main/java/org/jellyfin/androidtv/di/PlaybackModule.kt +++ b/app/src/main/java/org/jellyfin/androidtv/di/PlaybackModule.kt @@ -16,10 +16,9 @@ import org.jellyfin.androidtv.ui.playback.MediaManager import org.jellyfin.androidtv.ui.playback.RewritePlaybackLauncher import org.jellyfin.androidtv.ui.playback.VideoQueueManager import org.jellyfin.androidtv.ui.playback.rewrite.RewriteMediaManager -import org.jellyfin.playback.core.mediasession.MediaSessionOptions -import org.jellyfin.playback.core.mediasession.mediaSessionPlugin import org.jellyfin.playback.core.playbackManager import org.jellyfin.playback.exoplayer.exoPlayerPlugin +import org.jellyfin.playback.exoplayer.session.MediaSessionOptions import org.jellyfin.playback.jellyfin.jellyfinPlugin import org.koin.android.ext.koin.androidContext import org.koin.core.scope.Scope @@ -44,13 +43,10 @@ val playbackModule = module { } fun Scope.createPlaybackManager() = playbackManager(androidContext()) { - install(exoPlayerPlugin(get())) - install(jellyfinPlugin(get())) - val activityIntent = Intent(get(), MainActivity::class.java) val pendingIntent = PendingIntent.getActivity(get(), 0, activityIntent, PendingIntent.FLAG_IMMUTABLE) - val notificationChannelId = "mediasession" + val notificationChannelId = "session" if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( notificationChannelId, @@ -60,12 +56,13 @@ fun Scope.createPlaybackManager() = playbackManager(androidContext()) { NotificationManagerCompat.from(get()).createNotificationChannel(channel) } - install(mediaSessionPlugin(get(), MediaSessionOptions( + val mediaSessionOptions = MediaSessionOptions( channelId = notificationChannelId, notificationId = 1, iconSmall = R.drawable.app_icon_foreground, - openIntent = pendingIntent, - ))) + openIntent = pendingIntent,) + install(exoPlayerPlugin(get(), mediaSessionOptions)) + install(jellyfinPlugin(get())) // Options val userSettingPreferences = get() diff --git a/playback/core/build.gradle.kts b/playback/core/build.gradle.kts index fcd78cbfef..a4156c59de 100644 --- a/playback/core/build.gradle.kts +++ b/playback/core/build.gradle.kts @@ -1,7 +1,6 @@ plugins { id("com.android.library") kotlin("android") - alias(libs.plugins.kotlin.serialization) } android { @@ -29,15 +28,9 @@ android { dependencies { // Kotlin implementation(libs.kotlinx.coroutines) - implementation(libs.kotlinx.coroutines.guava) - implementation(libs.kotlinx.serialization.json) // Android(x) implementation(libs.androidx.core) - implementation(libs.androidx.appcompat) - implementation(libs.androidx.constraintlayout) - implementation(libs.bundles.androidx.lifecycle) - implementation(libs.androidx.media3.session) // Dependency Injection implementation(libs.bundles.koin) diff --git a/playback/core/src/main/AndroidManifest.xml b/playback/core/src/main/AndroidManifest.xml index 9bd2ab3f15..94cbbcfc39 100644 --- a/playback/core/src/main/AndroidManifest.xml +++ b/playback/core/src/main/AndroidManifest.xml @@ -1,13 +1 @@ - - - - - - - - - - + diff --git a/playback/core/src/main/kotlin/mediasession/MediaSessionPlugin.kt b/playback/core/src/main/kotlin/mediasession/MediaSessionPlugin.kt deleted file mode 100644 index 260805b221..0000000000 --- a/playback/core/src/main/kotlin/mediasession/MediaSessionPlugin.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.jellyfin.playback.core.mediasession - -import android.content.Context -import org.jellyfin.playback.core.plugin.playbackPlugin - -fun mediaSessionPlugin( - androidContext: Context, - options: MediaSessionOptions, -) = playbackPlugin { - provide(MediaSessionService(androidContext, options)) -} diff --git a/playback/core/src/main/kotlin/mediastream/MediaStreamState.kt b/playback/core/src/main/kotlin/mediastream/MediaStreamState.kt index f82173f5e6..2ac9f1479e 100644 --- a/playback/core/src/main/kotlin/mediastream/MediaStreamState.kt +++ b/playback/core/src/main/kotlin/mediastream/MediaStreamState.kt @@ -41,7 +41,6 @@ internal class MediaStreamState( } } }.launchIn(coroutineScope + Dispatchers.Main) - // TODO Register some kind of event when $current item is at -30 seconds to setNext() } diff --git a/playback/exoplayer/build.gradle.kts b/playback/exoplayer/build.gradle.kts index 6c42287fca..10c7b68587 100644 --- a/playback/exoplayer/build.gradle.kts +++ b/playback/exoplayer/build.gradle.kts @@ -32,15 +32,19 @@ dependencies { // AndroidX implementation(libs.androidx.core) - // ExoPlayer + // media3 implementation(libs.androidx.media3.exoplayer) implementation(libs.androidx.media3.exoplayer.hls) implementation(libs.jellyfin.androidx.media3.ffmpeg.decoder) implementation(libs.androidx.media3.ui) + implementation(libs.androidx.media3.session) // Logging implementation(libs.timber) + // Compatibility (desugaring) + coreLibraryDesugaring(libs.android.desugar) + // Testing testImplementation(libs.kotest.runner.junit5) testImplementation(libs.kotest.assertions) diff --git a/playback/exoplayer/src/main/AndroidManifest.xml b/playback/exoplayer/src/main/AndroidManifest.xml index 94cbbcfc39..3e0ebee175 100644 --- a/playback/exoplayer/src/main/AndroidManifest.xml +++ b/playback/exoplayer/src/main/AndroidManifest.xml @@ -1 +1,15 @@ - + + + + + + + + + + diff --git a/playback/exoplayer/src/main/kotlin/ExoPlayerPlugin.kt b/playback/exoplayer/src/main/kotlin/ExoPlayerPlugin.kt index 03a4690e5c..1f76585178 100644 --- a/playback/exoplayer/src/main/kotlin/ExoPlayerPlugin.kt +++ b/playback/exoplayer/src/main/kotlin/ExoPlayerPlugin.kt @@ -2,7 +2,13 @@ package org.jellyfin.playback.exoplayer import android.content.Context import org.jellyfin.playback.core.plugin.playbackPlugin +import org.jellyfin.playback.exoplayer.session.MediaSessionOptions +import org.jellyfin.playback.exoplayer.session.MediaSessionService -fun exoPlayerPlugin(androidContext: Context) = playbackPlugin { +fun exoPlayerPlugin( + androidContext: Context, + mediaSessionOptions: MediaSessionOptions, +) = playbackPlugin { provide(ExoPlayerBackend(androidContext)) + provide(MediaSessionService(androidContext, mediaSessionOptions)) } diff --git a/playback/core/src/main/kotlin/mediasession/AndroidMediaService.kt b/playback/exoplayer/src/main/kotlin/session/AndroidMediaService.kt similarity index 84% rename from playback/core/src/main/kotlin/mediasession/AndroidMediaService.kt rename to playback/exoplayer/src/main/kotlin/session/AndroidMediaService.kt index 9aa434314f..d5a5e829ec 100644 --- a/playback/core/src/main/kotlin/mediasession/AndroidMediaService.kt +++ b/playback/exoplayer/src/main/kotlin/session/AndroidMediaService.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.core.mediasession +package org.jellyfin.playback.exoplayer.session import androidx.media3.session.MediaSession import androidx.media3.session.MediaSessionService diff --git a/playback/core/src/main/kotlin/mediasession/MediaSessionOptions.kt b/playback/exoplayer/src/main/kotlin/session/MediaSessionOptions.kt similarity index 82% rename from playback/core/src/main/kotlin/mediasession/MediaSessionOptions.kt rename to playback/exoplayer/src/main/kotlin/session/MediaSessionOptions.kt index 4d4fb7e0b7..1120afd232 100644 --- a/playback/core/src/main/kotlin/mediasession/MediaSessionOptions.kt +++ b/playback/exoplayer/src/main/kotlin/session/MediaSessionOptions.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.core.mediasession +package org.jellyfin.playback.exoplayer.session import android.app.PendingIntent import androidx.annotation.DrawableRes diff --git a/playback/core/src/main/kotlin/mediasession/MediaSessionPlayer.kt b/playback/exoplayer/src/main/kotlin/session/MediaSessionPlayer.kt similarity index 99% rename from playback/core/src/main/kotlin/mediasession/MediaSessionPlayer.kt rename to playback/exoplayer/src/main/kotlin/session/MediaSessionPlayer.kt index df734e32d4..276c0b4d6f 100644 --- a/playback/core/src/main/kotlin/mediasession/MediaSessionPlayer.kt +++ b/playback/exoplayer/src/main/kotlin/session/MediaSessionPlayer.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.core.mediasession +package org.jellyfin.playback.exoplayer.session import android.os.Looper import androidx.annotation.OptIn diff --git a/playback/core/src/main/kotlin/mediasession/MediaSessionService.kt b/playback/exoplayer/src/main/kotlin/session/MediaSessionService.kt similarity index 98% rename from playback/core/src/main/kotlin/mediasession/MediaSessionService.kt rename to playback/exoplayer/src/main/kotlin/session/MediaSessionService.kt index 6172a02294..3cbcae3dfd 100644 --- a/playback/core/src/main/kotlin/mediasession/MediaSessionService.kt +++ b/playback/exoplayer/src/main/kotlin/session/MediaSessionService.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.core.mediasession +package org.jellyfin.playback.exoplayer.session import android.content.Context import android.os.Looper diff --git a/playback/core/src/main/kotlin/mediasession/MetadataExtensions.kt b/playback/exoplayer/src/main/kotlin/session/MetadataExtensions.kt similarity index 91% rename from playback/core/src/main/kotlin/mediasession/MetadataExtensions.kt rename to playback/exoplayer/src/main/kotlin/session/MetadataExtensions.kt index 310f6ed72a..5fff1ac235 100644 --- a/playback/core/src/main/kotlin/mediasession/MetadataExtensions.kt +++ b/playback/exoplayer/src/main/kotlin/session/MetadataExtensions.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.core.mediasession +package org.jellyfin.playback.exoplayer.session import androidx.core.net.toUri import androidx.media3.common.MediaItem @@ -6,7 +6,7 @@ import androidx.media3.common.MediaMetadata import org.jellyfin.playback.core.queue.QueueEntryMetadata fun QueueEntryMetadata.toMediaItem() = MediaItem.Builder().apply { - if (mediaId != null) setMediaId(mediaId) + mediaId?.let { setMediaId(it) } setMediaMetadata(MediaMetadata.Builder().apply { setTitle(title)