Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to AndroidX Media3 1.4.0 #618

Merged
merged 3 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,9 @@ package ch.srgssr.pillarbox.gradle.internal

import com.android.build.api.dsl.CommonExtension
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

internal val Project.libs: VersionCatalog
get() = extensions.getByType<VersionCatalogsExtension>().named("libs")

internal fun Project.configureAndroidModule(extension: CommonExtension<*, *, *, *, *, *>) = with(extension) {
namespace = "ch.srgssr.pillarbox." + name.removePrefix("pillarbox-").replace('-', '.')
compileSdk = AppConfig.compileSdk
Expand All @@ -27,18 +20,12 @@ internal fun Project.configureAndroidModule(extension: CommonExtension<*, *, *,
compileOptions {
sourceCompatibility = AppConfig.javaVersion
targetCompatibility = AppConfig.javaVersion
isCoreLibraryDesugaringEnabled = true
}

buildFeatures {
resValues = false
shaders = false
}

dependencies {
// coreLibraryDesugaring(libs.findLibrary("android-desugar-jdk-libs").get())
add("coreLibraryDesugaring", libs.findLibrary("android-desugar-jdk-libs").get())
}
}

internal fun Project.configureKotlinModule() {
Expand Down
19 changes: 0 additions & 19 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,25 +120,6 @@ kotlinOptions {
}
```

### Support Android API < 24

A change in AndroidX Media3 1.3.0 requires applications to use library desugaring, as described in the corresponding [Android documentation](https://developer.android.com/studio/write/java8-support#library-desugaring):

```kotlin
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
isCoreLibraryDesugaringEnabled = true
}

dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")
}
```

> [!IMPORTANT]
> This should be done even if your min SDK version is 24+.

### Integrate Pillarbox

To start using Pillarbox in your project, you can check each module's documentation:
Expand Down
8 changes: 2 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[versions]
accompanist = "0.34.0"
android-desugar-jdk-libs = "2.0.4"
android-gradle-plugin = "8.5.1"
androidx-activity = "1.9.0"
androidx-annotation = "1.8.0"
Expand All @@ -9,8 +8,7 @@ androidx-core = "1.13.1"
androidx-fragment = "1.8.1"
androidx-leanback = "1.0.0"
androidx-lifecycle = "2.8.3"
androidx-media = "1.7.0"
androidx-media3 = "1.3.1"
androidx-media3 = "1.4.0"
androidx-navigation = "2.7.7"
androidx-paging = "3.3.0"
androidx-test-core = "1.6.1"
Expand All @@ -24,7 +22,7 @@ comscore = "6.11.1"
dependency-analysis-gradle-plugin = "1.32.0"
detekt = "1.23.6"
dokka = "1.9.20"
guava = "32.1.3-android"
guava = "33.0.0-android"
json = "20240303"
junit = "4.13.2"
kotlin = "2.0.0"
Expand All @@ -42,7 +40,6 @@ turbine = "1.1.0"

[libraries]
accompanist-navigation-material = { module = "com.google.accompanist:accompanist-navigation-material", version.ref = "accompanist" }
android-desugar-jdk-libs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "android-desugar-jdk-libs" }
android-gradle-api = { module = "com.android.tools.build:gradle-api", version.ref = "android-gradle-plugin" }
androidx-activity = { module = "androidx.activity:activity", version.ref = "androidx-activity" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
Expand Down Expand Up @@ -108,7 +105,6 @@ androidx-media3-hls = { group = "androidx.media3", name = "media3-exoplayer-hls"
androidx-media3-session = { group = "androidx.media3", name = "media3-session", version.ref = "androidx-media3" }
androidx-media3-test-utils = { module = "androidx.media3:media3-test-utils", version.ref = "androidx-media3" }
androidx-media3-test-utils-robolectric = { module = "androidx.media3:media3-test-utils-robolectric", version.ref = "androidx-media3" }
androidx-media = { group = "androidx.media", name = "media", version.ref = "androidx-media" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
okhttp-logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
tagcommander-core = { group = "com.tagcommander.lib", name = "core", version.ref = "tag-commander-core" }
Expand Down
1 change: 0 additions & 1 deletion pillarbox-demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ dependencies {
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.media)
implementation(libs.androidx.media3.common)
implementation(libs.androidx.media3.exoplayer)
implementation(libs.androidx.media3.session)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class UpdatableMediaItemViewModel(application: Application) : AndroidViewModel(a
.setMediaDescriptionAdapter(PillarboxMediaDescriptionAdapter(context = application, pendingIntent = null))
.build()
notificationManager.setPlayer(player)
notificationManager.setMediaSessionToken(mediaSession.sessionCompatToken)
notificationManager.setMediaSessionToken(mediaSession.platformToken)

timer = timer(name = "update-item", period = 3.seconds.inWholeMilliseconds) {
viewModelScope.launch(Dispatchers.Main) {
Expand Down
1 change: 0 additions & 1 deletion pillarbox-player/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ android {
dependencies {
implementation(libs.androidx.annotation)
implementation(libs.androidx.core)
api(libs.androidx.media)
api(libs.androidx.media3.common)
implementation(libs.androidx.media3.dash)
implementation(libs.androidx.media3.datasource)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.media3.common.Timeline
import androidx.media3.exoplayer.DefaultLoadControl
import androidx.media3.exoplayer.LoadControl
import androidx.media3.exoplayer.Renderer
import androidx.media3.exoplayer.analytics.PlayerId
import androidx.media3.exoplayer.source.MediaSource
import androidx.media3.exoplayer.source.TrackGroupArray
import androidx.media3.exoplayer.trackselection.ExoTrackSelection
Expand Down Expand Up @@ -41,57 +42,47 @@ class PillarboxLoadControl(
.setBackBuffer(BACK_BUFFER_DURATION_MS, true)
.build()

override fun onPrepared() {
defaultLoadControl.onPrepared()
override fun onPrepared(playerId: PlayerId) {
defaultLoadControl.onPrepared(playerId)
}

override fun onStopped() {
defaultLoadControl.onStopped()
override fun onStopped(playerId: PlayerId) {
defaultLoadControl.onStopped(playerId)
}

override fun onReleased() {
defaultLoadControl.onReleased()
override fun onReleased(playerId: PlayerId) {
defaultLoadControl.onReleased(playerId)
}

override fun getAllocator(): Allocator {
return allocator
}

override fun getBackBufferDurationUs(): Long {
return defaultLoadControl.backBufferDurationUs
override fun getBackBufferDurationUs(playerId: PlayerId): Long {
return defaultLoadControl.getBackBufferDurationUs(playerId)
}

override fun retainBackBufferFromKeyframe(): Boolean {
return defaultLoadControl.retainBackBufferFromKeyframe()
override fun retainBackBufferFromKeyframe(playerId: PlayerId): Boolean {
return defaultLoadControl.retainBackBufferFromKeyframe(playerId)
}

override fun shouldContinueLoading(
playbackPositionUs: Long,
bufferedDurationUs: Long,
playbackSpeed: Float
): Boolean {
return defaultLoadControl.shouldContinueLoading(playbackPositionUs, bufferedDurationUs, playbackSpeed)
override fun shouldContinueLoading(parameters: LoadControl.Parameters): Boolean {
return defaultLoadControl.shouldContinueLoading(parameters)
}

override fun onTracksSelected(
playerId: PlayerId,
timeline: Timeline,
mediaPeriodId: MediaSource.MediaPeriodId,
renderers: Array<out Renderer>,
trackGroups: TrackGroupArray,
trackSelections: Array<out ExoTrackSelection>
) {
defaultLoadControl.onTracksSelected(timeline, mediaPeriodId, renderers, trackGroups, trackSelections)
defaultLoadControl.onTracksSelected(playerId, timeline, mediaPeriodId, renderers, trackGroups, trackSelections)
}

override fun shouldStartPlayback(
timeline: Timeline,
mediaPeriodId: MediaSource.MediaPeriodId,
bufferedDurationUs: Long,
playbackSpeed: Float,
rebuffering: Boolean,
targetLiveOffsetUs: Long
): Boolean {
return defaultLoadControl.shouldStartPlayback(timeline, mediaPeriodId, bufferedDurationUs, playbackSpeed, rebuffering, targetLiveOffsetUs)
override fun shouldStartPlayback(parameters: LoadControl.Parameters): Boolean {
return defaultLoadControl.shouldStartPlayback(parameters)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ object PillarboxNotificationManager {
override fun build(): PlayerNotificationManager {
val notificationManager = super.build()
mediaSession?.let {
notificationManager.setMediaSessionToken(it.sessionCompatToken)
notificationManager.setMediaSessionToken(it.platformToken)
}
return notificationManager
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ abstract class PlaybackService : Service() {
}
mediaSession?.let {
it.player = player
notificationManager.setMediaSessionToken(it.sessionCompatToken)
notificationManager.setMediaSessionToken(it.platformToken)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import androidx.media3.session.MediaController
import androidx.media3.session.MediaSessionService
import androidx.media3.session.SessionCommand
import androidx.media3.session.SessionCommands
import androidx.media3.session.SessionError
import androidx.media3.session.SessionResult
import androidx.media3.session.SessionToken
import ch.srgssr.pillarbox.player.PillarboxPlayer
Expand Down Expand Up @@ -113,7 +114,7 @@ open class PillarboxMediaController internal constructor() : PillarboxPlayer {
command: SessionCommand,
args: Bundle
): ListenableFuture<SessionResult> {
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
return Futures.immediateFuture(SessionResult(SessionError.ERROR_NOT_SUPPORTED))
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ package ch.srgssr.pillarbox.player.session
import android.app.PendingIntent
import androidx.annotation.IntRange
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import androidx.media3.session.LibraryResult
import androidx.media3.session.MediaLibraryService
import androidx.media3.session.MediaLibraryService.MediaLibrarySession
import androidx.media3.session.MediaSession
import androidx.media3.session.SessionError
import ch.srgssr.pillarbox.player.PillarboxPlayer
import ch.srgssr.pillarbox.player.session.PillarboxMediaLibrarySession.Builder
import ch.srgssr.pillarbox.player.utils.PendingIntentUtils
Expand Down Expand Up @@ -48,7 +48,7 @@ open class PillarboxMediaLibrarySession internal constructor() : PillarboxMediaS
browser: MediaSession.ControllerInfo,
params: MediaLibraryService.LibraryParams?,
): ListenableFuture<LibraryResult<MediaItem>> {
return Futures.immediateFuture(LibraryResult.ofError(LibraryResult.RESULT_ERROR_NOT_SUPPORTED))
return Futures.immediateFuture(LibraryResult.ofError(SessionError.ERROR_NOT_SUPPORTED))
}

/**
Expand All @@ -63,7 +63,7 @@ open class PillarboxMediaLibrarySession internal constructor() : PillarboxMediaS
@IntRange(from = 1) pageSize: Int,
params: MediaLibraryService.LibraryParams?,
): ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> {
return Futures.immediateFuture(LibraryResult.ofError(LibraryResult.RESULT_ERROR_NOT_SUPPORTED))
return Futures.immediateFuture(LibraryResult.ofError(SessionError.ERROR_NOT_SUPPORTED))
}

/**
Expand All @@ -75,7 +75,7 @@ open class PillarboxMediaLibrarySession internal constructor() : PillarboxMediaS
browser: MediaSession.ControllerInfo,
mediaId: String
): ListenableFuture<LibraryResult<MediaItem>> {
return Futures.immediateFuture(LibraryResult.ofError(LibraryResult.RESULT_ERROR_NOT_SUPPORTED))
return Futures.immediateFuture(LibraryResult.ofError(SessionError.ERROR_NOT_SUPPORTED))
}

/**
Expand All @@ -88,7 +88,7 @@ open class PillarboxMediaLibrarySession internal constructor() : PillarboxMediaS
query: String,
params: MediaLibraryService.LibraryParams?
): ListenableFuture<LibraryResult<Void>> {
return Futures.immediateFuture(LibraryResult.ofError(LibraryResult.RESULT_ERROR_NOT_SUPPORTED))
return Futures.immediateFuture(LibraryResult.ofError(SessionError.ERROR_NOT_SUPPORTED))
}

/**
Expand All @@ -103,7 +103,7 @@ open class PillarboxMediaLibrarySession internal constructor() : PillarboxMediaS
pageSize: Int,
params: MediaLibraryService.LibraryParams?
): ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> {
return Futures.immediateFuture(LibraryResult.ofError(LibraryResult.RESULT_ERROR_NOT_SUPPORTED))
return Futures.immediateFuture(LibraryResult.ofError(SessionError.ERROR_NOT_SUPPORTED))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ package ch.srgssr.pillarbox.player.session
import android.app.PendingIntent
import android.content.Context
import android.os.Bundle
import android.support.v4.media.session.MediaSessionCompat
import androidx.media3.common.MediaItem
import androidx.media3.common.util.Util
import androidx.media3.session.MediaLibraryService
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSession.MediaItemsWithStartPosition
import androidx.media3.session.SessionCommand
import androidx.media3.session.SessionCommands
import androidx.media3.session.SessionError
import androidx.media3.session.SessionResult
import ch.srgssr.pillarbox.player.PillarboxPlayer
import ch.srgssr.pillarbox.player.asset.timeRange.BlockedTimeRange
Expand Down Expand Up @@ -145,11 +145,11 @@ open class PillarboxMediaSession internal constructor() {
}

/**
* @see MediaSession.getSessionCompatToken
* @see MediaSession.getPlatformToken
*/
val token: MediaSessionCompat.Token
val token: android.media.session.MediaSession.Token
get() {
return _mediaSession.sessionCompatToken
return _mediaSession.platformToken
}

/**
Expand Down Expand Up @@ -288,7 +288,7 @@ open class PillarboxMediaSession internal constructor() {
}
}
DebugLogger.warning(TAG, "Unsupported session command ${customCommand.customAction}")
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
return Futures.immediateFuture(SessionResult(SessionError.ERROR_NOT_SUPPORTED))
}

override fun onSetMediaItems(
Expand Down
Loading
Loading