Safari中MediaRecorder API录制音频返回application/octet-stream类型求助
解决方案
1. 优先检测Safari支持的有效MIME类型
Safari对MediaRecorder的编码支持和Chrome存在差异,不兼容audio/mp4; codecs=opus组合,但原生支持audio/mp4; codecs=aac格式。初始化MediaRecorder前先检测浏览器支持的类型,避免硬编码不兼容格式:
// 检测浏览器支持的音频MIME类型 function getSupportedAudioMimeType() { const candidateTypes = [ 'audio/mp4; codecs=aac', // Safari优先适配 'audio/webm; codecs=opus', // Chrome优先适配 'audio/wav' // 通用无压缩格式 ]; return candidateTypes.find(type => MediaRecorder.isTypeSupported(type)); } // 初始化MediaRecorder时使用检测到的类型 const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const supportedType = getSupportedAudioMimeType(); const mediaRecorder = new MediaRecorder(stream, { mimeType: supportedType });
2. 不要事后修改Blob类型
你之前直接修改Blob的type属性仅修改了元数据,并未改变音频数据本身的编码和容器格式,服务器自然无法识别。必须让MediaRecorder从录制开始就输出符合要求的格式,这才是根本解决思路。
3. 手动指定Base64的MIME前缀
转换Base64时,忽略Safari可能返回错误的application/octet-stream,手动关联检测到的有效MIME类型前缀:
// 将Blob转换为带正确MIME前缀的Base64 function blobToBase64(blob, targetMimeType) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => { // 替换默认的错误前缀,替换为目标MIME类型 const base64Data = reader.result.replace( 'data:application/octet-stream;base64,', `data:${targetMimeType};base64,` ); resolve(base64Data); }; reader.onerror = reject; reader.readAsDataURL(blob); }); } // 使用示例 const base64Audio = await blobToBase64(recordingBlob, supportedType);
4. 备选方案:用兼容性库简化处理
如果上述方法仍有问题,可使用RecordRTC这类跨浏览器录制库,它会自动适配Safari的编码规则,直接输出标准音频格式:
// 引入RecordRTC后使用 const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const recorder = RecordRTC(stream, { type: 'audio', mimeType: 'audio/mp4' // 选择服务器支持的格式 }); recorder.startRecording(); // 停止录制后获取合规Blob recorder.stopRecording(() => { const validBlob = recorder.getBlob(); // 后续转换Base64并发送至服务器 });
内容的提问来源于stack exchange,提问作者dhruvin vaghasiya
相关产品推荐
相关产品推荐

