如何在兼容浏览器中用Web API AudioEncoder录制并生成可解码Opus帧
使用Web API AudioEncoder生成兼容标准Opus解码器的实时音频帧
我需要用AudioEncoder生成能被标准Opus解码器(如discordjs的Opus解码器)兼容的音频块,要求像旧的ScriptProcessor那样实时输出数据块,而非等待录制停止后再获取完整音频。
之前的两种方案存在局限:
- MediaRecorder需停止录制才会输出数据,无法满足实时需求;
- ScriptProcessor已被浏览器弃用,不推荐继续使用。
核心实现思路
利用现代Web API组合实现:
- 获取指定参数的音频媒体流(采样率16000Hz、单声道,匹配Opus语音场景);
- 配置AudioEncoder为Opus编码,设置实时输出回调;
- 通过MediaStreamTrackProcessor实时读取音频数据并送入编码器,生成独立的Opus帧。
完整代码示例
// 1. 获取符合要求的音频流 const stream = await navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 16000, // Opus语音场景推荐采样率 channelCount: 1, // 单声道兼容性更好 echoCancellation: true // 可选,根据需求开启降噪 } }); const audioTrack = stream.getAudioTracks()[0]; // 2. 初始化AudioEncoder,配置Opus编码参数 const opusFrames = []; // 存储实时生成的Opus帧 const encoder = new AudioEncoder({ output: (chunk) => { // 编码后的原始Opus帧,可直接传入标准Opus解码器 const opusFrame = new Uint8Array(chunk.data); opusFrames.push(opusFrame); // 这里可实时处理帧,比如发送到服务器或解码器 console.log('生成Opus帧,长度:', opusFrame.length); }, error: (err) => { console.error('编码错误:', err); } }); // 关键配置:必须和输入音频参数匹配 encoder.configure({ codec: 'opus', sampleRate: 16000, numberOfChannels: 1, bitrate: 64000, // 语音场景推荐64kbps,可根据需求调整 opus: { mode: 'voice' // 针对语音优化,提升解码器兼容性 } }); // 3. 实时读取音频数据并编码 const trackProcessor = new MediaStreamTrackProcessor({ track: audioTrack }); const reader = trackProcessor.readable.getReader(); async function processAudioFrames() { while (true) { const result = await reader.read(); if (result.done) break; // 将获取到的AudioData送入编码器 encoder.encode(result.value); // 无需手动flush,编码器会实时输出完整帧 } } // 启动实时处理 processAudioFrames(); // 停止录制的方法 function stopRecording() { audioTrack.stop(); reader.cancel(); encoder.flush(); // 确保最后一帧被输出 encoder.close(); }
关键注意事项
- 参数一致性:输入音频的采样率、声道数必须与编码器配置完全一致,否则会出现编码错误或解码失败;
- Opus帧格式:编码器输出的
chunk.data是原始Opus帧,无需封装在Ogg等容器中,可直接被标准Opus解码器识别; - API兼容性:MediaStreamTrackProcessor和AudioEncoder均为现代Web API,需确保浏览器支持;
- 性能优化:避免在
output回调中执行耗时操作,以免阻塞编码流程。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

