From 6bbf315d76c5c929c8d1106e73c71493422856da Mon Sep 17 00:00:00 2001 From: Niels van Velzen Date: Wed, 12 Jun 2024 21:44:56 +0200 Subject: [PATCH 1/2] 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) From 2eb45ac80cf2faafd5c05f9fac71ace0d472a544 Mon Sep 17 00:00:00 2001 From: Niels van Velzen Date: Wed, 12 Jun 2024 21:48:10 +0200 Subject: [PATCH 2/2] Drop unused playback-ui module --- app/build.gradle.kts | 1 - playback/ui/build.gradle.kts | 59 ------------------------ playback/ui/src/main/AndroidManifest.xml | 6 --- settings.gradle.kts | 1 - 4 files changed, 67 deletions(-) delete mode 100644 playback/ui/build.gradle.kts delete mode 100644 playback/ui/src/main/AndroidManifest.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 58a7e9bc86..0e59afa533 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -94,7 +94,6 @@ dependencies { implementation(projects.playback.core) implementation(projects.playback.exoplayer) implementation(projects.playback.jellyfin) - implementation(projects.playback.ui) implementation(projects.preference) implementation(libs.jellyfin.apiclient) implementation(libs.jellyfin.sdk) { diff --git a/playback/ui/build.gradle.kts b/playback/ui/build.gradle.kts deleted file mode 100644 index 9fc3efad76..0000000000 --- a/playback/ui/build.gradle.kts +++ /dev/null @@ -1,59 +0,0 @@ -plugins { - id("com.android.library") - kotlin("android") -} - -android { - namespace = "org.jellyfin.playback.ui" - compileSdk = 34 - - defaultConfig { - minSdk = 21 - } - - buildFeatures { - viewBinding = true - } - - lint { - lintConfig = file("$rootDir/android-lint.xml") - abortOnError = false - } - - testOptions.unitTests.all { - it.useJUnitPlatform() - } -} - -dependencies { - // Jellyfin - implementation(projects.playback.core) - implementation(projects.playback.jellyfin) - implementation(libs.jellyfin.sdk) { - // Change version if desired - val sdkVersion = findProperty("sdk.version")?.toString() - when (sdkVersion) { - "local" -> version { strictly("latest-SNAPSHOT") } - "snapshot" -> version { strictly("master-SNAPSHOT") } - "unstable-snapshot" -> version { strictly("openapi-unstable-SNAPSHOT") } - } - } - - // 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) - - // Logging - implementation(libs.timber) - - // Testing - testImplementation(libs.kotest.runner.junit5) - testImplementation(libs.kotest.assertions) - testImplementation(libs.mockk) -} diff --git a/playback/ui/src/main/AndroidManifest.xml b/playback/ui/src/main/AndroidManifest.xml deleted file mode 100644 index d7898ad6b4..0000000000 --- a/playback/ui/src/main/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/settings.gradle.kts b/settings.gradle.kts index 03f0c9d7a8..dea62829fa 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -9,7 +9,6 @@ include(":app") include(":playback:core") include(":playback:exoplayer") include(":playback:jellyfin") -include(":playback:ui") include(":preference") pluginManagement {