Upgrade to media3-beta01

This commit is contained in:
Maxence G 2022-06-19 18:21:33 +02:00
parent 5deb7d4d58
commit 9961213f09
No known key found for this signature in database
GPG Key ID: DC1FD9409E3FE284
7 changed files with 32 additions and 55 deletions

View File

@ -10,7 +10,7 @@ ktlintGradle = "10.2.0"
detekt = "1.19.0" detekt = "1.19.0"
preferences = "1.1.1" preferences = "1.1.1"
media = "1.3.1" media = "1.3.1"
media3 = "1.0.0-alpha03" media3 = "1.0.0-beta01"
androidSupport = "28.0.0" androidSupport = "28.0.0"
androidLegacySupport = "1.0.0" androidLegacySupport = "1.0.0"
@ -101,4 +101,3 @@ kluentAndroid = { module = "org.amshove.kluent:kluent-android", versio
mockWebServer = { module = "com.squareup.okhttp3:mockwebserver", version.ref = "okhttp" } mockWebServer = { module = "com.squareup.okhttp3:mockwebserver", version.ref = "okhttp" }
apacheCodecs = { module = "commons-codec:commons-codec", version.ref = "apacheCodecs" } apacheCodecs = { module = "commons-codec:commons-codec", version.ref = "apacheCodecs" }
robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" } robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" }

View File

@ -67,6 +67,7 @@
<!-- Needs to be exported: https://android.googlesource.com/platform/developers/build/+/4de32d4/prebuilts/gradle/MediaBrowserService/README.md --> <!-- Needs to be exported: https://android.googlesource.com/platform/developers/build/+/4de32d4/prebuilts/gradle/MediaBrowserService/README.md -->
<service android:name=".playback.PlaybackService" <service android:name=".playback.PlaybackService"
android:label="@string/common.appname" android:label="@string/common.appname"
android:foregroundServiceType="mediaPlayback"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>

View File

@ -21,7 +21,6 @@ import androidx.media3.common.Player
import androidx.media3.session.LibraryResult import androidx.media3.session.LibraryResult
import androidx.media3.session.MediaLibraryService import androidx.media3.session.MediaLibraryService
import androidx.media3.session.MediaSession import androidx.media3.session.MediaSession
import androidx.media3.session.SessionResult
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
@ -89,7 +88,7 @@ private const val SEARCH_QUERY_PREFIX = "androidx://media3-session/setMediaUri"
*/ */
@Suppress("TooManyFunctions", "LargeClass", "UnusedPrivateMember") @Suppress("TooManyFunctions", "LargeClass", "UnusedPrivateMember")
class AutoMediaBrowserCallback(var player: Player) : class AutoMediaBrowserCallback(var player: Player) :
MediaLibraryService.MediaLibrarySession.MediaLibrarySessionCallback, KoinComponent { MediaLibraryService.MediaLibrarySession.Callback, KoinComponent {
private val mediaPlayerController by inject<MediaPlayerController>() private val mediaPlayerController by inject<MediaPlayerController>()
private val activeServerProvider: ActiveServerProvider by inject() private val activeServerProvider: ActiveServerProvider by inject()
@ -181,39 +180,19 @@ class AutoMediaBrowserCallback(var player: Player) :
return onLoadChildren(parentId) return onLoadChildren(parentId)
} }
private fun setMediaItemFromSearchQuery(query: String) { // https://stackoverflow.com/questions/70096715/adding-mediaitem-when-using-the-media3-library-caused-an-error
// Only accept query with pattern "play [Title]" or "[Title]" override fun onAddMediaItems(
// Where [Title]: must be exactly matched mediaSession: MediaSession,
// If no media with exact name found, play a random media instead
val mediaTitle =
if (query.startsWith("play ", ignoreCase = true)) {
query.drop(5)
} else {
query
}
playFromMediaId(mediaTitle)
}
override fun onSetMediaUri(
session: MediaSession,
controller: MediaSession.ControllerInfo, controller: MediaSession.ControllerInfo,
uri: Uri, mediaItems: MutableList<MediaItem>
extras: Bundle ): ListenableFuture<MutableList<MediaItem>> {
): Int {
if (uri.toString().startsWith(SEARCH_QUERY_PREFIX) || val updatedMediaItems = mediaItems.map { mediaItem ->
uri.toString().startsWith(SEARCH_QUERY_PREFIX_COMPAT) mediaItem.buildUpon()
) { .setUri(mediaItem.requestMetadata.mediaUri)
val searchQuery = .build()
uri.getQueryParameter("query")
?: return SessionResult.RESULT_ERROR_NOT_SUPPORTED
setMediaItemFromSearchQuery(searchQuery)
return SessionResult.RESULT_SUCCESS
} else {
return SessionResult.RESULT_ERROR_NOT_SUPPORTED
} }
return Futures.immediateFuture(updatedMediaItems.toMutableList())
} }
@Suppress("ReturnCount", "ComplexMethod") @Suppress("ReturnCount", "ComplexMethod")

