diff --git a/android/app/src/main/java/com/audiobookshelf/app/data/PlaybackSession.kt b/android/app/src/main/java/com/audiobookshelf/app/data/PlaybackSession.kt index 288af33b..8b08823a 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/data/PlaybackSession.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/data/PlaybackSession.kt @@ -182,7 +182,7 @@ class PlaybackSession( } @JsonIgnore - fun getExoMediaMetadata(audioTrack:AudioTrack): MediaMetadata { + fun getExoMediaMetadata(): MediaMetadata { val metadataBuilder = MediaMetadata.Builder() .setTitle(displayTitle) .setDisplayTitle(displayTitle) @@ -192,9 +192,7 @@ class PlaybackSession( .setAlbumTitle(displayAuthor) .setDescription(displayAuthor) .setArtworkUri(getCoverUri()) - - val contentUri = this.getContentUri(audioTrack) - metadataBuilder.setMediaUri(contentUri) + .setMediaType(MediaMetadata.MEDIA_TYPE_AUDIO_BOOK) return metadataBuilder.build() } @@ -204,7 +202,7 @@ class PlaybackSession( val mediaItems:MutableList = mutableListOf() for (audioTrack in audioTracks) { - val mediaMetadata = this.getExoMediaMetadata(audioTrack) + val mediaMetadata = this.getExoMediaMetadata() val mediaUri = this.getContentUri(audioTrack) val mimeType = audioTrack.mimeType diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/CastManager.kt b/android/app/src/main/java/com/audiobookshelf/app/player/CastManager.kt index 1d2215ae..9b3356b6 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/CastManager.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/CastManager.kt @@ -123,7 +123,7 @@ class CastManager constructor(val mainActivity:Activity) { } fun startRouteScan(connListener:ChromecastListener) { - var callback = object : ScanCallback() { + val callback = object : ScanCallback() { override fun onRouteUpdate(routes: List?) { Log.d(tag, "CAST On ROUTE UPDATED ${routes?.size} | ${getContext().castState}") // if the routes have changed, we may have an available device @@ -136,7 +136,7 @@ class CastManager constructor(val mainActivity:Activity) { // Let the client know a receiver is available connListener.onReceiverAvailableUpdate(true) // Since we have a receiver we may also have an active session - var session = getSessionManager()?.currentCastSession + val session = getSessionManager()?.currentCastSession // If we do have a session if (session != null) { // Let the client know @@ -246,15 +246,15 @@ class CastManager constructor(val mainActivity:Activity) { onRouteUpdate(outRoutes) } - override fun onRouteAdded(router: MediaRouter?, route: MediaRouter.RouteInfo?) { + override fun onRouteAdded(router: MediaRouter, route: MediaRouter.RouteInfo) { onFilteredRouteUpdate() } - override fun onRouteChanged(router: MediaRouter?, route: MediaRouter.RouteInfo?) { + override fun onRouteChanged(router: MediaRouter, route: MediaRouter.RouteInfo) { onFilteredRouteUpdate() } - override fun onRouteRemoved(router: MediaRouter?, route: MediaRouter.RouteInfo?) { + override fun onRouteRemoved(router: MediaRouter, route: MediaRouter.RouteInfo) { onFilteredRouteUpdate() } } diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt b/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt index b876344a..b1aae56b 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt @@ -11,12 +11,12 @@ import com.google.android.exoplayer2.* import com.google.android.exoplayer2.C.TrackType import com.google.android.exoplayer2.MediaMetadata import com.google.android.exoplayer2.Player.* -import com.google.android.exoplayer2.TracksInfo.TrackGroupInfo +import com.google.android.exoplayer2.Tracks.Group import com.google.android.exoplayer2.audio.AudioAttributes import com.google.android.exoplayer2.ext.cast.SessionAvailabilityListener import com.google.android.exoplayer2.source.TrackGroup import com.google.android.exoplayer2.source.TrackGroupArray -import com.google.android.exoplayer2.text.Cue +import com.google.android.exoplayer2.text.CueGroup import com.google.android.exoplayer2.trackselection.TrackSelection import com.google.android.exoplayer2.trackselection.TrackSelectionArray import com.google.android.exoplayer2.trackselection.TrackSelectionParameters @@ -49,7 +49,7 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { private var myPlayWhenReady:Boolean = false private var playbackParameters:PlaybackParameters = PlaybackParameters.DEFAULT private var myAvailableCommands: Commands - private var myCurrentTracksInfo: TracksInfo + private var myCurrentTracksInfo: Tracks private var myCurrentTrackGroups: TrackGroupArray private var myCurrentTrackSelections: TrackSelectionArray @@ -76,7 +76,7 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { COMMAND_GET_MEDIA_ITEMS_METADATA, COMMAND_SET_MEDIA_ITEMS_METADATA, COMMAND_CHANGE_MEDIA_ITEMS, - COMMAND_GET_TRACK_INFOS) + COMMAND_GET_TRACKS) .build() var currentPlaybackState = Player.STATE_IDLE @@ -95,7 +95,7 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { Log.d(tag, "Init CastPlayer") myCurrentTrackGroups = TrackGroupArray.EMPTY myCurrentTrackSelections = EMPTY_TRACK_SELECTION_ARRAY - myCurrentTracksInfo = TracksInfo.EMPTY + myCurrentTracksInfo = Tracks.EMPTY statusListener = StatusListener() timelineTracker = CastTimelineTracker() myCurrentTimeline = CastTimeline.EMPTY_CAST_TIMELINE @@ -385,7 +385,7 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { } if (updateTracksAndSelectionsAndNotifyIfChanged()) { listeners.queueEvent( - EVENT_TRACKS_CHANGED) { listener: Listener -> listener.onTracksInfoChanged(currentTracksInfo) } + EVENT_TRACKS_CHANGED) { listener: Listener -> listener.onTracksChanged(currentTracks) } } updateAvailableCommandsAndNotifyIfChanged() listeners.flushEvents() @@ -405,7 +405,7 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { val hasChanged = !myCurrentTrackGroups.isEmpty myCurrentTrackGroups = TrackGroupArray.EMPTY myCurrentTrackSelections = EMPTY_TRACK_SELECTION_ARRAY - myCurrentTracksInfo = TracksInfo.EMPTY + myCurrentTracksInfo = Tracks.EMPTY return hasChanged } var activeTrackIds = mediaStatus.activeTrackIds @@ -414,7 +414,7 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { } val trackGroups = arrayOfNulls(castMediaTracks.size) val trackSelections = arrayOfNulls(RENDERER_COUNT) - val trackGroupInfos = arrayOfNulls(castMediaTracks.size) + val trackGroupInfos = arrayOfNulls(castMediaTracks.size) for (i in castMediaTracks.indices) { val mediaTrack = castMediaTracks[i] trackGroups[i] = TrackGroup( /* id= */i.toString(), mediaTrackToFormat(mediaTrack)) @@ -428,18 +428,16 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { } val trackSupport = intArrayOf(if (supported) C.FORMAT_HANDLED else C.FORMAT_UNSUPPORTED_TYPE) val trackSelected = booleanArrayOf(selected) - trackGroupInfos[i] = TrackGroupInfo(trackGroups[i]!!, trackSupport, trackType, trackSelected) + trackGroupInfos[i] = Group(trackGroups[i]!!, false, trackSupport, trackSelected) } val tg = trackGroups.filterNotNull().toTypedArray() - var ts = trackSelections.filterNotNull().toTypedArray() - var tgi = trackGroupInfos.filterNotNull().toMutableList() + val ts = trackSelections.filterNotNull().toTypedArray() + val tgi = trackGroupInfos.filterNotNull().toMutableList() val newTrackGroups = TrackGroupArray(*tg) val newTrackSelections = TrackSelectionArray(*ts) - val newTracksInfo = TracksInfo(tgi) - if (newTrackGroups != currentTrackGroups - || newTrackSelections != currentTrackSelections - || newTracksInfo != currentTracksInfo) { + val newTracksInfo = Tracks(tgi) + if (newTracksInfo != currentTracks) { myCurrentTrackSelections = newTrackSelections myCurrentTrackGroups = newTrackGroups myCurrentTracksInfo = newTracksInfo @@ -593,7 +591,7 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { listeners.flushEvents() val pendingResult: PendingResult = if (playWhenReady) remoteMediaClient!!.play() else remoteMediaClient!!.pause() - var resultCb = ResultCallback { + val resultCb = ResultCallback { updatePlayerStateAndNotifyIfChanged() } @@ -622,10 +620,10 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { return false } - override fun seekTo(mediaItemIndex: Int, positionMs: Long) { + override fun seekTo(mediaItemIndex: Int, positionMs: Long, seekCommand: Int, isRepeatingCurrentItem: Boolean) { Log.d(tag, "seekTo $mediaItemIndex position $positionMs") - var resultCb = ResultCallback { + val resultCb = ResultCallback { val statusCode: Int = it.status.statusCode if (statusCode != CastStatusCodes.SUCCESS && statusCode != CastStatusCodes.REPLACED) { Log.e(tag, "Seek failed. Error code $statusCode") @@ -645,14 +643,14 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { // We assume the default position is 0. There is no support for seeking to the default position // in RemoteMediaClient. - var positionMsFinal = if (positionMs != C.TIME_UNSET) positionMs else 0 + val positionMsFinal = if (positionMs != C.TIME_UNSET) positionMs else 0 if (mediaStatus != null) { if (currentMediaItemIndex != mediaItemIndex) { Log.d(tag, "seekTo: Changing media item index from $currentMediaItemIndex to $mediaItemIndex") remoteMediaClient?.queueJumpToItem(myCurrentTimeline.getPeriod(mediaItemIndex, period).uid as Int, positionMsFinal, JSONObject())?.setResultCallback(resultCb) } else { Log.d(tag, "seekTo: Same media index seek to position $positionMsFinal") - var mediaSeekOptions = MediaSeekOptions.Builder().setPosition(positionMsFinal).build() + val mediaSeekOptions = MediaSeekOptions.Builder().setPosition(positionMsFinal).build() remoteMediaClient?.seek(mediaSeekOptions)?.setResultCallback(resultCb) } val oldPosition = getCurrentPositionInfo() @@ -709,7 +707,7 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { val pendingResult: PendingResult? = remoteMediaClient?.setPlaybackRate(actualPlaybackParameters.speed.toDouble(), /* customData= */null) - var resultCb = ResultCallback { + val resultCb = ResultCallback { updatePlaybackRateAndNotifyIfChanged() listeners.flushEvents() } @@ -736,15 +734,7 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { sessionManager.endCurrentSession(false) } - override fun getCurrentTrackGroups(): TrackGroupArray { - return this.myCurrentTrackGroups - } - - override fun getCurrentTrackSelections(): TrackSelectionArray { - return this.myCurrentTrackSelections - } - - override fun getCurrentTracksInfo(): TracksInfo { + override fun getCurrentTracks(): Tracks { return this.myCurrentTracksInfo } @@ -858,8 +848,12 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { return VideoSize.UNKNOWN } - override fun getCurrentCues(): MutableList { - return mutableListOf() + override fun getSurfaceSize(): Size { + return Size.UNKNOWN + } + + override fun getCurrentCues(): CueGroup { + return CueGroup.EMPTY_TIME_ZERO } override fun getDeviceInfo(): DeviceInfo { diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt index 0e6d8c90..b62be5bb 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt @@ -264,7 +264,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { playerNotificationManager.setUseNextAction(false) playerNotificationManager.setUsePreviousAction(false) playerNotificationManager.setUseChronometer(false) - playerNotificationManager.setUseStopAction(true) + playerNotificationManager.setUseStopAction(false) playerNotificationManager.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) playerNotificationManager.setPriority(NotificationCompat.PRIORITY_MAX) playerNotificationManager.setUseFastForwardActionInCompactView(true) diff --git a/android/variables.gradle b/android/variables.gradle index a7a3183a..f3aad7ec 100644 --- a/android/variables.gradle +++ b/android/variables.gradle @@ -1,7 +1,7 @@ ext { minSdkVersion = 24 compileSdkVersion = 33 - targetSdkVersion = 32 + targetSdkVersion = 33 androidxActivityVersion = '1.4.0' androidxAppCompatVersion = '1.4.2' androidxCoordinatorLayoutVersion = '1.2.0' @@ -20,7 +20,7 @@ ext { arch_lifecycle_version = '2.2.0' constraint_layout_version = '2.0.1' espresso_version = '3.3.0' - exoplayer_version = '2.17.0' + exoplayer_version = '2.18.7' fragment_version = '1.2.5' glide_version = '4.11.0' gms_strict_version_matcher_version = '1.0.3'