abdullah celik
abdullah celik

Reputation: 551

Use only ExoPlayer's controller for playing audio in Android without the black preview

I want to play a list of audio files in android. As you might know, when you have video files, using the com.google.android.exoplayer2.ui.PlayerView does make sense because you can see the content of the video on the screen while you have the controller for play/pause etc. on the bottom. But with audio files, you have a black screen if you let play the audio files. What I need is to use only the controller without the black screen.

Is there a way to do that ?

1st EDIT: In the documentation, I came across PlaybackControlView and PlayerControlView. Can I use them for my situation ? If yes, which one to use ?

2nd EDIT: Here are my results after 1 day of research. I used PlaybackControlView in my layout like this:

<com.google.android.exoplayer2.ui.PlaybackControlView
      android:id="@+id/play_back_control_view"
      android:layout_width="0dp"        <--- I use ConstraintLayout, so this is okay
      android:layout_height="wrap_content"
      android:background="@color/black"
      android:alpha="0.15"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintBottom_toBottomOf="parent"
      app:controller_layout_id="@layout/custom_playback_control_view" />

As you might see from the layout above, I use a custom layout for this called custom_playback_control_view.xml. Here is the my custom layout content:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/black"
    xmlns:tools="http://schemas.android.com/tools">

    <ImageButton
        android:id="@id/exo_play"
        style="@style/ExoMediaButton.Play"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="ContentDescription"/>

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

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="ContentDescription"/>

    <View
        android:id="@id/exo_progress_placeholder"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="26dp"

        app:layout_constraintEnd_toStartOf="@id/exo_duration"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toEndOf="@id/exo_play"/>

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

</androidx.constraintlayout.widget.ConstraintLayout>

Last but not least, I attached the ExoPlayer to the PlaybackControlView like this in my Fragment:

myAudioPlayer = ExoPlayerFactory.newSimpleInstance(context)
binding.playBackControlView.player = myAudioPlayer

Upvotes: 3

Views: 2740

Answers (1)

crack_head
crack_head

Reputation: 246

Try to create a custom controller like this and name it media_controller.xml. I used data binding in laout

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

<FrameLayout
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#44000000"
    android:focusableInTouchMode="false">

    <RelativeLayout
        android:id="@+id/controller"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="10dp">


        <ImageView
            android:id="@+id/play"
            android:layout_width="64dp"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:adjustViewBounds="true"
            android:padding="2dp"
            android:src="@mipmap/ic_media_play" />

        <ImageView
            android:id="@+id/forward"
            android:layout_width="64dp"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toEndOf="@id/play"
            android:adjustViewBounds="true"
            android:clickable="true"
            android:focusable="true"
            android:padding="6dp"
            android:src="@mipmap/ic_media_forward" />

        <ImageView
            android:id="@+id/backward"
            android:layout_width="64dp"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toStartOf="@id/play"
            android:adjustViewBounds="true"
            android:clickable="true"
            android:focusable="true"
            android:padding="6dp"
            android:src="@mipmap/ic_media_backward" />


    </RelativeLayout>


</FrameLayout>
</layout>

Next create a custom class ExpoMediaController.java like following

public class ExpoMediaController extends FrameLayout implements View.OnClickListener, Player.EventListener{
 private LayoutInflater inflater;
 Player simpleExoPlayer;

 private MediaControllerBinding binding;//media_controller.xml

public ExpoMediaController(Context context, AttributeSet attrs) {
    super(context, attrs);
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    initView();
}


public ExpoMediaController(Context context) {
    super(context);
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    initView();
}


private void initView() {
    binding = DataBindingUtil.inflate(inflater, R.layout.media_controller, this, true);
    binding.play.setOnClickListener(this);
    binding.forward.setOnClickListener(this);
    binding.backward.setOnClickListener(this);


}

//Use this method to set and unset the player
public void setPlayer(@Nullable Player simpleExoPlayer) {
    if (this.simpleExoPlayer == simpleExoPlayer) {
        return;
    }
    Player oldPlayer = this.simpleExoPlayer;//get reference of old player which attached previously
    if (oldPlayer != null) {//if old player not null then clear it
        oldPlayer.removeListener(this);
    }
    this.simpleExoPlayer = simpleExoPlayer;
    if (this.simpleExoPlayer != null) {
        this.simpleExoPlayer.addListener(this);
    }
}

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    switch (playbackState) {
        case STATE_BUFFERING:
            break;
        case STATE_ENDED:
            break;
        case STATE_IDLE:
            break;
        case STATE_READY:
            if (playWhenReady) {
                binding.play.setImageResource(R.mipmap.ic_media_pause);
                binding.play.setVisibility(VISIBLE);

            } else {
                binding.play.setImageResource(R.mipmap.ic_media_play);
                binding.play.setVisibility(VISIBLE);
            }
            break;
        default:
            break;
    }
}

@Override
public void onClick(View v) {
    if (v == binding.play && simpleExoPlayer != null) {
        if (simpleExoPlayer.isPlaying()) {
            simpleExoPlayer.setPlayWhenReady(false);
            showControls();
        } else {
            if (simpleExoPlayer.getPlaybackState() == STATE_ENDED) {
                simpleExoPlayer.seekTo(0);
            }
            simpleExoPlayer.setPlayWhenReady(true);
        }
    }
}}

Use ExpoMediaController in your activity layout replacing com.google.android.exoplayer2.ui.PlaybackControlView. Then call setPlayer method of ExpoMediaController. Now you have total control over controller view.

Upvotes: 1

Related Questions