MediaRecorder分段录制摄像头生成MP4仅首个可播放问题求助
问题根因
- MediaRecorder输出的流式视频数据中,仅第一个
dataavailable事件返回的Blob包含完整的视频编码头信息,后续片段仅包含纯视频帧数据。播放器读取没有头信息的视频文件时,无法识别编码格式、分辨率、帧率等必要参数,自然无法正常播放。 - 你当前的逻辑是将每一段Blob单独解码存储为MP4文件,因此只有带头部的第一个文件可正常播放。
解决方案
根据你的业务需求可选择以下两种方案:
方案1:需要每个分段MP4都可独立播放
每次生成一个分段后,销毁当前MediaRecorder实例,重新创建新实例开启下一轮录制,每次新实例输出的第一个片段都会自动携带完整编码头:
componentDidMount() { navigator.mediaDevices .getUserMedia({ video: true}) .then(stream => { this.videoTag.current.srcObject = stream; this.handleSuccess(stream); }) .catch(console.log); } handleSuccess(stream) { this.stream = stream; // 封装录制启动逻辑,循环调用实现分段 const startNewRecord = () => { const media_recorder = new MediaRecorder(stream, { // 明确指定编码格式,避免浏览器默认差异导致后端解码失败 mimeType: 'video/webm;codecs=h264' }); media_recorder.start(10000); media_recorder.addEventListener('dataavailable', function (e) { // 停止当前录制,释放资源 media_recorder.stop(); // 原有上传逻辑不变 var reader = new FileReader(); reader.readAsDataURL(e.data); reader.onload = function () { const base64EncodedData = reader.result.split(',')[1]; const body = JSON.stringify({ data: base64EncodedData }); fetch('http://localhost:3090/api/recording', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body }).then(res => res.json()).then(json => console.log(json)); } // 立即启动下一段录制 startNewRecord(); }); } startNewRecord(); }
注意:该方案会存在毫秒级的录制间隙,普通业务场景可忽略。
方案2:仅需要最终完整MP4、不需要分段单独播放
服务端不要将每个片段单独存储为MP4,先按照前端上传的先后顺序拼接所有二进制片段,全部录制完成后再统一转码存储为MP4文件即可,拼接后的文件包含完整头信息+所有帧数据,可正常播放。
内容的提问来源于stack exchange,提问作者Allabakshu Shaik
相关产品推荐
相关产品推荐

