Search code examples
kotlinexoplayer2.x

Exoplayer don't show controller on play/pause


I want to implement mediaKeyEvents in my Exoplayer for usage on TVs.

For now I have a working setup:

override fun onCreate(savedInstanceState: Bundle?) {
...
    //Don't show controller on start
    viewBinding.playerView.controllerAutoShow = false
...
}

override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        when (keyCode) {
            KeyEvent.KEYCODE_MEDIA_PLAY -> {
                if (viewBinding.playerView.player!!.isPlaying) {
                    viewBinding.playerView.player!!.pause()
                } else {
                    viewBinding.playerView.player!!.play()
                }
                return true
            }
            KeyEvent.KEYCODE_DPAD_RIGHT -> {
                viewBinding.playerView.player!!.seekForward()
                return true
            }
            KeyEvent.KEYCODE_DPAD_LEFT -> {
                viewBinding.playerView.player!!.seekBack()
                return true
            }
        }
        return super.onKeyDown(keyCode, event)
    }

The TV controlls that matter the most to me are those for the Nvidia Shield Pro Controller.

The issue: in this setup, the controller shows whenever I play/pause. I have tried to disable the controller, and then the seek back/forward works, however, the play/pause stops working (additionally, I would like to keep the controller, just hidden).

Desired behaviour:

Something like plex or youtube, where these actions occur:

Actions that don't show the controller:

  • Play/pause
  • Seek back/forward

Actions that show the controller:

  • dpad down to show controller if not active
  • dpad up to hide controler if active

My ExoPlayer layout:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true">

    <com.google.android.exoplayer2.ui.StyledPlayerView
        android:id="@+id/player_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:keepScreenOn="true"
        app:show_shuffle_button="false"
        app:show_subtitle_button="true" />

    <LinearLayout
        android:id="@+id/controls_root"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:visibility="gone">

        <Button
            android:id="@+id/select_tracks_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:enabled="false"
            android:text="TEST" />

    </LinearLayout>

</FrameLayout>

Solution

  • I found the solution, I shouldn't use the onKeyDown, but rather the :

        @SuppressLint("RestrictedApi")
        override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
            if (event?.action == KeyEvent.ACTION_DOWN) {
                when (event?.keyCode) {
                    KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> {
                        if (viewBinding.playerView.player!!.isPlaying) {
                            viewBinding.playerView.player!!.pause()
                        } else {
                            viewBinding.playerView.player!!.play()
                        }
                        return true
                    }
                    KeyEvent.KEYCODE_DPAD_RIGHT -> {
                        viewBinding.playerView.player!!.seekForward()
                        return true
                    }
                    KeyEvent.KEYCODE_DPAD_LEFT -> {
                        viewBinding.playerView.player!!.seekBack()
                        return true
                    }
                }
            }
    
    
            return false
        }
    

    Small note if you copy paste: This will remove all of the other keybinds as well, because I would love to program the back button as well to close the controller if open and else go back.