Exoplayer示例中的自定义UI

23

我想为我的Exoplayer播放器编写自定义UI(例如更改暂停播放按钮的图标或添加新按钮,如速度控制、下一曲等)。

我使用了来自Github的Exoplayer示例,在将代码添加到我的原始项目之前,我想在官方示例上测试自定义UI。

我在Stackoverflow和tuts+中阅读了有关自定义UI的页面,但我感到非常困惑!

为什么更改一些按钮的图像或更改它们的位置会这么困难 :) 我怎么才能处理好这个问题呢?

编辑

这是示例 https://github.com/google/ExoPlayer/tree/master/demo

我阅读了以下两篇文章:

http://www.brightec.co.uk/ideas/custom-android-media-controller

http://code.tutsplus.com/tutorials/create-a-music-player-on-android-user-controls--mobile-22787

根据此链接,“您可以从包含在Android中的MediaController类开始,而不是从头编写自己的媒体控制器”,我问这个问题是因为我无法在Exoplayer库上执行这些步骤,而该教程是针对默认媒体播放器编写的。


请更详细地解释您的问题。 您尝试了什么? 查看您代码中必要的部分会很有帮助。 - Christopher
@Christopher,我编辑了帖子。主要问题是我无法尝试任何东西,因为Exoplayer库非常复杂 :) 我不知道在哪里进行编辑和覆盖。我像我之前提到的那样在示例上尝试。 - Siavash Abdoli
我认为你只需要更改https://github.com/google/ExoPlayer/blob/master/demo/src/main/res/layout/player_activity.xml。 - Christopher
@Christopher 不是播放器和其他控制器在代码中实现,它们设置在这里: mediaController = new MediaController(this); mediaController.setAnchorView(root); 虽然我不是高级开发人员,但在过去的两年中,我已经开发了一些好用且简单的应用程序 :) 它确实很复杂,有些人给我负面评价,让我感到非常生气。 - Siavash Abdoli
@Christopher 谢谢你的评论和尝试帮助 :) - Siavash Abdoli
3个回答

39

自定义ExoPlayer的UI非常简单。如果您查看ExoPlayer源代码,布局资源目录包含指向(包括)另一个布局的文件exo_player_control_view.xml - exo_playback_control_view

  1. 复制布局资源exo_playback_control_view.xml的内容
  2. 创建一个自己喜欢的名称的布局资源文件,例如:custom_exo_playback_control_view.xml,将复制的内容粘贴到新的xml文件中
  3. 根据需要更改UI小部件。不要更改任何小部件/控件的Id属性
  4. 在包含PlayerView的布局文件中指向自定义的ExoPlayer UI资源

这是我从原始代码创建的custom_exo_controller_view xml。我想为播放器控件设置不同的背景颜色和不同的按钮和进度条视图颜色:

<LinearLayout 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="wrap_content"
    android:layout_gravity="bottom"
    android:background="@drawable/attachment_document_desc_bg"
    android:layoutDirection="ltr"
    android:orientation="vertical"
    android:paddingStart="20dp"
    android:paddingEnd="20dp"
    tools:targetApi="28">

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

    <ImageButton
        android:id="@id/exo_prev"
        style="@style/ExoMediaButton.Previous"
        android:tint="@color/colorPrimaryDark"
        android:tintMode="src_in" />

    <ImageButton
        android:id="@id/exo_rew"
        style="@style/ExoMediaButton.Rewind"
        android:tint="@color/colorPrimaryDark"
        android:tintMode="src_in" />

    <ImageButton
        android:id="@id/exo_shuffle"
        style="@style/ExoMediaButton.Shuffle"
        android:tint="@color/colorPrimaryDark"
        android:tintMode="src_in" />

    <ImageButton
        android:id="@id/exo_repeat_toggle"
        style="@style/ExoMediaButton"
        android:tint="@color/colorPrimaryDark"
        android:tintMode="src_in" />

    <ImageButton
        android:id="@id/exo_play"
        style="@style/ExoMediaButton.Play"
        android:tint="@color/colorPrimaryDark"
        android:tintMode="src_in" />

    <ImageButton
        android:id="@id/exo_pause"
        style="@style/ExoMediaButton.Pause"
        android:tint="@color/colorPrimaryDark"
        android:tintMode="src_in" />

    <ImageButton
        android:id="@id/exo_ffwd"
        style="@style/ExoMediaButton.FastForward"
        android:tint="@color/colorPrimaryDark"
        android:tintMode="src_in" />

    <ImageButton
        android:id="@id/exo_next"
        style="@style/ExoMediaButton.Next"
        android:tint="@color/colorPrimaryDark"
        android:tintMode="src_in" />

    <ImageButton
        android:id="@id/exo_vr"
        style="@style/ExoMediaButton.VR"
        android:tint="@color/colorPrimaryDark"
        android:tintMode="src_in" />

  </LinearLayout>

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

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

    <com.google.android.exoplayer2.ui.DefaultTimeBar
        android:id="@id/exo_progress"
        android:layout_width="0dp"
        android:layout_height="26dp"
        android:layout_weight="1"
        app:played_color="@color/colorPrimaryDark"
        app:unplayed_color="@color/gray" />

    <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="#ff323232"
        android:textSize="14sp"
        android:textStyle="bold" />

  </LinearLayout>

