仅使用ExoPlayer的控制器在Android中播放音频,而无需黑色预览

如何解决仅使用ExoPlayer的控制器在Android中播放音频,而无需黑色预览

我想在android中播放音频文件列表。如您所知,当拥有视频文件时,使用com.google.android.exoplayer2.ui.PlayerView确实有意义,因为在底部具有播放/暂停等控制器的同时,您可以在屏幕上看到视频的内容。 但是对于音频文件,如果您播放音频文件,则会出现黑屏。 我需要的是只使用没有黑屏的控制器。

有办法吗?

第一个 EDIT : 在文档中,我遇到了PlaybackControlViewPlayerControlView。我可以根据情况使用它们吗?如果是,请使用哪个?

第二次编辑:这是经过1天研究的结果。我在布局中使用了PlaybackControlView,如下所示:

<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" />

从上面的布局中您可能会看到,我为此使用了一个自定义布局,称为custom_playback_control_view.xml。这是我的自定义布局内容:

<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>

最后但并非最不重要的一点,我在片段中将ExoPlayer附加到PlaybackControlView上:

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

解决方法

尝试创建这样的自定义控制器,并将其命名为media_controller.xml。我在数据仓库中使用了数据绑定

<?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>

接下来,像下面这样创建自定义类ExpoMediaController.java

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);
        }
    }
}}

在活动布局中使用ExpoMediaController替换com.google.android.exoplayer2.ui.PlaybackControlView。然后调用ExpoMediaController的setPlayer方法。现在,您可以完全控制控制器视图。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?