androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
https://developer.android.com/media/media3
Apache License 2.0
1.62k stars 384 forks source link

PlayerControlView #651

Open rbinek opened 1 year ago

rbinek commented 1 year ago

Based on https://developer.android.com/guide/topics/media/session/mediasessionservice I can play music using the controller from notification. But when I added androidx.media3.ui.PlayerControlView to main activity it doesn't synchronize with media status. How to use/connect PlayerControlView to the player ?

yuroyami commented 1 year ago

You're not supposed to use PlayerControlView. It is already implemented under the hood when you use the PlayerView instead :

<androidx.media3.ui.PlayerView
        android:id="@+id/exoview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000000"
        app:keep_content_on_player_reset="true"
        app:show_shuffle_button="false"
        app:show_buffering="always"
        app:show_vr_button="true"
        app:show_subtitle_button="true"
        app:controller_layout_id="@layout/custom_exo_ui"
        app:shutter_background_color="#000000"
        app:surface_type="surface_view"
        app:use_artwork="false"
        app:use_controller="true" />

After that, when you build your ExoPlayer in code and obtain a Player, you can set your xml's PlayerView to use that created exoplayer instance, like this:

/* Building exoplayer code here */
val YOUR_CREATED_PLAYER_INSTANCE = ExoPlayer.Builder(this)
         .build()

//Using the conventional findViewById
findViewById(R.id.exoview)?.player = YOUR_CREATED_PLAYER_INSTANCE
//or using viewbinding
binding.exoview.player = YOUR_CREATED_PLAYER_INSTANCE

Also, if you want your UI to use the same player that is used inside your MediaSessionService, you're supposed to create a MediaController and link it with your session in your service. This MediaController contains the player that is used in notifications and you can also set it to your PlayerView.

marcbaechinger commented 1 year ago

As explained above, PlayerControlView is not supposed to be used directly. Use PlayerView instead that gives you a setPlayer(Player) method.

MediaController implements the Player interface and hence can be used where ever a Player interface is required.

rbinek commented 1 year ago

Thanks for reply. But I have some problem to get it works. my MainActivity:

class MainActivity : AppCompatActivity() {

    private var playerView: PlayerView? = null

    private lateinit var controllerFuture: ListenableFuture<MediaController>
    private lateinit var controller: MediaController

    @UnstableApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        playerView = findViewById(R.id.player_view)
    }

    @UnstableApi
    override fun onStart() {
        super.onStart()
        val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java))
        controllerFuture = MediaController.Builder(this, sessionToken).buildAsync()
        controllerFuture.addListener(
            {
                controller = controllerFuture.get()
                playerView?.player = controller
                controller.addMediaItems(loadData())
            },
            MoreExecutors.directExecutor()
        )
    }

activity_main.xml:

 <androidx.media3.ui.PlayerView
        android:id="@+id/player_view"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        app:hide_on_touch="false"
        app:auto_show="true"
        app:use_controller="true" />

Using this activity there is only one button play or pause based on the state of the player. The play and pause button work ok. When I change activity_main to:

    <androidx.media3.ui.PlayerView
        android:id="@+id/player_view"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        app:hide_on_touch="false"
        app:auto_show="true"
        app:player_layout_id="@layout/custom_ui"
        app:use_controller="true" />

I see play and pause button simultaneously. When I push play nothing happens. What is wrong ?

rbinek commented 1 year ago

any suggestion ?

marcbaechinger commented 1 year ago

But when I added androidx.media3.ui.PlayerControlView to main activity it doesn't synchronize with media status.

It looks to me this works in the session demo app and I heaven't heard complains that this isn't generally working. I think you need to dig a bit on your end to get that working.

We can't really review app code I'm afraid. Please consult the docs around using a MediaController and the PlayerView. If you think this is a library problem then please narrow down the problem to a reproducible test fixture and provide reproduction steps, so we can look into this.