ExoPlayer 演示应用

ExoPlayer 的主演示应用主要有两个用途:

  1. 提供一个相对简单但功能齐全的 ExoPlayer 用法示例。 您可以将演示版应用作为一个便捷的起点进行开发 自己的应用。
  2. 为了便于试用 ExoPlayer。该演示版应用可用于测试播放 您自己内容的部分。

本页介绍了如何获取、编译和运行演示版应用。还介绍了 如何使用它播放您自己的媒体内容。

获取代码

主演示版应用的源代码位于以下目录的 demos/main 文件夹中: 我们的 GitHub 项目。将项目克隆到 本地目录:

git clone https://github.com/androidx/media.git

接下来,在 Android Studio 中打开项目。您应该会在 Android 项目视图(已展开演示版应用的相关文件夹):

Android Studio 中的项目

编译和运行

如需编译和运行演示版应用,请在以下位置选择并运行 demo 配置: Android Studio。演示版应用将在连接的 Android 设备上安装并运行。 我们建议尽可能使用实体设备。如果您想使用模拟器 请阅读支持的设备中的模拟器部分,并确保 您的虚拟设备使用 API 级别至少为 23 的系统映像。

SampleChooserActivity 和 PlayerActivity

演示版应用会显示一系列示例 (SampleChooserActivity)。正在选择 示例将打开第二个 activity (PlayerActivity) 进行播放。演示 具有播放控件和曲目选择功能。它还使用 ExoPlayer 的 EventLogger 实用程序类,用于向 查看系统日志查看此日志记录(以及 其他标记)。

adb logcat EventLogger:V *:E

启用捆绑解码器

ExoPlayer 有许多扩展程序允许使用捆绑的软件 解码器,包括 AV1、VP9、Opus、FLAC 和 FFmpeg(仅限音频)。演示版应用 可以构建包含和使用这些扩展,如下所示:

  1. 构建要包含的每个扩展程序。请注意,这是一个 手动流程。请参阅每个扩展名中的 README.md 文件,了解 操作说明。
  2. 在 Android Studio 的“Build Variants”视图中,为演示设置 build 变体 模块转换为 withDecoderExtensionsDebugwithDecoderExtensionsRelease, 如下图所示

    选择演示版“withDecoderExtensionsDebug”构建变体

  3. 照常编译、安装并运行 demo 配置。

默认情况下,仅当有合适的平台解码器时才会使用扩展解码器 不存在。可以指定扩展解码器应该 如以下部分所述。

播放你自己的内容

您可以在演示版应用中以多种方式播放您自己的内容。

1. 修改 assets/media.exolist.json

该演示版应用中列出的示例是从 assets/media.exolist.json 加载的。 通过编辑此 JSON 文件,可以在演示中添加和移除示例 应用。架构如下所示,其中 [O] 表示可选属性。

[
  {
    "name": "Name of heading",
    "samples": [
      {
        "name": "Name of sample",
        "uri": "The URI of the sample",
        "extension": "[O] Sample type hint. Values: mpd, ism, m3u8",
        "clip_start_position_ms": "[O] A start point to which the sample should be clipped, in milliseconds"
        "clip_end_position_ms": "[O] An end point from which the sample should be clipped, in milliseconds"
        "drm_scheme": "[O] Drm scheme if protected. Values: widevine, playready, clearkey",
        "drm_license_uri": "[O] URI of the license server if protected",
        "drm_force_default_license_uri": "[O] Whether to force use of "drm_license_uri" for key requests that include their own license URI",
        "drm_key_request_properties": "[O] Key request headers if protected",
        "drm_session_for_clear_content": "[O] Whether to attach a DRM session to clear video and audio tracks"
        "drm_multi_session": "[O] Enables key rotation if protected",
        "subtitle_uri": "[O] The URI of a subtitle sidecar file",
        "subtitle_mime_type": "[O] The MIME type of subtitle_uri (required if subtitle_uri is set)",
        "subtitle_language": "[O] The BCP47 language code of the subtitle file (ignored if subtitle_uri is not set)",
        "ad_tag_uri": "[O] The URI of an ad tag to load via the IMA extension"
      },
      ...etc
    ]
  },
  ...etc
]

可以使用以下架构指定示例播放列表:

[
  {
    "name": "Name of heading",
    "samples": [
      {
        "name": "Name of playlist sample",
        "playlist": [
          {
            "uri": "The URI of the first sample in the playlist",
            "extension": "[O] Sample type hint. Values: mpd, ism, m3u8"
            "clip_start_position_ms": "[O] A start point to which the sample should be clipped, in milliseconds"
            "clip_end_position_ms": "[O] An end point from which the sample should be clipped, in milliseconds"
            "drm_scheme": "[O] Drm scheme if protected. Values: widevine, playready, clearkey",
            "drm_license_uri": "[O] URI of the license server if protected",
            "drm_force_default_license_uri": "[O] Whether to force use of "drm_license_uri" for key requests that include their own license URI",
            "drm_key_request_properties": "[O] Key request headers if protected",
            "drm_session_for_clear_content": "[O] Whether to attach a DRM session to clear video and audio tracks",
            "drm_multi_session": "[O] Enables key rotation if protected",
            "subtitle_uri": "[O] The URI of a subtitle sidecar file",
            "subtitle_mime_type": "[O] The MIME type of subtitle_uri (required if subtitle_uri is set)",
            "subtitle_language": "[O] The BCP47 language code of the subtitle file (ignored if subtitle_uri is not set)"
          },
          {
            "uri": "The URI of the second sample in the playlist",
            ...etc
          },
          ...etc
        ]
      },
      ...etc
    ]
  },
  ...etc
]

