前言
浏览器中如何让视频在页面打开时自动播放,原本以为很简单的事,后面了解一下,背后还是有一点小小的规则。本文主要介绍自动播放的策略和使用方案。
1. 了解自动播放策略
具体规则我们可以查看MDN Autoplay guide for media and Web Audio APIs中的规则。
要想自动播放需要满足以下规则:
那么会有疑问,为什么B站等一些网站是可以自动播放呢?
这是因为他们媒体参与度得分较高,相当于有权限控制自动播放。具体可查看chrome://media-engagement/
。
媒体互动指数
媒体互动指数 (MEI) 衡量的是个人在网站上观看媒体的倾向。Chrome 的方法是统计每个来源的访问次数与重要媒体播放事件的比率:
- 媒体(音频/视频)的用时必须超过 7 秒。
- 音频必须存在且已取消静音。
- 包含该视频的标签页处于有效状态。
- 视频的尺寸(以像素为单位)必须大于 200×140。
然后,Chrome 会计算出媒体互动得分,该得分在定期播放媒体的网站上最高。当该值足够高时,系统将仅允许在桌面设备上自动播放媒体内容。可参考Autoplay policy in Chrome
用户的 MEI 可在 about://media-engagement
内部页面上查看:
那么如果我们不能进行自动播放,那有哪些方案处理呢?
下面介绍两种方案。
2. 解决方案
下面使用两种方案进行解决,默认引导都是通过弹层按钮实现。
方案一:设置视频自动播放,如果发生异常,则引导用户进行互动操作,然后再进行播放。
具体代码实现:
// 第一种方案:
async function play() {
try {
await vdo.play()
modal.style.display = 'none';
btn.removeEventListener('click', play)
} catch (error) {
// 失败显示引导
modal.style.display = 'flex'
btn.addEventListener('click', play)
}
}
play()
具体操作:
总结下:尝试播放视频,如果成功则隐藏模态框并移除按钮的事件监听器,如果失败则显示模态框并重新添加按钮的事件监听器。
报错如下:
方案二:先静音播放,然后根据是否能自动播放决定是否取消静音,如果:
- 能自动播放,取消静音
- 不能自动播放,引导用户进行互动操作后取消静音
具体代码实现:
// 第二种方案
async function play() {
vdo.muted = true;
vdo.play()
// 是否声音running判断是否自动播放
const ctx = new AudioContext()
const canAutoPlay = ctx.state === 'running'
ctx.close()
if (canAutoPlay) {
// 自动关闭静音
vdo.muted = false
modal.style.display = 'none';
btn.removeEventListener('click', play)
} else {
// 无声音显示声音
modal.style.display = 'flex'
btn.addEventListener('click', play)
}
}
具体操作:
总结一下:尝试以静音方式播放一个视频,是可以自动播放,根据音频上下文(AudioContext)的状态来判断视频是否能够自动播放。可以看到上述操作中声音是从开始关闭再到打开的。如果是则自动关闭静音,如果不是则弹出模态框进行用户引导。
完整代码:
<style>
.container {
position: relative;
}
video {
width: 400px;
height: 300px;
}
.modal {
width: 408px;
height: 300px;
position: absolute;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.3);
justify-content: center;
align-items: center;
z-index: 9;
}
.btn {
background-color: #4CAF50;
border: none;
color: white;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}
</style>
<div class="container">
<video src="./test.mp4" controls></video>
<div class="modal">
<!-- 开始播放/ -->
<button class="btn">打开声音</button>
</div>
</div>
<script>
const vdo = document.querySelector('video')
const modal = document.querySelector('.modal')
const btn = document.querySelector('.btn')
// 第一种方案:
async function play() {
try {
await vdo.play()
modal.style.display = 'none';
btn.removeEventListener('click', play)
} catch (error) {
console.log(error);
// 失败显示蒙层
modal.style.display = 'flex'
btn.addEventListener('click', play)
}
}
// 第二种方案
async function play() {
vdo.muted = true;
vdo.play()
const ctx = new AudioContext()
const canAutoPlay = ctx.state === 'running'
ctx.close()
if (canAutoPlay) {
vdo.muted = false
modal.style.display = 'none';
btn.removeEventListener('click', play)
} else {
// 无声音显示声音
modal.style.display = 'flex'
btn.addEventListener('click', play)
}
}
play()
</script>
3. 总结
最后总结一波:自动播放视频是因为浏览器有一系列的策略和限制。这些限制主要是出于用户体验的考虑,避免在未经用户允许的情况下自动播放视频或音频,从而打扰用户。
可以通过浏览器的内部页面(如chrome://media-engagement/
)来查看和了解媒体参与度。
针对无法自动播放的情况,有两种常见的解决方案。
- 尝试设置视频自动播放,如果播放失败,引导用户进行互动操作
- 先静音播放,然后根据是否能自动播放决定是否取消静音
如有错误,请指正O^O!
原文链接:https://juejin.cn/post/7352146376632582178 作者:一诺滚雪球