Safari调用enumerateDevice()不显示audiooutput设备
问题产生原因
- 这是浏览器原生API实现差异导致的,和代码调用逻辑、权限申请状态无关:Safari基于WebKit内核,全端稳定版(桌面端、iOS/iPadOS端)默认未实现W3C标准的Audio Output Devices API,既不支持
navigator.mediaDevices.enumerateDevices()返回audiooutput类型设备,也没有实现配套的音频输出切换接口HTMLMediaElement.prototype.setSinkId,自然不会在枚举结果里展示音频输出类设备。 - 观测到
audioinput、videoinput设备正常返回,恰恰说明当前页面已经拿到了足够的媒体访问权限,不存在权限拦截导致输出设备不展示的问题。 - 目前仅Safari技术预览版、最新版开发者测试版把音频输出设备相关能力放在实验性功能列表里,默认处于关闭状态,需要用户手动在「开发-实验性功能」中手动开启
Audio Output Devices API开关才能生效,普通用户默认配置下完全无法使用该能力,生产环境不能依赖这个实验特性做逻辑。 - Chrome、Edge等Chromium内核浏览器很早之前就完整落地了Audio Output Devices API的全量实现,所以可以正常枚举
audiooutput类型设备、调用接口切换音频输出目标,和Safari的表现差异是内核实现进度不同导致的。
适配解决方案
- 优先做特性检测做逻辑分支,不要通过UA嗅探判断能力,避免未来Safari默认开启该能力后出现逻辑误判,检测参考代码:
// 检测当前环境是否支持音频输出设备枚举与切换 async function checkAudioOutputSupport() { // 先判断核心输出切换API是否存在 if (typeof HTMLMediaElement.prototype.setSinkId !== 'function') { return false; } // 注意:必须在用户授予麦克风/摄像头媒体权限后,枚举结果才会返回完整的设备信息 const devices = await navigator.mediaDevices.enumerateDevices(); return devices.some(device => device.kind === 'audiooutput'); }
- 针对检测后确认不支持音频输出枚举的环境(包含默认配置的稳定版Safari),直接隐藏页面上的音频输出设备选择交互入口,增加明确提示:当前浏览器不支持自定义音频输出设备,将默认使用系统选定的播放设备输出声音,不要强行调用相关API,否则会抛出未定义的JS异常。
- 如果业务场景强依赖音频输出设备切换能力,可在不支持的环境下增加引导提示,建议用户使用Chrome、Edge等Chromium内核浏览器访问对应功能模块。
- 额外适配注意:即便是在支持音频输出枚举的浏览器中,未获得麦克风/摄像头授权的状态下,枚举返回的设备信息会做脱敏处理,设备ID、设备名称字段均为空值,注意和浏览器本身不支持能力的场景做区分。
现象参考


内容的提问来源于stack exchange,提问作者Mac EiEi
相关产品推荐
相关产品推荐