如果需要,可将密钥请求标头指定为包含字符串的对象 属性:

"drm_key_request_properties": {
  "name1": "value1",
  "name2": "value2",
  ...etc
}

在示例选择器 activity 中,溢出菜单包含用于 指定是否首选扩展解码器。

本地文件 URI 和分区存储限制

指定本地文件 URI 时,演示版应用会请求必要的存储空间 读取这些文件的权限。不过,从 Android 13 开始, 可以加载不以典型媒体文件结尾的任意文件 扩展名(例如 .mp4)。如果您需要加载此类文件,可以将其置于 演示版应用的无访问限制的特定存储目录。这个 通常位于 /sdcard/Android/data/androidx.media3.demo.main/files

2. 加载外部 exolist.json 文件

演示版应用可以使用上述架构加载外部 JSON 文件,并将 符合 *.exolist.json 惯例。例如,如果你托管这样的 https://yourdomain.com/samples.exolist.json下的文件,则可在 演示版应用:

adb shell am start -a android.intent.action.VIEW \
    -d https://yourdomain.com/samples.exolist.json

点击 *.exolist.json 链接(例如,在浏览器中或电子邮件中) 客户端),也会在演示中打开它 应用。因此,托管 *.exolist.json JSON 文件提供了一种简单的 分发内容供其他人在演示版应用中试用。

3. 触发 intent

intent 可用于绕过样本列表,直接启动到 。要播放单个样本,请将 intent 的操作设置为 androidx.media3.demo.main.action.VIEW 及其数据 URI 到 示例。可以使用以下代码从终端触发此类 intent:

adb shell am start -a androidx.media3.demo.main.action.VIEW \
    -d https://yourdomain.com/sample.mp4

单个示例 intent 支持的可选 extra 包括:

  • 配置 extra 示例: <ph type="x-smartling-placeholder">
      </ph>
    • mime_type [字符串] MIME 类型提示示例。例如 application/dash+xml,用于 DASH 内容。
    • clip_start_position_ms [Long] 样本应到达的起点 以毫秒为单位。
    • clip_end_position_ms [Long] 表示样本的终点 以毫秒为单位。
    • drm_scheme [字符串] DRM 方案(如果受保护)。有效值为 widevineplayreadyclearkey。您也可以使用 DRM 方案 UUID。
    • drm_license_uri [字符串] 许可服务器的 URI(如果受保护)。
    • drm_force_default_license_uri [布尔值] 是否强制使用 drm_license_uri,适用于包含自己的许可 URI 的密钥请求。
    • drm_key_request_properties [字符串数组] 键请求标头打包为 name1、value1、name2、value2 等(如果受保护)。
    • drm_session_for_clear_content [布尔值] 是否附加 DRM 会话 清除视频轨道和音轨。
    • drm_multi_session [布尔值] 如果受保护,则启用密钥轮替。
    • subtitle_uri [字符串] 字幕辅助信息文件文件的 URI。
    • subtitle_mime_type [字符串] subtitle_uri 的 MIME 类型(如果需要 subtitle_uri 已设置)。
    • subtitle_language [字符串] 字幕文件的 BCP47 语言代码 (如果未设置 subtitle_uri,则忽略)。
    • ad_tag_uri [字符串] 使用 [IMA 附加信息][]。
    • prefer_extension_decoders [布尔值] 扩展解码器是否 更倾向于平台应用

使用 adb shell am start 触发 intent 时,可选的字符串 extra 可以 设置为 --es(例如,--es extension mpd)。可选的布尔型 extra 可以 设置为 --ez(例如,--ez prefer_extension_decoders TRUE)。可选的 可使用 --el 设置长 extra(例如,--el clip_start_position_ms 5000)。一个 可选的字符串数组 extra 可使用 --esa 进行设置(例如, --esa drm_key_request_properties name1,value1)。

要播放示例播放列表,请将 intent 的操作设置为 androidx.media3.demo.main.action.VIEW_LIST。示例配置 extra 与 androidx.media3.demo.main.action.VIEW 相同, 但有两点区别

  • 额外福利键应带有下划线和样本的索引(从 0 开始) 作为后缀。例如,extension_0 会提示第一个 示例。drm_scheme_1 将为第二个样本设置 DRM 方案。
  • 样本的 URI 作为带有 uri_<sample-index> 键的 extra 传递。

其他不依赖于样本的 extra 不会发生变化。例如,您 可以在终端中运行以下命令来播放包含两项的播放列表: 替换第二项的扩展名:

adb shell am start -a androidx.media3.demo.main.action.VIEW_LIST \
    --es uri_0 https://a.com/sample1.mp4 \
    --es uri_1 https://b.com/sample2.fake_mpd \
    --es extension_1 mpd