diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 137446211e..9cb15b2b8b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -92,8 +92,9 @@ val versionTxt by tasks.registering { dependencies { // Jellyfin implementation(projects.playback.core) - implementation(projects.playback.exoplayer) implementation(projects.playback.jellyfin) + implementation(projects.playback.media3.exoplayer) + implementation(projects.playback.media3.session) implementation(projects.preference) implementation(libs.jellyfin.apiclient) implementation(libs.jellyfin.sdk) { 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 3ed0e31591..a5c57e2189 100644 --- a/app/src/main/java/org/jellyfin/androidtv/di/PlaybackModule.kt +++ b/app/src/main/java/org/jellyfin/androidtv/di/PlaybackModule.kt @@ -17,10 +17,11 @@ 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.playbackManager -import org.jellyfin.playback.exoplayer.ExoPlayerOptions -import org.jellyfin.playback.exoplayer.exoPlayerPlugin -import org.jellyfin.playback.exoplayer.session.MediaSessionOptions import org.jellyfin.playback.jellyfin.jellyfinPlugin +import org.jellyfin.playback.media3.exoplayer.ExoPlayerOptions +import org.jellyfin.playback.media3.exoplayer.exoPlayerPlugin +import org.jellyfin.playback.media3.session.MediaSessionOptions +import org.jellyfin.playback.media3.session.media3SessionPlugin import org.jellyfin.sdk.api.client.ApiClient import org.koin.android.ext.koin.androidContext import org.koin.core.scope.Scope @@ -58,18 +59,21 @@ fun Scope.createPlaybackManager() = playbackManager(androidContext()) { NotificationManagerCompat.from(get()).createNotificationChannel(channel) } + val api = get() + val exoPlayerOptions = ExoPlayerOptions( + httpConnectTimeout = api.httpClientOptions.connectTimeout, + httpReadTimeout = api.httpClientOptions.requestTimeout + ) + install(exoPlayerPlugin(get(), exoPlayerOptions)) + val mediaSessionOptions = MediaSessionOptions( channelId = notificationChannelId, notificationId = 1, iconSmall = R.drawable.app_icon_foreground, openIntent = pendingIntent, ) - val api = get() - val exoPlayerOptions = ExoPlayerOptions( - httpConnectTimeout = api.httpClientOptions.connectTimeout, - httpReadTimeout = api.httpClientOptions.requestTimeout - ) - install(exoPlayerPlugin(get(), mediaSessionOptions, exoPlayerOptions)) + install(media3SessionPlugin(get(), mediaSessionOptions)) + install(jellyfinPlugin(get())) // Options diff --git a/playback/exoplayer/src/main/kotlin/ExoPlayerPlugin.kt b/playback/exoplayer/src/main/kotlin/ExoPlayerPlugin.kt deleted file mode 100644 index 841a9da982..0000000000 --- a/playback/exoplayer/src/main/kotlin/ExoPlayerPlugin.kt +++ /dev/null @@ -1,15 +0,0 @@ -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, - mediaSessionOptions: MediaSessionOptions, - exoPlayerOptions: ExoPlayerOptions = ExoPlayerOptions(), -) = playbackPlugin { - provide(ExoPlayerBackend(androidContext, exoPlayerOptions)) - provide(MediaSessionService(androidContext, mediaSessionOptions)) -} diff --git a/playback/exoplayer/build.gradle.kts b/playback/media3/exoplayer/build.gradle.kts similarity index 95% rename from playback/exoplayer/build.gradle.kts rename to playback/media3/exoplayer/build.gradle.kts index 10c7b68587..fa1d8b0798 100644 --- a/playback/exoplayer/build.gradle.kts +++ b/playback/media3/exoplayer/build.gradle.kts @@ -37,7 +37,6 @@ dependencies { 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) diff --git a/playback/media3/exoplayer/src/main/AndroidManifest.xml b/playback/media3/exoplayer/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..94cbbcfc39 --- /dev/null +++ b/playback/media3/exoplayer/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/playback/exoplayer/src/main/kotlin/ExoPlayerAudioPipeline.kt b/playback/media3/exoplayer/src/main/kotlin/ExoPlayerAudioPipeline.kt similarity index 95% rename from playback/exoplayer/src/main/kotlin/ExoPlayerAudioPipeline.kt rename to playback/media3/exoplayer/src/main/kotlin/ExoPlayerAudioPipeline.kt index 77b2408aac..adb636a311 100644 --- a/playback/exoplayer/src/main/kotlin/ExoPlayerAudioPipeline.kt +++ b/playback/media3/exoplayer/src/main/kotlin/ExoPlayerAudioPipeline.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer +package org.jellyfin.playback.media3.exoplayer import android.media.audiofx.LoudnessEnhancer import timber.log.Timber diff --git a/playback/exoplayer/src/main/kotlin/ExoPlayerBackend.kt b/playback/media3/exoplayer/src/main/kotlin/ExoPlayerBackend.kt similarity index 97% rename from playback/exoplayer/src/main/kotlin/ExoPlayerBackend.kt rename to playback/media3/exoplayer/src/main/kotlin/ExoPlayerBackend.kt index 2763fb234a..a2d46807ff 100644 --- a/playback/exoplayer/src/main/kotlin/ExoPlayerBackend.kt +++ b/playback/media3/exoplayer/src/main/kotlin/ExoPlayerBackend.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer +package org.jellyfin.playback.media3.exoplayer import android.app.ActivityManager import android.content.Context @@ -33,8 +33,8 @@ import org.jellyfin.playback.core.queue.QueueEntry import org.jellyfin.playback.core.support.PlaySupportReport import org.jellyfin.playback.core.ui.PlayerSubtitleView import org.jellyfin.playback.core.ui.PlayerSurfaceView -import org.jellyfin.playback.exoplayer.support.getPlaySupportReport -import org.jellyfin.playback.exoplayer.support.toFormats +import org.jellyfin.playback.media3.exoplayer.support.getPlaySupportReport +import org.jellyfin.playback.media3.exoplayer.support.toFormats import timber.log.Timber import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds diff --git a/playback/exoplayer/src/main/kotlin/ExoPlayerOptions.kt b/playback/media3/exoplayer/src/main/kotlin/ExoPlayerOptions.kt similarity index 75% rename from playback/exoplayer/src/main/kotlin/ExoPlayerOptions.kt rename to playback/media3/exoplayer/src/main/kotlin/ExoPlayerOptions.kt index ee0365aeff..bbb9d6a98a 100644 --- a/playback/exoplayer/src/main/kotlin/ExoPlayerOptions.kt +++ b/playback/media3/exoplayer/src/main/kotlin/ExoPlayerOptions.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer +package org.jellyfin.playback.media3.exoplayer import kotlin.time.Duration diff --git a/playback/media3/exoplayer/src/main/kotlin/ExoPlayerPlugin.kt b/playback/media3/exoplayer/src/main/kotlin/ExoPlayerPlugin.kt new file mode 100644 index 0000000000..1a74cefb03 --- /dev/null +++ b/playback/media3/exoplayer/src/main/kotlin/ExoPlayerPlugin.kt @@ -0,0 +1,11 @@ +package org.jellyfin.playback.media3.exoplayer + +import android.content.Context +import org.jellyfin.playback.core.plugin.playbackPlugin + +fun exoPlayerPlugin( + androidContext: Context, + exoPlayerOptions: ExoPlayerOptions = ExoPlayerOptions(), +) = playbackPlugin { + provide(ExoPlayerBackend(androidContext, exoPlayerOptions)) +} diff --git a/playback/exoplayer/src/main/kotlin/mapping/audio.kt b/playback/media3/exoplayer/src/main/kotlin/mapping/audio.kt similarity index 99% rename from playback/exoplayer/src/main/kotlin/mapping/audio.kt rename to playback/media3/exoplayer/src/main/kotlin/mapping/audio.kt index 74349d3d9f..efa9222b6f 100644 --- a/playback/exoplayer/src/main/kotlin/mapping/audio.kt +++ b/playback/media3/exoplayer/src/main/kotlin/mapping/audio.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.mapping +package org.jellyfin.playback.media3.exoplayer.mapping import androidx.annotation.OptIn import androidx.media3.common.MimeTypes diff --git a/playback/exoplayer/src/main/kotlin/mapping/container.kt b/playback/media3/exoplayer/src/main/kotlin/mapping/container.kt similarity index 99% rename from playback/exoplayer/src/main/kotlin/mapping/container.kt rename to playback/media3/exoplayer/src/main/kotlin/mapping/container.kt index 3e30858a12..95386efcae 100644 --- a/playback/exoplayer/src/main/kotlin/mapping/container.kt +++ b/playback/media3/exoplayer/src/main/kotlin/mapping/container.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.mapping +package org.jellyfin.playback.media3.exoplayer.mapping import androidx.annotation.OptIn import androidx.media3.common.MimeTypes diff --git a/playback/exoplayer/src/main/kotlin/mapping/video.kt b/playback/media3/exoplayer/src/main/kotlin/mapping/video.kt similarity index 94% rename from playback/exoplayer/src/main/kotlin/mapping/video.kt rename to playback/media3/exoplayer/src/main/kotlin/mapping/video.kt index 3d49cbca6c..8908e4b9a2 100644 --- a/playback/exoplayer/src/main/kotlin/mapping/video.kt +++ b/playback/media3/exoplayer/src/main/kotlin/mapping/video.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.mapping +package org.jellyfin.playback.media3.exoplayer.mapping import androidx.annotation.OptIn import androidx.media3.common.MimeTypes diff --git a/playback/exoplayer/src/main/kotlin/support/AdaptiveSupport.kt b/playback/media3/exoplayer/src/main/kotlin/support/AdaptiveSupport.kt similarity index 90% rename from playback/exoplayer/src/main/kotlin/support/AdaptiveSupport.kt rename to playback/media3/exoplayer/src/main/kotlin/support/AdaptiveSupport.kt index 2aa7f0d743..94ae6758db 100644 --- a/playback/exoplayer/src/main/kotlin/support/AdaptiveSupport.kt +++ b/playback/media3/exoplayer/src/main/kotlin/support/AdaptiveSupport.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.support +package org.jellyfin.playback.media3.exoplayer.support import androidx.annotation.OptIn import androidx.media3.common.util.UnstableApi diff --git a/playback/exoplayer/src/main/kotlin/support/DecoderSupport.kt b/playback/media3/exoplayer/src/main/kotlin/support/DecoderSupport.kt similarity index 91% rename from playback/exoplayer/src/main/kotlin/support/DecoderSupport.kt rename to playback/media3/exoplayer/src/main/kotlin/support/DecoderSupport.kt index 438b9928f2..2fb1d86a1b 100644 --- a/playback/exoplayer/src/main/kotlin/support/DecoderSupport.kt +++ b/playback/media3/exoplayer/src/main/kotlin/support/DecoderSupport.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.support +package org.jellyfin.playback.media3.exoplayer.support import androidx.annotation.OptIn import androidx.media3.common.util.UnstableApi diff --git a/playback/exoplayer/src/main/kotlin/support/ExoPlayerPlaySupportReport.kt b/playback/media3/exoplayer/src/main/kotlin/support/ExoPlayerPlaySupportReport.kt similarity index 97% rename from playback/exoplayer/src/main/kotlin/support/ExoPlayerPlaySupportReport.kt rename to playback/media3/exoplayer/src/main/kotlin/support/ExoPlayerPlaySupportReport.kt index a2e318fcbc..e593e82e97 100644 --- a/playback/exoplayer/src/main/kotlin/support/ExoPlayerPlaySupportReport.kt +++ b/playback/media3/exoplayer/src/main/kotlin/support/ExoPlayerPlaySupportReport.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.support +package org.jellyfin.playback.media3.exoplayer.support import androidx.annotation.OptIn import androidx.media3.common.Format diff --git a/playback/exoplayer/src/main/kotlin/support/FormatSupport.kt b/playback/media3/exoplayer/src/main/kotlin/support/FormatSupport.kt similarity index 92% rename from playback/exoplayer/src/main/kotlin/support/FormatSupport.kt rename to playback/media3/exoplayer/src/main/kotlin/support/FormatSupport.kt index 863b02554e..5960402803 100644 --- a/playback/exoplayer/src/main/kotlin/support/FormatSupport.kt +++ b/playback/media3/exoplayer/src/main/kotlin/support/FormatSupport.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.support +package org.jellyfin.playback.media3.exoplayer.support import androidx.annotation.OptIn import androidx.media3.common.C diff --git a/playback/exoplayer/src/main/kotlin/support/mediaStreamToFormat.kt b/playback/media3/exoplayer/src/main/kotlin/support/mediaStreamToFormat.kt similarity index 86% rename from playback/exoplayer/src/main/kotlin/support/mediaStreamToFormat.kt rename to playback/media3/exoplayer/src/main/kotlin/support/mediaStreamToFormat.kt index e7b70d0947..e15e66a6ef 100644 --- a/playback/exoplayer/src/main/kotlin/support/mediaStreamToFormat.kt +++ b/playback/media3/exoplayer/src/main/kotlin/support/mediaStreamToFormat.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.support +package org.jellyfin.playback.media3.exoplayer.support import androidx.annotation.OptIn import androidx.media3.common.C @@ -8,9 +8,9 @@ import androidx.media3.common.util.UnstableApi import org.jellyfin.playback.core.mediastream.MediaStream import org.jellyfin.playback.core.mediastream.MediaStreamAudioTrack import org.jellyfin.playback.core.mediastream.MediaStreamVideoTrack -import org.jellyfin.playback.exoplayer.mapping.getFfmpegAudioMimeType -import org.jellyfin.playback.exoplayer.mapping.getFfmpegContainerMimeType -import org.jellyfin.playback.exoplayer.mapping.getFfmpegVideoMimeType +import org.jellyfin.playback.media3.exoplayer.mapping.getFfmpegAudioMimeType +import org.jellyfin.playback.media3.exoplayer.mapping.getFfmpegContainerMimeType +import org.jellyfin.playback.media3.exoplayer.mapping.getFfmpegVideoMimeType @OptIn(UnstableApi::class) private val PCM_CODECS = mapOf( diff --git a/playback/media3/session/build.gradle.kts b/playback/media3/session/build.gradle.kts new file mode 100644 index 0000000000..b4fc68ad7b --- /dev/null +++ b/playback/media3/session/build.gradle.kts @@ -0,0 +1,48 @@ +plugins { + id("com.android.library") + kotlin("android") +} + +android { + namespace = "org.jellyfin.playback.media3.session" + compileSdk = 34 + + defaultConfig { + minSdk = 21 + } + + lint { + lintConfig = file("$rootDir/android-lint.xml") + abortOnError = false + } + + testOptions.unitTests.all { + it.useJUnitPlatform() + } +} + +dependencies { + // Jellyfin + implementation(projects.playback.core) + + // Kotlin + implementation(libs.kotlinx.coroutines) + implementation(libs.kotlinx.coroutines.guava) + + // AndroidX + implementation(libs.androidx.core) + + // media3 + 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) + testImplementation(libs.mockk) +} diff --git a/playback/exoplayer/src/main/AndroidManifest.xml b/playback/media3/session/src/main/AndroidManifest.xml similarity index 84% rename from playback/exoplayer/src/main/AndroidManifest.xml rename to playback/media3/session/src/main/AndroidManifest.xml index 3e0ebee175..3f0ba05031 100644 --- a/playback/exoplayer/src/main/AndroidManifest.xml +++ b/playback/media3/session/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ diff --git a/playback/exoplayer/src/main/kotlin/session/AndroidMediaService.kt b/playback/media3/session/src/main/kotlin/AndroidMediaService.kt similarity index 84% rename from playback/exoplayer/src/main/kotlin/session/AndroidMediaService.kt rename to playback/media3/session/src/main/kotlin/AndroidMediaService.kt index d5a5e829ec..2b0cd039d1 100644 --- a/playback/exoplayer/src/main/kotlin/session/AndroidMediaService.kt +++ b/playback/media3/session/src/main/kotlin/AndroidMediaService.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.session +package org.jellyfin.playback.media3.session import androidx.media3.session.MediaSession import androidx.media3.session.MediaSessionService diff --git a/playback/media3/session/src/main/kotlin/Media3SessionPlugin.kt b/playback/media3/session/src/main/kotlin/Media3SessionPlugin.kt new file mode 100644 index 0000000000..287800f5e6 --- /dev/null +++ b/playback/media3/session/src/main/kotlin/Media3SessionPlugin.kt @@ -0,0 +1,11 @@ +package org.jellyfin.playback.media3.session + +import android.content.Context +import org.jellyfin.playback.core.plugin.playbackPlugin + +fun media3SessionPlugin( + androidContext: Context, + options: MediaSessionOptions +) = playbackPlugin { + provide(MediaSessionService(androidContext, options)) +} diff --git a/playback/exoplayer/src/main/kotlin/session/MediaSessionOptions.kt b/playback/media3/session/src/main/kotlin/MediaSessionOptions.kt similarity index 82% rename from playback/exoplayer/src/main/kotlin/session/MediaSessionOptions.kt rename to playback/media3/session/src/main/kotlin/MediaSessionOptions.kt index 1120afd232..ad546d0239 100644 --- a/playback/exoplayer/src/main/kotlin/session/MediaSessionOptions.kt +++ b/playback/media3/session/src/main/kotlin/MediaSessionOptions.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.session +package org.jellyfin.playback.media3.session import android.app.PendingIntent import androidx.annotation.DrawableRes diff --git a/playback/exoplayer/src/main/kotlin/session/MediaSessionPlayer.kt b/playback/media3/session/src/main/kotlin/MediaSessionPlayer.kt similarity index 99% rename from playback/exoplayer/src/main/kotlin/session/MediaSessionPlayer.kt rename to playback/media3/session/src/main/kotlin/MediaSessionPlayer.kt index 276c0b4d6f..d4dc755f06 100644 --- a/playback/exoplayer/src/main/kotlin/session/MediaSessionPlayer.kt +++ b/playback/media3/session/src/main/kotlin/MediaSessionPlayer.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.session +package org.jellyfin.playback.media3.session import android.os.Looper import androidx.annotation.OptIn diff --git a/playback/exoplayer/src/main/kotlin/session/MediaSessionService.kt b/playback/media3/session/src/main/kotlin/MediaSessionService.kt similarity index 98% rename from playback/exoplayer/src/main/kotlin/session/MediaSessionService.kt rename to playback/media3/session/src/main/kotlin/MediaSessionService.kt index 3cbcae3dfd..f65458698a 100644 --- a/playback/exoplayer/src/main/kotlin/session/MediaSessionService.kt +++ b/playback/media3/session/src/main/kotlin/MediaSessionService.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.session +package org.jellyfin.playback.media3.session import android.content.Context import android.os.Looper diff --git a/playback/exoplayer/src/main/kotlin/session/MetadataExtensions.kt b/playback/media3/session/src/main/kotlin/MetadataExtensions.kt similarity index 95% rename from playback/exoplayer/src/main/kotlin/session/MetadataExtensions.kt rename to playback/media3/session/src/main/kotlin/MetadataExtensions.kt index 5fff1ac235..2fa8c4f4d0 100644 --- a/playback/exoplayer/src/main/kotlin/session/MetadataExtensions.kt +++ b/playback/media3/session/src/main/kotlin/MetadataExtensions.kt @@ -1,4 +1,4 @@ -package org.jellyfin.playback.exoplayer.session +package org.jellyfin.playback.media3.session import androidx.core.net.toUri import androidx.media3.common.MediaItem diff --git a/settings.gradle.kts b/settings.gradle.kts index dea62829fa..4d2c942172 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,8 +7,9 @@ include(":app") // Modules include(":playback:core") -include(":playback:exoplayer") include(":playback:jellyfin") +include(":playback:media3:exoplayer") +include(":playback:media3:session") include(":preference") pluginManagement {