androidx / androidx/media

Add forwarding player with simplified extension points that ensure consistency (e.g. ForwardingSimpleBasePlayer)

Open
#1,183 3 comments 4 reactions 1 assignee View on GitHub

@tonihei is already working on this.

Since Mar 14, 2024.

enhancement
Dominant language
Java
Stars
3k
Forks
955
Avg merge
12d 14h
Merged PRs (30d)
2

Description

I have a similar issue to the one described here.

Based on the data I have in MediaMetadata I want to have control whether COMMAND_SEEK_TO_NEXT is available or not.

To reproduce issue from demo application, I altered data in catalog.json from demos/session_service and changed artist for few media items to empty strings in Electronic category. Then I wrapped ExoPlayer with ForwardingPlayer in DemoPlaybackService

val player = object : ForwardingPlayer(ExoPlayer.Builder(this)
        .setAudioAttributes(AudioAttributes.DEFAULT, /* handleAudioFocus= */ true)
        .build()
        .apply {
            addAnalyticsListener(EventLogger())
        }) {

    override fun getAvailableCommands(): Player.Commands {
        return super.getAvailableCommands().buildUpon().apply {
            if (currentMediaItem?.mediaMetadata?.artist?.isNotBlank() == true) {
                add(COMMAND_SEEK_TO_NEXT)
            } else {
                remove(COMMAND_SEEK_TO_NEXT)
            }
        }.build()
    }

    override fun isCommandAvailable(command: Int): Boolean {
        if (command == Player.COMMAND_SEEK_TO_NEXT) {
            return currentMediaItem?.mediaMetadata?.artist?.isNotBlank() == true
        }
        return super.isCommandAvailable(command)
    }
}

When I run the code, ExoPlayer in PlayerActivity displays that exo_next button is always available, even though when I click this button it sets some strange state in the player (no progress, old media item still plays).

But, when I add exactly the same code to the PlayerActivity

playerView.player = object : ForwardingPlayer(controller) {

  override fun getAvailableCommands(): Player.Commands {
    return super.getAvailableCommands().buildUpon().apply {
      if (currentMediaItem?.mediaMetadata?.artist?.isNotBlank() == true) {
        add(COMMAND_SEEK_TO_NEXT)
      } else {
        remove(COMMAND_SEEK_TO_NEXT)
      }
    }.build()
  }

  override fun isCommandAvailable(command: Int): Boolean {
    if (command == Player.COMMAND_SEEK_TO_NEXT) {
      return currentMediaItem?.mediaMetadata?.artist?.isNotBlank() == true
    }
    return super.isCommandAvailable(command)
  }
}

exo_next button displays state correctly.

With this info I have few questions:

  1. Why does that happen? Shouldn't MediaController respect what's inside ForwardingPlayer to be correctly shown in the playerView.player?
  2. Why media controller on the notification is still able to seekToNext? This one is strange, because in my application overriding those methods in our implementation of Player interface is enough to control the behaviour of media notification.
  3. How to wrap ExoPlayer in only one place (service) to get it work correctly?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.