View File

@ -50,7 +50,7 @@ class LegacyPlaylistManager : KoinComponent {
for (i in 0 until n) { for (i in 0 until n) {
val item = controller.getMediaItemAt(i) val item = controller.getMediaItemAt(i)
val file = mediaItemCache[item.mediaMetadata.mediaUri.toString()] val file = mediaItemCache[item.requestMetadata.toString()]
if (file != null) if (file != null)
_playlist.add(file) _playlist.add(file)
} }
@ -59,11 +59,11 @@ class LegacyPlaylistManager : KoinComponent {
} }
fun addToCache(item: MediaItem, file: DownloadFile) { fun addToCache(item: MediaItem, file: DownloadFile) {
mediaItemCache.put(item.mediaMetadata.mediaUri.toString(), file) mediaItemCache.put(item.requestMetadata.toString(), file)
} }
fun updateCurrentPlaying(item: MediaItem?) { fun updateCurrentPlaying(item: MediaItem?) {
currentPlaying = mediaItemCache[item?.mediaMetadata?.mediaUri.toString()] currentPlaying = mediaItemCache[item?.requestMetadata.toString()]
} }
@Synchronized @Synchronized

View File

@ -7,6 +7,7 @@
package org.moire.ultrasonic.playback package org.moire.ultrasonic.playback
/*
import android.app.Notification import android.app.Notification
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
@ -24,14 +25,17 @@ import androidx.media3.session.MediaController
import androidx.media3.session.MediaNotification import androidx.media3.session.MediaNotification
import androidx.media3.session.MediaNotification.ActionFactory import androidx.media3.session.MediaNotification.ActionFactory
import org.moire.ultrasonic.R import org.moire.ultrasonic.R
*/
/* /*
* This is a copy of DefaultMediaNotificationProvider.java with some small changes * This is a copy of DefaultMediaNotificationProvider.java with some small changes
* I have opened a bug https://github.com/androidx/media/issues/65 to make it easier to customize * I have opened a bug https://github.com/androidx/media/issues/65 to make it easier to customize
* the icons and actions without creating our own copy of this class.. * the icons and actions without creating our own copy of this class..
*/ */
@UnstableApi //@UnstableApi
/* package */ /* package */
// Disabled while getting updated
/*
internal class MediaNotificationProvider(context: Context) : internal class MediaNotificationProvider(context: Context) :
MediaNotification.Provider { MediaNotification.Provider {
private val context: Context = context.applicationContext private val context: Context = context.applicationContext
@ -148,3 +152,4 @@ internal class MediaNotificationProvider(context: Context) :
} }
} }
} }
*/

View File

