写在前面
有一次在做视频播放的时候,我想让页面打开的时候,视频就自动播放,不需要用户自己手动点击播放按钮,但是直接执行video的play方法,报错如下:
Uncaught (in promise) DOMException: play() failed because the user didn’t interact with the document first.
大概意思就是因为用户没有与页面进行交互操作,经过测试等包括代码执行click一样的,均无效,必须是用户自己真实的页面操作。
寻找原因
那为什么我刷的网页抖音,可以直接播放呢? 浏览器video自动播放,它是有要求的,要在它的规则下才能自动播放,如下:MDN Autoplay guide for media and Web Audio APIs
浏览器觉得音频轨道的视频如果直接自动播放会打扰到用户,以下情况除外
之所以抖音,哔哩哔哩,可以自动播放是因为他们上了白名单,浏览器会根据这个页面打开次数,看视频的时长等等因素算出一个指数,指数高了这个地址才能拥有直接自动播放权限,这个我们开发者没有办法干涉。见下chrome://media-engagement/,复制在浏览器打开
那一开始抖音b站他们并不能自动播放,他们的方案是什么呢,我们可以根据第一条,如果视频是静音状态下就可以自动播放,所以抖音在自动播放的时候失败的时候,他会选择静音播放,提示打开声音,用户点击,于是有了第二个条件,视频就可以带着声音播放了。
所以解决这个问题步骤:
- 看是否能自动播放,如果可以正常播放
- 如果不行,则静音播放,引导用户进行点击,有交互行为
参考代码:
<!DOCTYPE html>
<html lang="en">
<title>视频不能播放的问题</title>
<style>
* {
margin: 0;
padding: 0;
}
.mask {
display: flex;
position: absolute;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.3);
height: 360px;
width: 640px;
justify-content: center;
align-items: center;
visibility: hidden;
}
.on {
visibility: visible;
}
button {
background-color: #4CAF50;
/* Green */
border: none;
color: white;
padding: 16px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
-webkit-transition-duration: 0.4s;
/* Safari */
transition-duration: 0.4s;
cursor: pointer;
}
</style>
<body>
<video
src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
id="video"
controls
autoplay></video>
<div class="mask">
<button id="btn">打开声音</button>
</div>
<script>
// video.play方法返回的是一个promise,失败会reject然后触发catch
const play = async () => {
try {
await video.play()
// 取消静音静音
video.muted = false
}
catch (err) {
// 添加蒙层和
document.getElementsByClassName("mask")[0].classList.add("on")
// 设置静音
video.muted = true
video.playbackRate = 10
video.play()
}
}
play()
document.getElementById("btn").addEventListener("click", () => {
play()
})
</script>
</body>
</html>
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END