</LinearLayout>

以下是我用于播放器的代码。注意,xml属性app:controller_layout_id指向上面定义的自定义控制器视图。

<FrameLayout 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="match_parent"
    android:padding="20dp">

  <com.google.android.exoplayer2.ui.PlayerView
      android:id="@+id/video_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_gravity="center"
      app:auto_show="true"
      app:controller_layout_id="@layout/custom_exo_controller_view"
      app:fastforward_increment="10000"
      app:repeat_toggle_modes="none"
      app:resize_mode="fixed_width"
      app:rewind_increment="10000"
      app:surface_type="surface_view"
      app:use_controller="true" />

</FrameLayout>

那样可以让UI变成你想要的样子。

您可以在自定义控制器和代码中根据需要添加额外的控件,使用 findViewById() 查找控件并编写事件监听器等。


如果我想在这个布局中添加一个按钮,如何从代码中添加按钮的单击监听器呢?我正在使用数据绑定,当我键入binding.playerview时,没有自定义按钮ID出现以添加单击监听器。你能告诉我怎么做吗?我卡在这里,无法取得任何进展。 - Prahlad V Thej
@PrahladVThej,我怀疑你是否可以在Exoplayer中使用数据绑定。我认为他们的Git Repo中有一个功能请求。此外,我还没有尝试过。您可以参考此链接:https://github.com/brianwernick/ExoMedia/issues/456 - Ram Iyer

21

好的,这花了我半天时间,直到我深入研究库代码并找到了这样的文本:

为了在整个应用程序中自定义PlaybackControlView的布局,或仅针对某些配置,您可以在应用程序的 res/layout 目录下定义exo_playback_control_view.xml 布局文件。这些布局将覆盖ExoPlayer库提供的布局,并将被用于播放控件视图。

完整文本:https://github.com/google/ExoPlayer/blob/release-v2/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlaybackControlView.java

另外,想要添加的是,您可以像这样在PlayerView中指定自定义布局:

<com.google.android.exoplayer2.ui.SimpleExoPlayerView android:id="@+id/player_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:controller_layout_id="@layout/custom_controls"/>

1
我们可以通过编程的方式添加controller_layout_id吗? - Zeero0
1
尝试扩展PlaybackControlView.java并添加此方法=) - Sough
哪个方法请? - Zeero0
我不明白... 有例子吗? - Frank Fang
1
弃用的...... - mathematics-and-caffeine

11

实际上,调用播放和暂停方法的代码位于PlayerControl 类中。

如果您不想使用默认的Android媒体控制器UI,只需不使用MediaController 类,在布局文件中创建自己的UI并使用自定义的播放和暂停按钮将操作绑定到按钮的 onClickListener 上。

要播放视频,请调用exoPlayer.setPlayWhenReady(true);

要暂停,则调用exoPlayer.setPlayWhenReady(false);

这与如何为Android MediaController创建自定义UI 的类似问题。


根据此链接(http://www.brightec.co.uk/ideas/custom-android-media-controller),“您可以使用Android中包含的MediaController类来代替从头开始编写自己的媒体控制器”,我提出这个问题是因为我无法在ExoPlayer库上执行这些步骤,而且该教程是针对默认媒体播放器编写的。 - Siavash Abdoli
1
在五年后,你的解决方案对我来说更有意义了:))我不知道它是否可行,因为我不再从事任何播放器工作,但它对我来说看起来是合理的:D抱歉,我当时还是初级程序员,没有导师:D - Siavash Abdoli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接