使用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
相关产品推荐
相关产品推荐

