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

使用ExoPlayer 2.7.3 IMA扩展如何在指定时间点展示广告?

实现ExoPlayer 2.7.3 + IMA扩展定时插播广告

嘿,我来帮你搞定每30分钟插播广告的需求!既然你已经完成了开头广告的集成,核心就是通过播放进度监听+动态触发IMA广告加载来实现midroll(中途)广告。下面是适配ExoPlayer 2.7.3的具体步骤:

一、准备状态变量

先定义几个关键变量,用来跟踪广告触发时机和播放状态:

private static final long AD_INTERVAL_MS = 30 * 60 * 1000; // 30分钟,单位毫秒
private long lastAdPosition = 0; // 上一次插播广告的位置
private boolean isAdPlaying = false; // 当前是否在播放广告

二、添加播放进度监听

给ExoPlayer注册Player.EventListener,监听播放位置变化,判断是否到达广告触发节点:

player.addListener(new Player.EventListener() {
    @Override
    public void onPositionChanged(long position, long bufferedPosition) {
        // 过滤条件:不在广告播放中、当前是主媒体窗口、距离上次广告已达间隔
        if (!isAdPlaying && player.getCurrentTimeline().getWindowCount() > 0) {
            Window window = player.getCurrentTimeline().getWindow(player.getCurrentWindowIndex(), new Window());
            if (!window.isAd()) {
                long elapsedSinceLastAd = position - lastAdPosition;
                // 检查是否达到广告间隔,同时避免回退播放时重复触发
                if (elapsedSinceLastAd >= AD_INTERVAL_MS && position > lastAdPosition) {
                    triggerMidrollAd(position);
                }
            }
        }
    }

    @Override
    public void onTimelineChanged(Timeline timeline, Object manifest) {
        // 更新广告播放状态:判断当前窗口是否是广告窗口
        Window currentWindow = timeline.getWindow(player.getCurrentWindowIndex(), new Window());
        isAdPlaying = currentWindow.isAd();
        
        // 广告播放结束后,更新上次广告位置为当前主媒体位置
        if (!isAdPlaying) {
            lastAdPosition = player.getCurrentPosition();
        }
    }

    // 按需实现其他监听方法,比如onPlayerStateChanged处理暂停/播放状态
});

三、实现midroll广告触发逻辑

当到达触发节点时,暂停主媒体,请求IMA广告播放:

private void triggerMidrollAd(long currentPosition) {
    isAdPlaying = true;
    // 先暂停主媒体播放
    player.setPlayWhenReady(false);

    // 使用你已初始化的AdsLoader请求midroll广告
    AdRequest adRequest = new AdRequest.Builder().build();
    // 传入当前播放位置,告诉IMA广告要在这个节点插入
    yourExistingAdsLoader.requestAds(adRequest, currentPosition);
}

四、监听广告播放事件,恢复主媒体

给AdsMediaSource注册AdEventListener,处理广告的开始、完成、失败等事件:

yourAdsMediaSource.setAdEventListener(new AdEventListener() {
    @Override
    public void onAdStarted() {
        isAdPlaying = true;
    }

    @Override
    public void onAdCompleted() {
        isAdPlaying = false;
        // 广告播放完成后,更新上次广告位置并恢复主媒体播放
        lastAdPosition = player.getCurrentPosition();
        player.setPlayWhenReady(true);
    }

    @Override
    public void onAdFailedToLoad(int errorCode) {
        // 广告加载失败时,恢复主媒体播放,避免卡住
        isAdPlaying = false;
        player.setPlayWhenReady(true);
        // 可以在这里记录错误日志
    }

    // 按需实现其他广告事件回调,比如onAdClicked、onAdSkipped等
});

五、关键注意事项

  • 避免重复触发:一定要维护好isAdPlaying标志位,防止广告播放时重复触发请求;
  • 处理快进/回退:如果用户快进超过30分钟,逻辑会自动在下一个间隔触发,也可以根据需求调整为直接触发一次;
  • 视频长度判断:如果视频总时长小于30分钟,要跳过广告触发逻辑,可以通过player.getDuration()判断;
  • 内存泄漏:在播放器销毁时,记得移除所有监听(player.removeListener()、adsMediaSource.setAdEventListener(null)等)。

这样就能实现每30分钟自动插播广告的效果了,要是遇到API适配问题(毕竟是2.7.3的老版本),可以核对一下你当前依赖的IMA扩展类的方法签名调整细节~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:13:28