向应用添加播放控件

播放媒体的应用需要使用用于显示媒体和 控制播放。Media3 库包含一个界面模块,该模块包含 多个界面组件如需依赖于界面模块,请添加以下内容 依赖项:

Kotlin

implementation("androidx.media3:media3-ui:1.4.1")

Groovy

implementation "androidx.media3:media3-ui:1.4.1"

最重要的组件是 PlayerView,它是一个用于播放媒体的视图。 PlayerView 会在播放期间显示视频、图片、字幕和专辑封面。 以及播放控件

PlayerView 具有用于附加和分离的 setPlayer 方法(通过 传递 null) Player 实例。

PlayerView

PlayerView 可用于播放视频、图片和音频。它会渲染 视频和字幕(如果是视频播放的话)、位图(如果是图片播放) 并且可以在音频文件中显示作为元数据包含的海报图片。你可以添加它 与任何其他界面组件一样。例如,PlayerView 可包含在以下 XML 中:

<androidx.media3.ui.PlayerView
    android:id="@+id/player_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:show_buffering="when_playing"
    app:show_shuffle_button="true"/>

上面的代码段说明 PlayerView 提供了 属性。这些属性可用于自定义视图的行为,如 以及它的外观其中大多数属性都有对应的 setter 方法,这些方法可用于在运行时自定义视图。通过 PlayerView Javadoc 列出了 。

在布局文件中声明视图后,便可在 onCreate 方法:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView = findViewById(R.id.player_view)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // ...
  playerView = findViewById(R.id.player_view);
}

播放器完成初始化后,即可通过调用 setPlayer:

Kotlin

// Instantiate the player.
val player = ExoPlayer.Builder(context).build()
// Attach player to the view.
playerView.player = player
// Set the media item to be played.
player.setMediaItem(mediaItem)
// Prepare the player.
player.prepare()

Java

// Instantiate the player.
player = new ExoPlayer.Builder(context).build();
// Attach player to the view.
playerView.setPlayer(player);
// Set the media item to be played.
player.setMediaItem(mediaItem);
// Prepare the player.
player.prepare();

选择表面类型

通过 PlayerViewsurface_type 属性,您可以设置 Surface 的类型 用于视频播放。除了值spherical_gl_surface_view( 是适用于球面视频播放的特殊值)和 video_decoder_gl_surface_view(用于使用扩展程序呈现视频) 渲染程序),允许使用的值为 surface_viewtexture_viewnone。如果 该视图仅用于音频播放,则应使用 none,以避免 因为创建表面的成本可能很高

如果观看行为是常规视频播放,则 surface_viewtexture_view 。与 TextureView相比,SurfaceView的 视频播放:

  • 功率明显下降 许多设备上的消费量 设备。
  • 帧时间越准确,视频播放更顺畅。
  • 在支持的设备上支持更高质量的 HDR 视频输出。
  • 支持播放受 DRM 保护的内容时的安全输出。
  • 能够以显示屏的完整分辨率呈现视频内容 可提升界面层的 Android TV 设备。

因此,应尽可能优先使用 SurfaceView,而不是 TextureView。 仅当 SurfaceView 无法满足您的需求时,才应使用 TextureView。一个 例如,需要流畅的动画或视频滚动操作 Android 7.0(API 级别 24)之前的版本,如以下说明所述。对于 在这种情况下,最好只使用 TextureView SDK_INT 高于 24 (Android 7.0),否则为 SurfaceView

Android TV 上的方向键导航

Android TV 的遥控器有一个方向键控制器,可发送 在ActivitydispatchKeyEvent(KeyEvent)以关键事件的形式到达。这些 需要委托给播放器视图:

Kotlin

override fun dispatchKeyEvent(event: KeyEvent?): Boolean{
  return playerView.dispatchKeyEvent(event!!) || super.dispatchKeyEvent(event)
}

Java

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
  return playerView.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}

为播放器视图请求焦点对于导航播放非常重要 控制和跳过广告建议在以下时间的 onCreate 中请求焦点: Activity

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView.requestFocus()
  // ...
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    playerView.requestFocus();
    // ...
}

如果您在 Android TV 上使用 Compose,则需要将 AndroidView 设为 可聚焦,并通过将修饰符参数传递到 AndroidView

AndroidView(
  modifier = modifier
    .focusable()
    .onKeyEvent { playerView.dispatchKeyEvent(it.nativeKeyEvent) },
  factory = { playerView }
)

替换可绘制对象

PlayerView 使用 PlayerControlView 显示播放内容 控件和进度条。PlayerControlView 使用的可绘制对象可以 会被替换为应用中定义的相同名称的可绘制对象。请参阅 PlayerControlView Javadoc,获取 其他属性

进一步自定义

如果还需要进行上述自定义之外的其他自定义,我们期望应用 开发者会实现自己的界面组件,而不是使用提供的组件 由 Media3 的界面模块生成。