video标签本身不支持广告贴片,需用javascript控制播放时机:pre-roll在用户交互后播放广告再衔接主视频,mid-roll需监听timeupdate并保存/恢复时间点,post-roll在ended事件后触发;所有play()必须在用户手势中调用,ios需muted+playsinline+preload="metadata"。

video 标签本身不支持广告贴片,必须靠 JavaScript 控制播放时机
HTML <video></video> 只是媒体容器,没有广告调度能力。所谓“贴片广告”,本质是在主视频开始前(pre-roll)、暂停时(mid-roll)或结束后(post-roll)插入另一段视频,并阻止主内容播放。这需要监听 play、timeupdate、ended 等事件,手动切换 src 和控制 play()/pause()。
常见错误现象:autoplay 被浏览器拦截导致 pre-roll 广告无法自动播放;广告视频加载完成前就调用 play() 报错 DOMException: play() failed because the user didn't interact with the document;广告播完后没重置主视频时间点,导致跳过开头几秒。
- 必须等用户真实交互(如点击按钮)后,才能安全调用
play()—— 这是现代浏览器的 autoplay 策略硬限制 - 广告视频建议用
preload="metadata"减少初始加载量,主视频可设preload="none"避免提前下载 - mid-roll 需监听
timeupdate并用Math.abs(currentTime - triggerTime) 判断是否到达插播点,避免因帧率或精度漏触发
用 addEventListener 监听 ended 事件实现 pre-roll 广告链式播放
最简可行路径:先加载广告视频 → 播完 → 自动加载并播放主视频。关键不是“嵌入”,而是“衔接”。
const adVideo = document.getElementById('ad-video');
const mainVideo = document.getElementById('main-video');
<p>adVideo.addEventListener('ended', () => {
mainVideo.src = '/videos/main.mp4';
mainVideo.load(); // 必须显式调用 load()
mainVideo.play().catch(e => console.warn('Auto-play prevented:', e));
});</p><p>// 用户点击“播放”按钮时才启动广告
document.getElementById('play-btn').addEventListener('click', () => {
adVideo.play().catch(e => console.warn('Ad play blocked:', e));
});
</p>
注意:load() 不可省略,否则部分浏览器不会重新解析新 src;play() 必须包裹在用户手势回调中,否则在 Chrome/Firefox/Safari 均会失败。
mid-roll 广告需暂停主视频 + 动态替换 src + 手动恢复时间点
mid-roll 是最容易出错的环节。不能只靠 currentTime 设断点,还要处理广告播放期间主视频的“暂停态”和“上下文保存”。
- 主视频播放到 60 秒时插广告:监听
timeupdate,当currentTime >= 60 && !adPlaying时执行广告逻辑 - 保存当前主视频时间点:
const savedTime = mainVideo.currentTime;,并在广告结束回调里mainVideo.currentTime = savedTime; - 广告视频要加
muted和playsinline(iOS Safari 要求),否则可能静音或全屏弹出 - 不要用
mainVideo.pause()后立刻换src,应等pause事件确认后再操作,避免状态竞争
绕不开的兼容性坑:iOS Safari 对 autoplay/muted 的苛刻要求
iOS Safari 要求:广告视频必须同时满足 muted + playsinline + 用户手势触发,缺一不可。即使广告无声,没加 muted 也会被静音策略拦截播放。
错误配置示例:<video id="ad-video" playsinline></video> → 缺 muted,iOS 上 play() 永远 rejected。
正确写法:<video id="ad-video" muted playsinline preload="metadata"></video>,且 JS 中必须在用户点击后调用 play()。
另一个隐藏问题:Safari 对 timeupdate 触发频率极低(约每秒 1–2 次),mid-roll 定时点若设在 60.7 秒,很可能错过。稳妥做法是把 mid-roll 触发窗口放宽到 ±0.5 秒,并用 requestAnimationFrame 补偿精度。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











