react-media-recorder在Safari录音后无法播放?求跨浏览器解决方案
React 语音录制兼容 Safari 最简实现方案
Safari 对 MediaRecorder 的编码格式支持与 Chrome 存在差异,默认的 webm 格式在 Safari 中无法正常解码播放,需要指定兼容的 MIME 类型(如 audio/mp4;codecs=mp4a.40.2)。以下是不依赖第三方库、直接基于原生 API 实现的兼容 Chrome 和 Safari 的最简代码:
import { useState, useRef, useEffect } from 'react'; const VoiceRecorder = () => { const [isRecording, setIsRecording] = useState(false); const [recordedBlob, setRecordedBlob] = useState(null); const [audioUrl, setAudioUrl] = useState(null); const mediaRecorderRef = useRef(null); const audioRef = useRef(null); const chunksRef = useRef([]); // 请求麦克风权限并初始化录音 const startRecording = async () => { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); // 指定兼容 Safari 的编码格式 const mimeType = 'audio/mp4;codecs=mp4a.40.2'; const mediaRecorder = new MediaRecorder(stream, { mimeType }); mediaRecorderRef.current = mediaRecorder; chunksRef.current = []; mediaRecorder.ondataavailable = (e) => { if (e.data.size > 0) { chunksRef.current.push(e.data); } }; mediaRecorder.onstop = () => { const blob = new Blob(chunksRef.current, { type: mimeType }); setRecordedBlob(blob); // 创建可播放的音频 URL const url = URL.createObjectURL(blob); setAudioUrl(url); // 停止媒体流,释放麦克风资源 stream.getTracks().forEach(track => track.stop()); }; mediaRecorder.start(); setIsRecording(true); } catch (err) { console.error('录音初始化失败:', err); alert('无法访问麦克风,请检查权限设置'); } }; const stopRecording = () => { if (mediaRecorderRef.current && isRecording) { mediaRecorderRef.current.stop(); setIsRecording(false); } }; const playRecording = () => { if (audioUrl && audioRef.current) { audioRef.current.play().catch(err => { console.error('播放失败:', err); alert('音频无法播放,请检查浏览器设置'); }); } }; // 组件卸载时清理 ObjectURL,避免内存泄漏 useEffect(() => { return () => { if (audioUrl) { URL.revokeObjectURL(audioUrl); } }; }, [audioUrl]); return ( <div> <button onClick={isRecording ? stopRecording : startRecording}> {isRecording ? '停止录音' : '开始录音'} </button> {recordedBlob && ( <button onClick={playRecording} style={{ marginLeft: '10px' }}> 播放录音 </button> )} <audio ref={audioRef} src={audioUrl} controls style={{ display: 'block', marginTop: '10px' }} /> </div> ); }; export default VoiceRecorder;
关键兼容说明:
- MIME 类型指定:必须明确使用
audio/mp4;codecs=mp4a.40.2,这是 Safari 原生支持的音频编码格式,Chrome 也兼容该格式。 - 媒体流清理:录音停止后主动停止麦克风流,避免持续占用设备资源。
- ObjectURL 管理:组件卸载时调用
URL.revokeObjectURL释放内存,防止内存泄漏。 - 播放异常处理:调用
play()时捕获异常,处理 Safari 中严格的自动播放限制(需用户交互触发播放)。
内容的提问来源于stack exchange,提问作者aurelien_morel
相关产品推荐
相关产品推荐

