如何让MediaRecorder API生成的单个分片可独立播放,同时避免分段录制的卡顿问题
如何让MediaRecorder API生成的单个分片可独立播放,同时避免分段录制的卡顿问题
嗨,我完全懂你现在的困扰——既要让每个录制的分片能单独播放,又不想因为频繁启停MediaRecorder导致视频出现卡顿,确实是个两难的问题。不过别担心,咱们可以换个思路来解决,不用反复重启Recorder实例就能达到目的:
利用MediaRecorder原生的时间分片功能,告别频繁启停
其实MediaRecorder本身就支持按指定时长自动生成分片,你只需要在调用start()方法时传入一个时间片参数(比如3000毫秒),它就会在同一个录制会话里,每隔指定时间输出一个完整的Blob分片,完全不需要销毁再重建Recorder实例,这样就能彻底避免启停带来的延迟和卡顿了。不过这里有个关键:必须选择支持碎片化编码的容器格式,比如碎片化MP4(fMP4)或者WebM VP9,这类格式的每个分片都包含独立播放所需的元数据,不会像普通MP4那样只有第一个分片有完整头部。
给你修改一下你的代码示例,看看具体怎么实现:
const startVideoRecording = async (screenStream: MediaStream, audioStream: MediaStream) => { setStartingRecording(true); try { const res = await getVideoId(); videoId.current = res; // 合并屏幕流和音频流 const combinedStream = new MediaStream([ ...screenStream.getTracks(), ...audioStream.getTracks() ]); // 优先选择碎片化MP4格式(兼容性好,适合流式传输) const recorderOptions = { mimeType: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' // 备选WebM格式:'video/webm; codecs="vp9, opus"' }; // 检测浏览器是否支持所选格式,不支持就降级 if (!MediaRecorder.isTypeSupported(recorderOptions.mimeType)) { recorderOptions.mimeType = 'video/webm; codecs="vp8, opus"'; } const mediaRecorder = new MediaRecorder(combinedStream, recorderOptions); recorder.current = mediaRecorder; // 每3秒生成一个分片,无需重启Recorder mediaRecorder.start(3000); // 监听分片生成事件,拿到分片后直接发服务器 mediaRecorder.ondataavailable = (event) => { if (event.data.size > 0) { // 这里调用你的上传逻辑,把Blob分片发送到Rails服务器 sendChunkToServer(event.data, videoId.current); } }; // 录制结束后的收尾操作 mediaRecorder.onstop = () => { combinedStream.getTracks().forEach(track => track.stop()); setStartingRecording(false); }; } catch (error) { console.error('录制初始化出错:', error); setStartingRecording(false); } };服务器端配合处理碎片化分片
因为你用的是fMP4或WebM这类流式友好的格式,你的Rails服务器上的FFmpeg可以直接处理这些分片:- 如果要转成HLS流,单个分片可以直接转成HLS片段;
- 如果需要拼接多个分片再转HLS,也能通过FFmpeg的concat协议轻松完成,因为所有分片的编码格式都是一致的,拼接不会有兼容性问题。
举个FFmpeg处理的简单示例(命令行伪代码):
# 将单个fMP4分片转成HLS片段 ffmpeg -i received_chunk.mp4 -c:v copy -c:a copy -hls_time 3 -hls_list_size 0 output_stream.m3u8
这样一来,你既不需要频繁重启MediaRecorder导致卡顿,生成的每个分片又能独立播放,同时也能顺畅地在服务器端转成HLS流上传到S3,完美解决你的需求~
备注:内容来源于stack exchange,提问作者tedGuy
相关产品推荐
相关产品推荐

