Reputation: 551
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
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