【web音频学习(二)】 获取设备播放和麦克风权限

363 阅读4分钟

码云地址

音频播放

根据 MDN 文档,音频自动播放需满足以下任一条件:

  • 音频被静音或音量为 0。
  • 用户已与页面发生交互(点击、触摸、按键等)。
  • 站点已列入浏览器 自动播放白名单

实际开发中通常采用第②种方案(交互后播放)。

自动播放白名单

PC端Chrome 浏览器 的音频自动播放限制相对“人性化”,它引入了一个名为 MEI(Media Engagement Index,媒体参与指数) 的策略。 该策略的核心逻辑是:

当用户在某个网页上主动进行一系列“可信的媒体消费行为”后,Chrome 会为该域名积累 MEI 分数。 一旦该分数达到最低阈值(通常为 0.2),未来访问该站时,即使无用户点击,也允许自动播放带声音的音频

用户可在地址栏输入 chrome://media-engagement/ ,查看各域名的 MEI 分数与详细记录。

有效增加 MEI 分数的“操作”

  • 音频必须未静音muted 标签或 volume=0 不计入)。
  • 播放过程中,当前标签页必须保持在前台且页面可见(切换标签或最小化窗口会整段作废)。
  • 单次有效播放时长 ≥7 秒(暂停若在 5 s 内恢复,计时累加;否则重新从 0 计算)。
  • 播放必须由真实的用户点击、键盘、触摸事件启动(脚本直接 audio.play() 不计入)。
  • 通常需要 ≥20 次有效会话可信播放次数 ÷ 总访问次数(即 chrome://media-engagement/ 页面中的 Playback rate)≥0.2,该域名即可进入 Chrome 本地的自动播放白名单。

如何清理浏览器记录的 MEI 数据

白名单实时写入本地 MEI 数据库,不随缓存清除而丢失,但用户手动“站点设置→重置权限”或“清空浏览数据→Cookie 及其他站点数据”会归零。

开发者速查

  • 本地测试:chrome://media-engagement/Score 列,≥0.2 即已进白名单

    image-20250914155017489

  • 强制清空:chrome://settings/content/sound

    image-20250914155105826

  • 命令行绕过:--autoplay-policy=no-user-gesture-required(仅调试使用)

    1. 找到浏览器的快捷方式(桌面或开始菜单)。

    2. 右键 → 属性 → 找到 “目标” 字段。

    3. 在原有路径后面加一个空格,然后添加:

      --autoplay-policy=no-user-gesture-required
      

      示例:

      "C:\Program Files\Google\Chrome\Application\chrome.exe" --autoplay-policy=no-user-gesture-required
      
    4. 点击 应用确定

    image-20250914155625245

其他的浏览器的自动播放

移动端浏览器(Android Chrome / Edge / 各类 WebView/iOS / iPadOS)
  • 永久白名单:即使 MEI ≥ 0.2,带声音 autoplay 仍被拦截;每次新导航都要重新拿手势。
  • 用户首次交互:静音自动播放可以全程可用;有声预加载或静音→出声都必须在用户第一次点/触之后才能放行。

结论:统一按“静音起步 → 首次点击升音量”落地,可包全场。

注意点

  • 在 iOS 中,播放音频必须先获取麦克风权限,再获取音频播放权限,否则无法正常播放。
  • 在 iOS 中,通过内网 IP 地址访问网页时无法播放音频,原因是该内网 IP 地址环境下无法获取麦克风权限。可以通过内网穿透将内网 IP 映射为公网域名访问。
  • 在 PC 中,可通过预检测 AudioContext 状态,若为 running,则认为站点已列入浏览器自动播放白名单。 在 H5 不能预检测 AudioContext 状态。
  • 在 iOS 中,即使用户已与页面发生交互,AudioContext 状态也不会直接变成 running,仍需如下操作:
    1. 调用 resume 方法并成功返回,注意首次调用可能(暂未找到规律)在 resume 方法调用 一直卡住,需做超时处理。
    2. 等待 50 ms。
    3. 最终校验 AudioContext 是否为 running 状态。

交互实现

在 iOS中,获取音频播放权限,必须先获取麦克风权限

实战效果

用户初始进入时,因为并没有和网页产生交互,所以是静音状态。

  • 在 PC、Android中,当用户点击”打开声音“,就等于和网页产生了点击交互,也就能顺利获取音频播放权限。

  • 在 iOS 中,用户点击”打开声音“,首先需要获取浏览器麦克风权限,才能顺利获取音频播放权限。

image-20250904112148173

麦克风

根据 MDN 文档,调用 navigator.mediaDevices.getUserMedia 需同时满足:

  • 安全上下文(HTTPS)。
  • 用户明确授权。
  • 顶级文档上下文,或通过 Permissions-Policy 授权的 <iframe>

前两条必须同时满足;若页面嵌入 <iframe>,还需满足第三条。

注意点

  • 在 iOS 中,通过内网 IP 地址访问网页时无法获取麦克风权限。通过内网穿透将内网 IP 映射为公网域名访问。
  • 浏览器会永久缓存用户的麦克风权限决定;若用户首次弹框即拒绝,后续将默认拒绝。
  • 在小米安卓手机中,如果用户拒绝了麦克风权限,后续调用 navigator.mediaDevices.getUserMedia 一直卡住,需做超时处理。

交互实现

实战效果