本文详解JavaScript中处理浏览器声音自动播放限制的方法,包括解决play()因用户未交互报错的问题。通过navigator.permissions.query查询麦克风、相机等权限状态,并利用getUserMedia等API设置权限,对比各浏览器支持情况。
近期遇到一个后端Socket推送警告消息的需求,需要在浏览器中弹出提示框并播放声音。但在初次打开页面时,声音播放失败,控制台报错如下:
错误信息:play() failed because the user didn't interact with the document first.
该错误表明,浏览器要求用户必须在当前页面进行至少一次交互操作,否则禁止自动播放音频。

方案一:手动开启浏览器声音权限,在浏览器地址栏输入对应链接进入设置页面。
(经测试,该链接无法通过a标签或JavaScript直接打开)
Google Chrome浏览器:chrome://settings/content/sound
Firefox浏览器:about:preferences#privacy
Edge浏览器:edge://settings/content/mediaAutoplay

方案二:当声音播放失败时,提示用户手动授权。只要用户与当前页面发生交互,浏览器便不再阻止播放。
// 加载声音
const sound = new Audio(`video.mp3`)
// 播放声音
sound.play()
.then((res) => {
console.log('视频播放成功')
})
.catch((error) => {
// if (error.message.indexOf('didn't interact') !== -1) 判断报错内容
// 如果视频播放失败在这里弹出提示框
alert('由于您的浏览器设置,报警声音无法自动播放,请点击确认按钮授权播放。')
})
目前尚未发现直接获取或设置声音权限的API,因此需通过交互引导用户授权。
上述为声音权限的解决方案,接下来介绍如何获取浏览器的麦克风、通知及视频权限。
1. 使用navigator.permissions.query API查询浏览器权限是否已开启。
// 查询麦克风权限
navigator.permissions.query({ name: 'microphone' })
.then((res) => {
if (res.state === 'granted') {
// 已授权
}
})
// 查询相机权限
navigator.permissions.query({ name: 'camera' })
.then((res) => {
if (res.state === 'denied') {
// 拒绝授权
}
})
返回的结果:{name: "", onchange: "", state: ""}以下权限列表均已通过测试验证。
microphone:麦克风权限
camera:相机权限
geolocation:地理位置信息权限
notifications:网站显示桌面通知权限
以及其他相关权限。
2. 通过navigator API设置浏览器允许特定权限。

// 设置麦克风权限
navigator.mediaDevices.getUserMedia({ audio: true })
.then((res) => {
// 允许麦克风权限
})
.catch((error) => {
// 拒绝麦克风权限
})
navigator.geolocation.getCurrentPosition(
() => {
// 允许地理位置权限
},
() => {
// 拒绝地理位置权限
})以下权限设置方法均已通过测试验证。
navigator.mediaDevices.getUserMedia({ audio: true }).then():用于获取麦克风权限。
navigator.mediaDevices.getUserMedia({ video: true }).then():用于获取摄像头权限。
navigator.geolocation.getCurrentPosition(callback):用于获取地理位置权限。
Notification.requestPermission().then():用于获取通知权限。
以及其他权限设置方式。
在Google、Firefox、Safari、Edge浏览器上测试发现,仅Google浏览器完全支持上述功能,其他浏览器仅部分支持。
总结
本文介绍了JS获取浏览器声音、麦克风及通知权限的方法,更多相关内容可搜索本站历史文章或继续浏览后续文章,感谢支持!