Skip to content

Commit

Permalink
refactor: use skip/previous buttons from DefaultMediaNotificationProv…
Browse files Browse the repository at this point in the history
…ider
  • Loading branch information
Bnyro committed Dec 5, 2024
1 parent bd85503 commit 6947f89
Showing 1 changed file with 43 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,18 @@ import androidx.core.app.ServiceCompat
import androidx.core.os.bundleOf
import androidx.core.os.postDelayed
import androidx.media3.common.C
import androidx.media3.common.ForwardingPlayer
import androidx.media3.common.MediaMetadata
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
import androidx.media3.session.CommandButton
import androidx.media3.session.MediaLibraryService
import androidx.media3.session.MediaLibraryService.MediaLibrarySession
import androidx.media3.session.MediaSession
import androidx.media3.session.SessionCommand
import androidx.media3.session.SessionResult
import com.github.libretube.R
import com.github.libretube.api.obj.Subtitle
import com.github.libretube.constants.IntentData
import com.github.libretube.enums.PlayerCommand
Expand Down Expand Up @@ -261,19 +260,6 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
): MediaSession.ConnectionResult {
val connectionResult = super.onConnect(session, controller)

// Select the button to display.
val customLayout = listOf(
CommandButton.Builder()
.setDisplayName(getString(R.string.rewind))
.setSessionCommand(SessionCommand(PlayerEvent.Prev.name, Bundle.EMPTY))
.setIconResId(R.drawable.ic_prev_outlined)
.build(),
CommandButton.Builder()
.setDisplayName(getString(R.string.play_next))
.setSessionCommand(SessionCommand(PlayerEvent.Next.name, Bundle.EMPTY))
.setIconResId(R.drawable.ic_next_outlined)
.build(),
)
val mediaNotificationSessionCommands =
connectionResult.availableSessionCommands.buildUpon()
.also { builder ->
Expand All @@ -284,18 +270,17 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
stopServiceCommand
)
)
builder.addSessionCommands(customLayout.mapNotNull(CommandButton::sessionCommand))
}
.build()

val playerCommands = connectionResult.availablePlayerCommands.buildUpon()
.remove(Player.COMMAND_SEEK_TO_PREVIOUS)
.add(Player.COMMAND_SEEK_TO_NEXT)
.add(Player.COMMAND_SEEK_TO_PREVIOUS)
.build()

return MediaSession.ConnectionResult.AcceptedResultBuilder(session)
.setAvailableSessionCommands(mediaNotificationSessionCommands)
.setAvailablePlayerCommands(playerCommands)
.setCustomLayout(customLayout)
.build()
}

Expand All @@ -318,7 +303,8 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio

PlayerHelper.setPreferredCodecs(trackSelector)

mediaLibrarySession = MediaLibrarySession.Builder(this, player, this)
val forwardingPlayer = MediaSessionForwarder(player)
mediaLibrarySession = MediaLibrarySession.Builder(this, forwardingPlayer, this)
.setId(this.javaClass.name)
.build()
}
Expand Down Expand Up @@ -347,16 +333,20 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
handlePlayerAction(PlayerEvent.Next)
return true
}

KeyEvent.KEYCODE_MEDIA_PREVIOUS -> {
handlePlayerAction(PlayerEvent.Prev)
return true
}

KeyEvent.KEYCODE_MEDIA_REWIND -> {
handlePlayerAction(PlayerEvent.Rewind)
}

KeyEvent.KEYCODE_MEDIA_FAST_FORWARD -> {
handlePlayerAction(PlayerEvent.Forward)
}

KeyEvent.KEYCODE_MEDIA_STOP -> {
handlePlayerAction(PlayerEvent.Stop)
}
Expand Down Expand Up @@ -406,6 +396,40 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
onDestroy()
}

/**
* [Player] wrapper that handles seeking actions (next/previous) itself instead of using the
* default [Player] implementation
*/
inner class MediaSessionForwarder(player: Player) : ForwardingPlayer(player) {
override fun hasNextMediaItem(): Boolean {
return PlayingQueue.hasNext()
}

override fun hasPreviousMediaItem(): Boolean {
return PlayingQueue.hasPrev()
}

override fun seekToPrevious() {
handlePlayerAction(PlayerEvent.Prev)
}

override fun seekToNext() {
handlePlayerAction(PlayerEvent.Next)
}

override fun getAvailableCommands(): Player.Commands {
return super.getAvailableCommands().buildUpon()
.addAll(Player.COMMAND_SEEK_TO_PREVIOUS, Player.COMMAND_SEEK_TO_NEXT)
.build()
}

override fun isCommandAvailable(command: Int): Boolean {
if (command == Player.COMMAND_SEEK_TO_NEXT || command == Player.COMMAND_SEEK_TO_PREVIOUS) return true

return super.isCommandAvailable(command)
}
}

companion object {
private const val START_SERVICE_ACTION = "start_service_action"
private const val STOP_SERVICE_ACTION = "stop_service_action"
Expand Down

0 comments on commit 6947f89

Please sign in to comment.