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

Android中使用ExoPlayer播放音频时插入中插广告方案咨询

基于ExoPlayer实现自定义中插广告(Mid-Roll)方案

核心思路

无需依赖IMA或VAST协议,直接利用ExoPlayer的拼接播放列表(ConcatenatingMediaSource)结合播放进度监听,将广告音频作为普通媒体源插入到剧集的指定时间节点。本质是把完整剧集拆分为「广告前片段」+「广告源」+「广告后片段」的组合,按顺序播放。

具体实现步骤

1. 拆分剧集与创建广告媒体源

  • 先获取剧集的总时长,确定中插广告的触发时间点(比如每15分钟一次,或固定的几个时间戳)。
  • 使用ClippingMediaSource截取剧集的前后分段,同时创建广告的媒体源(和普通剧集源创建方式一致):
    // 假设midRollTime是预设的中插时间,单位为微秒
    val episodeMediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
        .createMediaSource(MediaItem.fromUri(episodeUrl))
    
    // 截取剧集从开始到中插点的片段
    val preAdSegment = ClippingMediaSource(
        episodeMediaSource,
        0,
        midRollTime
    )
    // 截取剧集从中插点到结束的片段
    val postAdSegment = ClippingMediaSource(
        episodeMediaSource,
        midRollTime,
        C.TIME_END_OF_SOURCE
    )
    // 创建广告媒体源
    val adMediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
        .createMediaSource(MediaItem.fromUri(adAudioUrl))
    

2. 构建拼接播放列表并播放

将拆分后的片段和广告源按顺序加入ConcatenatingMediaSource,再设置给播放器:

val concatenatedSource = ConcatenatingMediaSource(
    preAdSegment,
    adMediaSource,
    postAdSegment
)
player.setMediaSource(concatenatedSource)
player.prepare()
player.play()

3. 动态插入广告(可选场景)

如果需要在播放过程中动态触发广告(比如根据用户行为或实时规则),可以通过监听播放进度,动态修改播放列表:

var adInserted = false
player.addListener(object : Player.Listener {
    override fun onPositionDiscontinuity(oldPosition: Player.PositionInfo, newPosition: Player.PositionInfo, reason: Int) {
        super.onPositionDiscontinuity(oldPosition, newPosition, reason)
        val currentPos = player.currentPosition
        // 检查是否到达中插点且未插入过广告
        if (currentPos >= midRollTime && !adInserted) {
            player.pause()
            // 截取当前位置到剧集结尾的剩余片段
            val remainingSegment = ClippingMediaSource(
                episodeMediaSource,
                currentPos,
                C.TIME_END_OF_SOURCE
            )
            // 替换原剧集源,插入广告和剩余片段
            concatenatedSource.removeMediaSource(0)
            concatenatedSource.addMediaSource(adMediaSource)
            concatenatedSource.addMediaSource(remainingSegment)
            adInserted = true
            player.play()
        }
    }
})

4. 异常与体验优化

  • 广告加载失败时,监听Player.Listener的onPlayerError事件,自动跳过广告,直接播放后续剧集片段。
  • 若允许用户跳过广告,可在广告播放时显示跳过按钮,点击后调用player.seekToNextMediaItem()切换到剧集片段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:45:12