Search code examples
androidexoplayerexoplayer2.x

How to place the controls of an Exoplayer outside of the PlayerView


I'm using Exoplayer2 to show videos in my application. I need the controls to be visible at all time. I can archive this by setting app:show_timeout="0". But when the controls are always visible they take up space in the PlayerView.

I would like to show the controls beneath the PlayerView, so that I can always show to whole video.

This is my layout file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MediaPlayerActivity"
    android:theme="@android:style/Theme.NoTitleBar"
    android:contentDescription="hf_hide_help">

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/playerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:use_controller="true"
        app:rewind_increment="0"
        app:fastforward_increment="0"
        app:repeat_toggle_modes="none"
        app:show_timeout="0"
        />
</RelativeLayout>

And this is my exo_player_control_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:layoutDirection="ltr"
    android:background="#CC000000"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:paddingTop="4dp"
        android:orientation="horizontal">

        <ImageButton android:id="@id/exo_play"
            style="@style/ExoMediaButton.Play"/>

        <ImageButton android:id="@id/exo_pause"
            style="@style/ExoMediaButton.Pause"/>

        <TextView android:id="@id/exo_position"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textStyle="bold"
            android:paddingLeft="4dp"
            android:paddingRight="4dp"
            android:includeFontPadding="false"
            android:textColor="#FFBEBEBE"/>

        <com.google.android.exoplayer2.ui.DefaultTimeBar
            android:id="@id/exo_progress"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="26dp"/>

        <TextView android:id="@id/exo_duration"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textStyle="bold"
            android:paddingLeft="4dp"
            android:paddingRight="4dp"
            android:includeFontPadding="false"
            android:textColor="#FFBEBEBE"/>

    </LinearLayout>

</LinearLayout>

This is what it looks like: Player

And this is what it looks like, when I click on the player - the controls hide. Player without controls


Solution

  • Your use-case is not something general and ExoPlayer doesn't support it. In your case, you will need to disable the default controls and add your own custom controls beneath the player view. It would be very easy to build the layout and add the actions to them.

    Update: (To answer Gyan's comment about time-bar)

    Two approaches: (I explain the strategies since thousands of code examples are available already on SO and other sites)

    1 - My suggestion which has worked perfectly for my needs: override default controls view of the exoplayer (having a view with the same name in your layouts folder would do the job). Then remove all unnecessary buttons which you brought down in your custom view but just keep the time bar in overridden view. By doing that, all the appearing / disappearing behaviors are automatically kept for the time bar and you will have the rest in your own view. You wouldn't need to worry about handling the time bar if you liked that approach.

    2- Just in case you insist on bringing the time bar out under the player window, what you need is a horizontal progressbar (Notice that you can customize the look of progress view to match your design). Then write a listener on exoplayer to take the timings (passed / remaining / current play-time) and calculate and update the progress of the bar based upon them. Remember that the progress bar needs to be touchable (and focusable) so that the user could drag it back and forth. Then you would need to re-calculate playtime when user drags the progress. (lots of coding and calculations obviously but almost easy stuff). Hope it works for you. If you needed code samples please let me know.