媒体项目

播放列表 API 基于 MediaItem 实例,可以使用 MediaItem.Builder 方便地构建这些实例。在播放器内部,MediaItemMediaSource.Factory 转换为可播放的 MediaSource。如果没有 自定义配置,此转换将由 DefaultMediaSourceFactory 执行,它能够构建与媒体项目属性相对应的复杂媒体源。可以在媒体项目上设置的一些属性如下所示。

简单的媒体项目

仅包含流 URI 的媒体项目可以使用 fromUri 便利方法构建

Kotlin

val mediaItem = MediaItem.fromUri(videoUri)

Java

MediaItem mediaItem = MediaItem.fromUri(videoUri);

对于所有其他情况,可以使用 MediaItem.Builder。在下面的示例中,使用 ID 和一些附加元数据构建媒体项目

Kotlin

val mediaItem = MediaItem.Builder().setMediaId(mediaId).setTag(myAppData).setUri(videoUri).build()

Java

MediaItem mediaItem =
    new MediaItem.Builder().setMediaId(mediaId).setTag(myAppData).setUri(videoUri).build();

附加元数据对于 在播放列表转换发生时更新应用的 UI很有用。

图像

图像播放需要媒体项目中的持续时间来指定图像在播放期间应显示多长时间。有关 图像动态照片图像加载库(例如,Glide)的更多信息,请参阅指南页面。

Kotlin

val mediaItem = MediaItem.Builder().setUri(imageUri).setImageDurationMs(3000).build()

Java

MediaItem mediaItem =
    new MediaItem.Builder().setUri(imageUri).setImageDurationMs(3_000).build();

自适应媒体的非标准文件扩展名

ExoPlayer 提供了针对 DASH、HLS 和 SmoothStreaming 的自适应媒体源。如果此类自适应媒体项目的 URI 以标准文件扩展名结尾,则会自动创建相应的媒体源。如果 URI 具有非标准扩展名或根本没有扩展名,则可以显式设置 MIME 类型以指示媒体项目的类型

Kotlin

val mediaItem = MediaItem.Builder().setUri(hlsUri).setMimeType(MimeTypes.APPLICATION_M3U8).build()

Java

MediaItem mediaItem =
    new MediaItem.Builder().setUri(hlsUri).setMimeType(MimeTypes.APPLICATION_M3U8).build();

对于渐进式媒体流,不需要 MIME 类型。

受保护内容

对于受保护的内容,应设置媒体项目的 DRM 属性。需要 UUID,所有其他属性都是可选的。

使用 Widevine DRM 保护项目的播放示例配置,其中许可证 URI 不直接在媒体中可用(例如,在 DASH 播放列表中),并且需要多个会话(例如,由于密钥轮换)

Kotlin

val mediaItem =
  MediaItem.Builder()
    .setUri(videoUri)
    .setDrmConfiguration(
      MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
        .setLicenseUri(licenseUri)
        .setMultiSession(true)
        .setLicenseRequestHeaders(httpRequestHeaders)
        .build()
    )
    .build()

Java

MediaItem mediaItem =
    new MediaItem.Builder()
        .setUri(videoUri)
        .setDrmConfiguration(
            new MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
                .setLicenseUri(licenseUri)
                .setMultiSession(true)
                .setLicenseRequestHeaders(httpRequestHeaders)
                .build())
        .build();

在播放器内部,DefaultMediaSourceFactory 将把这些属性传递给 DrmSessionManagerProvider 以获取 DrmSessionManager,然后将其注入到创建的 MediaSource 中。可以 进一步自定义 DRM 行为以满足您的需求。

侧载字幕轨道

要侧载字幕轨道,可以在构建媒体项目时添加 MediaItem.Subtitle 实例

Kotlin

val subtitle =
  SubtitleConfiguration.Builder(subtitleUri)
    .setMimeType(mimeType) // The correct MIME type (required).
    .setLanguage(language) // The subtitle language (optional).
    .setSelectionFlags(selectionFlags) // Selection flags for the track (optional).
    .build()
val mediaItem =
  MediaItem.Builder().setUri(videoUri).setSubtitleConfigurations(listOf(subtitle)).build()

Java

MediaItem.SubtitleConfiguration subtitle =
    new MediaItem.SubtitleConfiguration.Builder(subtitleUri)
        .setMimeType(mimeType) // The correct MIME type (required).
        .setLanguage(language) // The subtitle language (optional).
        .setSelectionFlags(selectionFlags) // Selection flags for the track (optional).
        .build();
MediaItem mediaItem =
    new MediaItem.Builder()
        .setUri(videoUri)
        .setSubtitleConfigurations(ImmutableList.of(subtitle))
        .build();

在内部,DefaultMediaSourceFactory 将使用 MergingMediaSource 将内容媒体源与每个字幕轨道的 SingleSampleMediaSource 组合。 DefaultMediaSourceFactory 不支持为多周期 DASH 侧载字幕。

剪辑媒体流

要剪辑媒体项目引用的内容,请设置自定义起始和结束位置

Kotlin

val mediaItem =
  MediaItem.Builder()
    .setUri(videoUri)
    .setClippingConfiguration(
      MediaItem.ClippingConfiguration.Builder()
        .setStartPositionMs(startPositionMs)
        .setEndPositionMs(endPositionMs)
        .build()
    )
    .build()

Java

MediaItem mediaItem =
    new MediaItem.Builder()
        .setUri(videoUri)
        .setClippingConfiguration(
            new ClippingConfiguration.Builder()
                .setStartPositionMs(startPositionMs)
                .setEndPositionMs(endPositionMs)
                .build())
        .build();

在内部,DefaultMediaSourceFactory 将使用 ClippingMediaSource 来包装内容媒体源。还有其他剪辑属性。有关更多详细信息,请参阅 MediaItem.Builder Javadoc

广告插入

要插入广告,应设置媒体项目的广告标签 URI 属性

Kotlin

val mediaItem =
  MediaItem.Builder()
    .setUri(videoUri)
    .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).build())

Java

MediaItem mediaItem =
    new MediaItem.Builder()
        .setUri(videoUri)
        .setAdsConfiguration(new MediaItem.AdsConfiguration.Builder(adTagUri).build())
        .build();

在内部,DefaultMediaSourceFactory 将使用 AdsMediaSource 包装内容媒体源以插入广告标签中定义的广告。要使此功能正常工作,播放器还需要对其 DefaultMediaSourceFactory 进行 相应配置