如何从mediaDevices.getUserMedia音频流获取采样率解决Firefox报错
Firefox 环境下MediaStream与AudioContext采样率不匹配问题的解决方案
核心现状
- 按照Web标准的定义,
MediaStreamTrack的getSettings()方法本就应该返回带sampleRate字段的对象,但Firefox当前版本的引擎实现有缺口,不会在settings、constraints、capabilities的返回值里暴露这个字段,这就是你之前用这些接口读不到采样率的根本原因。 - 目前没有任何公开API可以同步直接从MediaStream音频轨道上读到采样率,针对Firefox的这个引擎限制,有两个能实际落地的规避方案。
方案1:别在初始化AudioContext的时候手动写自定义采样率
- 初始化时硬传
sampleRate: 48000是触发这个报错最常见的原因。不指定这个参数的话,Firefox会自动用当前音频硬件的原生采样率来初始化AudioContext,从根上避免和硬件、输入流的采样率不匹配问题。 - 调整后的初始化代码示例:
navigator.mediaDevices.getUserMedia(constraints).then(stream => { // 不传自定义sampleRate,自动匹配硬件原生采样率 const context = new (window.AudioContext || window.webkitAudioContext)(); // 修正原示例里的变量引用问题:局部定义的是context,不是挂在this上的context const audioInput = context.createMediaStreamSource(stream); });
- 这个方案的额外好处是各个浏览器的兼容一致性最好,也不会触发跨采样率重采样带来的性能损耗。
方案2:如果业务必须用固定采样率,就先探测流的实际采样率
如果你的业务场景确实需要AudioContext固定用某一个采样率,完全可以用低成本探测的方式拿到输入流和硬件匹配的实际采样率,避免一上来就抛错:
- 实现逻辑很简单:
- 先建一个不带自定义采样率参数的临时AudioContext,这个上下文会自动匹配当前音频硬件、输入流的实际采样率
- 直接读临时上下文的
sampleRate属性,拿到的值就是当前MediaStream对应的实际采样率 - 拿到采样率之后,再根据业务需求创建对应参数的正式业务用AudioContext
- 探测逻辑的示例代码:
// 临时上下文会自动匹配硬件和流的实际采样率 const tempContext = new AudioContext(); // 读取实际采样率值 const actualStreamSampleRate = tempContext.sampleRate; // 用完及时把临时上下文关掉,释放资源 await tempContext.close(); // 之后再按需创建固定采样率的业务上下文 const businessContext = new AudioContext({ sampleRate: 48000 });
- 要注意:如果探测到的实际采样率和你业务要求的采样率对不上,在Firefox环境下别硬把不同采样率上下文的AudioNode连起来,不然还是会抛你遇到的那个
DOMException错误。
补充说明:Firefox的引擎目前还没做跨采样率AudioNode连接的自动重采样能力,也没完全对齐Web标准里MediaStreamTrack要暴露采样率属性的要求,这个限制是引擎层面的实现缺口,不是你业务代码写错了。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

