浏览器自动播放限制(0x4043错误)
前言
为防止网页自动播放音视频对用户造成干扰,浏览器对视频的自动播放做了限制:在没有用户交互之前,网页将被禁止播放带有声音的媒体。
受上述浏览器自动播放策略影响,当用户使用 WebRTC 播放远端流时,将有可能捕获 0x4043 错误。
本文介绍 Chrome 和 Safari 浏览器的自动播放限制策略,并提供 0x4043 错误的解决方法供 WebRTC 接入方参考。
Chrome 浏览器限制策略
Chrome 浏览器自动播放策略:
- 允许网页自动播放静音媒体
- 以下情况允许网页自动播放有声媒体
- 用户已经与同域名下的网页进行了交互(点击,tap 等)。
- 在 PC 上,用户在该网页中的的
媒体参与指数
足够高。 - 在移动设备上,用户将该网页添加到了主屏幕。
- 页面可以授予自动播放权限给它嵌套的 iframe 以允许自动播放声音。
媒体参与指数(Media Engagement Index)(MEI)
MEI 用来衡量用户在网站上消费媒体的倾向。
Chrome 目前获取 MEI 的方法是分析用户在各个页面中满足以下条件的媒体播放比率:
- 用户对媒体(音频/视频)的消耗大于7秒。
- 音频必须存在且没有静音。
- 视频所在的网页tab处于活动状态。
- 视频大小(以像素为单位)大于200x140。
Chrome 浏览器计算用户在各个网页的媒体参与指数,该指数与用户在网页中播放媒体的次数成正相关。当用户对网页的媒体参与指数足够高时,该网页将在 PC 上获得自动播放有声媒体的权限。(用户的MEI值可以通过 chrome://media-engagement/ 查看)
更多 Chrome 自动播放策略信息,请查看 Chrome 自动播放限制策略。
Safari 浏览器限制策略
Safari 浏览器使用自动推理引擎来阻止绝大多数网站自动播放媒体元素。
更多 Safari 自动播放策略信息,请查看 Safari 自动播放限制策略。
0x4043 错误解决方法
当您在使用 stream.play
接口播放视频的过程中,如果受到浏览器自动播放策略的限制不能正常播放视频,您将会捕捉到错误编码为 0x4043 的错误提醒。
v4.8.4 以下版本, 请使用以下方式捕捉并处理 0x4043 错误
stream.play('remote').then(() => {
// auto-play success
}).catch((error) => {
const errorCode = error.getCode();
if (errorCode === 0x4043) {
// PLAY_NOT_ALLOWED,引导用户手势操作并调用 stream.resume 恢复音视频播放
// stream.resume()
}
});
v4.8.4 及其以上版本, 强烈建议使用 stream 监听 error
的方式捕捉并处理 0x4043 错误
stream.play('remote').catch(error => {});
stream.on('error', error => {
const errorCode = error.getCode();
if (errorCode === 0x4043) {
// PLAY_NOT_ALLOWED,引导用户手势操作并调用 stream.resume 恢复音视频播放
// stream.resume()
}
})
⚠️注意: 由于本地流的播放为静音播放,0x4043 错误仅发生在远端流播放时,所以只需要处理远端流的错误事件。
如何避免 0x4043 错误
方案一、 静音播放远端视频流,等到用户与页面发生交互后解除静音
1) 为页面添加交互监听事件
// 监听用户鼠标事件,replay 方法在第三步定义
document.addEventListener('mousedown', replay)
或者
// 监听用户触屏事件, replay 方法在第三步定义
document.addEventListener('touchstart', replay)
2)创建远端流 stream, 在调用 play 接口时通过 muted 参数设置静音播放视频
stream.play('containerId', { muted: true })
3)当页面监听到 mousedown 或者 touchstart 事件后, 执行回调函数
let replay = () => {
stream.stop()
stream.play('containerId', { muted: false })
// 移除用户鼠标事件监听
document.removeEventListener('mousedown', replay)
// 移除用户触屏事件监听
document.removeEventListener('touchstart', replay)
}
⚠️注意:该方法在 iOS 微信拉流时,会出现视频自动播放失败的情况。因此,若您的使用场景包含 iOS 微信拉流, 请参考方案二。
方案二、 提前引导用户与页面产生交互
确保在调用 stream.play
之前,通过弹窗指引或按钮点击等方式要求用户进行必要的点击操作。
自动播放问题总结
大部分的浏览器在用户交互之后就放开了 AutoPlay 限制,使用【提前引导用户与页面产生交互】的方式可以有效规避桌面端以及安卓设备上的自动播放错误。
由于 iOS safari/webview 只允许用户交互来触发有声媒体的播放,因此在 iOS safari/webview 中请参考【0x4043 错误解决方法】捕获自动播放错误,恢复远端流的播放。