You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ExoPlayer 2.18.1中实现DASH+DAI+Preroll(Widevine DRM)?

如何在ExoPlayer 2.18.1中实现Preroll前置广告+DAI动态广告+DRM加密DASH流共存?

问题背景

已分别实现「DASH+Preroll前置广告」和「DASH+DAI动态广告插入」功能,但三者结合时抛出异常:

com.google.android.exoplayer2.upstream.Loader$UnexpectedLoaderException: Unexpected IllegalArgumentException: null

现有实现代码

DASH+DAI 实现代码

val dashMediaSource = DashMediaSource.Factory(dashChunkSourceFactory, manifestDataSourceFactory)
            .createMediaSource(
                MediaItem.Builder()
                    .setUri(Uri.parse(URLDAI))  //diff
                    .setDrmConfiguration(
                        MediaItem.DrmConfiguration.Builder(drmSchemeUuid)
                            .setLicenseUri(DRM_LICENSE_URL).build()
                    )
                    .setMimeType(MimeTypes.APPLICATION_MPD)
                    .setTag(null)
                    .build()
            )

playerView.setMediaSource(adsMediaSource)
playerView.prepare()

DASH+Preroll 实现代码

val dashMediaSource = DashMediaSource.Factory(dashChunkSourceFactory, manifestDataSourceFactory)
            .createMediaSource(
                MediaItem.Builder()
                    .setUri(Uri.parse(URL))  //diff
                    .setDrmConfiguration(
                        MediaItem.DrmConfiguration.Builder(drmSchemeUuid)
                            .setLicenseUri(DRM_LICENSE_URL).build()
                    )
                    .setMimeType(MimeTypes.APPLICATION_MPD)
                    .setTag(null)
                    .build()
            )

val dataSpec = DataSpec(Uri.parse(PREROLL))
val imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings()
val imaAdsLoader = ImaAdsLoader.Builder(this).setImaSdkSettings(imaSdkSettings).build()
imaAdsLoader.setPlayer(playerView)
val adsMediaSource = AdsMediaSource(mediaSource, dataSpec, 0, DefaultMediaSourceFactory(this), imaAdsLoader, binding.playerView)
playerView.setMediaSource(adsMediaSource)
playerView.prepare()

解决方案

核心问题是普通Preroll的AdsMediaSource与DAI的广告加载逻辑冲突,不能同时叠加使用。需通过IMA DAI原生API统一配置前置广告和动态广告插入,同时保留DRM配置。

完整实现代码

// 1. 配置IMA SDK设置,统一指定前置广告标签
val imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings().apply {
    adTagUrl = PREROLL // 传入你的前置广告VAST/VPAID标签URL
}

// 2. 创建DAI专用的AdsLoader
val daiAdsLoader = ImaAdsLoader.Builder(this)
    .setImaSdkSettings(imaSdkSettings)
    .build()

// 3. 构建DAI流请求(按需切换Live/Vod)
val streamRequest = LiveStreamRequest.Builder()
    .setAssetKey(DAI_ASSET_KEY) // 替换为你的DAI资产Key
    .setApiKey(DAI_API_KEY)     // 替换为你的DAI API Key
    .build()

// 4. 构建带DRM的DASH媒体源(DAI流)
val daiDashMediaSource = DashMediaSource.Factory(dashChunkSourceFactory, manifestDataSourceFactory)
    .createMediaSource(
        MediaItem.Builder()
            .setUri(Uri.parse(URLDAI))
            .setDrmConfiguration(
                MediaItem.DrmConfiguration.Builder(drmSchemeUuid)
                    .setLicenseUri(DRM_LICENSE_URL)
                    .build()
            )
            .setMimeType(MimeTypes.APPLICATION_MPD)
            .build()
    )

// 5. 用DAI AdsMediaSource包裹媒体源,关联播放器视图
val adsMediaSource = AdsMediaSource(
    daiDashMediaSource,
    DefaultMediaSourceFactory(this),
    daiAdsLoader,
    binding.playerView
)

// 6. 初始化播放器并加载
binding.playerView.player?.apply {
    setMediaSource(adsMediaSource)
    prepare()
}

关键注意事项

  • 禁止同时使用普通AdsMediaSource加载Preroll和DAI的AdsMediaSource,两者的广告加载逻辑会互相干扰
  • 确保前置广告标签(PREROLL)符合IMA DAI的格式要求(支持VAST 2.0+或VPAID)
  • DRM配置必须直接绑定到DAI的MediaItem中,确保加密流的解密流程正常
  • 确认依赖库版本匹配,build.gradle中需包含:
implementation 'com.google.android.exoplayer:exoplayer-ima:2.18.1'

内容的提问来源于stack exchange,提问作者BejanCorneliu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 06:33:26