Tutorial: 自动播放受限处理建议

自动播放受限处理建议

浏览器自动播放限制(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 错误解决方法】捕获自动播放错误,恢复远端流的播放。