AndroidX Media3之ExoPlayer简单使用

Posted 愿天深海

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AndroidX Media3之ExoPlayer简单使用相关的知识,希望对你有一定的参考价值。

ExoPlayer是谷歌开源的一个应用级的音视频播放器。它提供了 android 的 MediaPlayer API 的替代方案,用于在本地和通过 Internet 播放音频和视频。ExoPlayer 支持 Android 的 MediaPlayer API 目前不支持的功能,包括 DASH 和 SmoothStreaming 自适应播放。

ExoPlayer于2014年推出,而在2021年新推出了AndroidX Media3。

Media3 是 Android 媒体支持库的新家,里面包括了 ExoPlayer,目前仍处于Beta 版阶段,还未发布正式版,因此ExoPlayer 和 Media3 目前处于同步更新阶段,Media3的1.0.0-beta02版本ExoPlayer 2.18.1 版本相对应。具体更新说明:https://developer.android.google.cn/jetpack/androidx/releases/media3#version_100_2

两者的github地址,都包含有demo:Meida3ExoPlayer

依赖项

基本的Google Maven 仓库和Java 8支持就不说,新建的项目都会自动配置好。如果是网络视频链接,不要忘记了网络权限。如果是从ExoPlayer迁移到Media3,可查看Media3迁移指南
主要的依赖项是media3-exoplayer,其余的media3-ui、media3-cast、media3-exoplayer-dash等等按需添加。

    implementation 'androidx.media3:media3-exoplayer:1.0.0-beta02'
    implementation 'androidx.media3:media3-ui:1.0.0-beta02'

media3-exoplayer 对应着ExoPlayer里exoplayer-core,提供着exoplayer的核心功能,必须添加。media3-ui对应着ExoPlayer里exoplayer-ui,提供着用于ExoPlayer的UI组件和资源。

创建播放器,添加至视图

使用ExoPlayer.Builder(this).build()就可以创建出一个player:

val player = ExoPlayer.Builder(this).build()

media3-ui库为媒体播放提供了一系列预构建的UI组件,其中PlayerView中包含了PlayerControlView和渲染视频的Surface,在布局文件中直接使用PlayerView:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
    tools:context=".MainActivity">

    <androidx.media3.ui.PlayerView
        android:id="@+id/player_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

然后将创建的播放器添加至视图上:

playerView.player = player

填充媒体数据,准备播放

在ExoPlayer中媒体数据由MediaItem表示,setMediaItem可以填充媒体数据,addMediaItem可以填充一系列媒体数据列表。

//填充媒体数据
player.addMediaItem(MediaItem.fromUri(url3))
//准备播放
player.prepare()
//准备完成就开始播放
player.playWhenReady = true

至此,就可以使用ExoPlayer进行视频播放了。playerView中封装好了对于播放器的控制以及播放异常情况。

播放器控制

以下为常用控制播放的方法:

  • prepare 准备
  • playWhenReady 准备完成立即播放
  • play 播放
  • pause 暂停
  • seekTo 指定进度
  • repeatMode 指定播放的循环模式
  • setPlaybackSpeed 播放速度
  • hasPreviousMediaItem/hasNextMediaItem 播放列表中是否有上一个/下一个媒体数据
  • seekToPreviousMediaItem/seekToNextMediaItem 播放列表中指定进度为上一个/下一个媒体数据

播放器释放

当不再需要播放器时,记得释放资源:

player.stop()
player.release()

播放事件监听

通过player.addListener添加一个Player.Listener进行播放事件的监听。Player.Listener有空的默认方法,因此按需实现所需要的方法即可。

播放状态

ExoPlayer具有四种播放状态:

  • STATE_IDLE:初始状态,此时播放器没有可以播放的资源,播放器停止播放或者播放失败后也会处于该状态
  • STATE_BUFFERING: 没有足够的数据可以加载播放,此时无法立即播放
  • STATE_READY : 播放器可以立即播放,是否播放取决于playWhenReady的值,该值表达了使用者的意愿,为true,将会开始播放,否则不播。
  • STATE_ENDED: 播放完了所有的资源后处于该状态

在Player.Listener中通过onPlaybackStateChanged方法就可以拿到播放状态。

播放异常

在Player.Listener中通过onPlayerError方法就可以监听到播放异常情况。

Exoplayer - Widevine 和 MPEG DASH

【中文标题】Exoplayer - Widevine 和 MPEG DASH【英文标题】:Exoplayer - Widevine and MPEG DASH 【发布时间】:2015-12-28 01:28:05 【问题描述】:

我正在尝试实现 Android 应用来播放受宽藤保护的视频。我在 Exoplayer 上构建我的应用程序,我遇到了 MediaDrm 的问题。

android.media.MediaDrm$MediaDrmStateException: Failed to get key request: DRM vendor-defined error: -2998
            at android.media.MediaDrm.getKeyRequest(Native Method)
            at com.google.android.exoplayer.drm.StreamingDrmSessionManager.postKeyRequest(StreamingDrmSessionManager.java:370)
            at com.google.android.exoplayer.drm.StreamingDrmSessionManager.openInternal(StreamingDrmSessionManager.java:314)
            at com.google.android.exoplayer.drm.StreamingDrmSessionManager.open(StreamingDrmSessionManager.java:284)
            at com.google.android.exoplayer.MediaCodecTrackRenderer.maybeInitCodec(MediaCodecTrackRenderer.java:325)
            at com.google.android.exoplayer.MediaCodecTrackRenderer.onInputFormatChanged(MediaCodecTrackRenderer.java:739)
            at com.google.android.exoplayer.MediaCodecTrackRenderer.readFormat(MediaCodecTrackRenderer.java:511)
            at com.google.android.exoplayer.MediaCodecTrackRenderer.doSomeWork(MediaCodecTrackRenderer.java:492)
            at com.google.android.exoplayer.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:417)
            at com.google.android.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:205)

我有这个例外。我发现这行代码抛出了这个异常:

keyRequest = mediaDrm.getKeyRequest(sessionId, schemeData, mimeType, MediaDrm.KEY_TYPE_STREAMING, params);

方法的所有参数都设置正确,但是调用该方法失败并抛出上面的异常。

你知道我该如何解决吗?感谢您的帮助。

【问题讨论】:

【参考方案1】:

我终于解决了。问题出在我用于测试的设备上。此设备是搭载 Android 5.0.1 的三星 Galaxy S4。当我在不同的设备(Nexus 5、一些三星平板电脑等)上尝试我的代码时,它运行良好。因此,Galaxy S4 中可能存在一些错误或缺少对 Widevine Modular 的支持。

【讨论】:

以上是关于AndroidX Media3之ExoPlayer简单使用的主要内容,如果未能解决你的问题,请参考以下文章

android之AndroidX介绍

android,Exoplayer实现视频播放器

无法解决:com.google.android.exoplayer:exoplayer-smoothstreaming:2.6.1

音视频开发之旅(44)-ExoPlayer介绍及简单使用

如何在 android 中实现 Exoplayer 2.11.1?

Android 依赖 'com.google.android.exoplayer:exoplayer' 有不同版本的编译(r2.1.0)和运行时(2.9.1)类路径