@ -13,11 +13,11 @@ import androidx.media3.common.AudioAttributes
import androidx.media3.common.C import androidx.media3.common.C
import androidx.media3.common.C.CONTENT_TYPE_MUSIC import androidx.media3.common.C.CONTENT_TYPE_MUSIC
import androidx.media3.common.C.USAGE_MEDIA import androidx.media3.common.C.USAGE_MEDIA
import androidx.media3.common.MediaItem
import androidx.media3.datasource.DataSource import androidx.media3.datasource.DataSource
import androidx.media3.exoplayer.DefaultRenderersFactory import androidx.media3.exoplayer.DefaultRenderersFactory
import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
import androidx.media3.session.DefaultMediaNotificationProvider
import androidx.media3.session.MediaLibraryService import androidx.media3.session.MediaLibraryService
import androidx.media3.session.MediaSession import androidx.media3.session.MediaSession
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
@ -38,7 +38,7 @@ class PlaybackService : MediaLibraryService(), KoinComponent {
private lateinit var mediaLibrarySession: MediaLibrarySession private lateinit var mediaLibrarySession: MediaLibrarySession
private lateinit var apiDataSource: APIDataSource.Factory private lateinit var apiDataSource: APIDataSource.Factory
private lateinit var librarySessionCallback: MediaLibrarySession.MediaLibrarySessionCallback private lateinit var librarySessionCallback: MediaLibrarySession.Callback
private var rxBusSubscription = CompositeDisposable() private var rxBusSubscription = CompositeDisposable()
@ -48,18 +48,6 @@ class PlaybackService : MediaLibraryService(), KoinComponent {
* For some reason the LocalConfiguration of MediaItem are stripped somewhere in ExoPlayer, * For some reason the LocalConfiguration of MediaItem are stripped somewhere in ExoPlayer,
* and thereby customarily it is required to rebuild it.. * and thereby customarily it is required to rebuild it..
*/ */
private class CustomMediaItemFiller : MediaSession.MediaItemFiller {
override fun fillInLocalConfiguration(
session: MediaSession,
controller: MediaSession.ControllerInfo,
mediaItem: MediaItem
): MediaItem {
// Again, set the Uri, so that it will get a LocalConfiguration
return mediaItem.buildUpon()
.setUri(mediaItem.mediaMetadata.mediaUri)
.build()
}
}
override fun onCreate() { override fun onCreate() {
Timber.i("onCreate called") Timber.i("onCreate called")
@ -102,7 +90,7 @@ class PlaybackService : MediaLibraryService(), KoinComponent {
private fun initializeSessionAndPlayer() { private fun initializeSessionAndPlayer() {
if (isStarted) return if (isStarted) return
setMediaNotificationProvider(MediaNotificationProvider(UApp.applicationContext())) setMediaNotificationProvider(DefaultMediaNotificationProvider(UApp.applicationContext()))
val subsonicAPIClient: SubsonicAPIClient by inject() val subsonicAPIClient: SubsonicAPIClient by inject()
@ -134,7 +122,6 @@ class PlaybackService : MediaLibraryService(), KoinComponent {
// This will need to use the AutoCalls // This will need to use the AutoCalls
mediaLibrarySession = MediaLibrarySession.Builder(this, player, librarySessionCallback) mediaLibrarySession = MediaLibrarySession.Builder(this, player, librarySessionCallback)
.setMediaItemFiller(CustomMediaItemFiller())
.setSessionActivity(getPendingIntentForContent()) .setSessionActivity(getPendingIntentForContent())
.build() .build()

View File

@ -659,16 +659,22 @@ fun Track.toMediaItem(): MediaItem {
val bitrate = Settings.maxBitRate val bitrate = Settings.maxBitRate
val uri = "$id|$bitrate|$filePath" val uri = "$id|$bitrate|$filePath"
val rmd = MediaItem.RequestMetadata.Builder()
.setMediaUri(uri.toUri())
.build()
val metadata = MediaMetadata.Builder() val metadata = MediaMetadata.Builder()
metadata.setTitle(title) metadata.setTitle(title)
.setArtist(artist) .setArtist(artist)
.setAlbumTitle(album) .setAlbumTitle(album)
.setMediaUri(uri.toUri())
.setAlbumArtist(artist) .setAlbumArtist(artist)
.build()
val mediaItem = MediaItem.Builder() val mediaItem = MediaItem.Builder()
.setUri(uri) .setUri(uri)
.setMediaId(id) .setMediaId(id)
.setRequestMetadata(rmd)
.setMediaMetadata(metadata.build()) .setMediaMetadata(metadata.build())
return mediaItem.build() return mediaItem.build()