如何在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
相关产品推荐
相关产品推荐

