页面刷新后,能否通过MediaRecorder继续录制至原文件?
能否在浏览器刷新后继续录制到同一文件?
直接在刷新页面后继续写入到刷新前的同一个文件是不可能的——浏览器刷新会完全销毁当前页面的所有上下文:包括MediaRecorder实例、内存中的录制数据,以及对任何临时/本地文件的引用都会被清空,没有办法恢复之前的录制状态和文件句柄。
不过可以通过分段录制+本地存储+后期合并的方式实现类似效果,最终得到一个完整的录制文件,具体方案如下:
可行的替代方案
1. 分段录制并存储到IndexedDB
- 录制时不要一次性生成完整文件,而是每隔固定时长(比如10秒)生成一个录制分段(Blob),将这些分段存储到
IndexedDB中(它支持存储大体积的Blob数据,比localStorage更适合)。 - 页面刷新后,重新获取媒体流、创建新的
MediaRecorder实例,继续录制新的分段并追加到存储中。 - 用户主动停止录制时,从
IndexedDB中取出所有分段,合并成一个完整的Blob文件,再提供下载。
2. 关键注意事项
- 确保所有录制分段的编码格式一致(比如统一用
video/webm),否则合并后的文件无法正常播放。 - 浏览器会记住之前的媒体设备授权,刷新后可以自动重新获取流,但部分浏览器可能需要用户交互触发(比如点击页面按钮)才能重新调用
getUserMedia。 - 录制过程中如果用户关闭浏览器,未完成的分段会保留在IndexedDB中,下次打开页面可以继续录制。
简单示例代码
// 初始化IndexedDB用于存储录制分段 let recordingDB; function initRecordingDB() { const openRequest = indexedDB.open('RecordingSegments', 1); openRequest.onupgradeneeded = (event) => { recordingDB = event.target.result; // 创建存储分段的对象仓库 recordingDB.createObjectStore('segments', { keyPath: 'id', autoIncrement: true }); }; openRequest.onsuccess = (event) => { recordingDB = event.target.result; }; } // 开始/恢复录制 function startRecording(stream) { const mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm' }); // 每10秒生成一个分段并存储 mediaRecorder.start(10000); mediaRecorder.ondataavailable = (event) => { if (event.data.size > 0) { const transaction = recordingDB.transaction('segments', 'readwrite'); const store = transaction.objectStore('segments'); store.add({ blob: event.data }); } }; // 绑定停止按钮逻辑 document.getElementById('stop-recording').addEventListener('click', () => { mediaRecorder.stop(); mergeAndDownloadSegments(); }); } // 合并所有分段并下载 function mergeAndDownloadSegments() { const transaction = recordingDB.transaction('segments', 'readonly'); const store = transaction.objectStore('segments'); const getAllRequest = store.getAll(); getAllRequest.onsuccess = () => { const allBlobs = getAllRequest.result.map(item => item.blob); const mergedBlob = new Blob(allBlobs, { type: 'video/webm' }); // 生成下载链接 const downloadUrl = URL.createObjectURL(mergedBlob); const aTag = document.createElement('a'); aTag.href = downloadUrl; aTag.download = 'complete-recording.webm'; aTag.click(); // 清空存储的分段 const clearTransaction = recordingDB.transaction('segments', 'readwrite'); clearTransaction.objectStore('segments').clear(); }; } // 页面加载时初始化并尝试恢复录制 window.addEventListener('load', () => { initRecordingDB(); // 重新获取媒体流 navigator.mediaDevices.getUserMedia({ video: true, audio: true }) .then(stream => startRecording(stream)) .catch(err => console.error('获取媒体流失败:', err)); });
内容的提问来源于stack exchange,提问作者Vlodko
相关产品推荐
相关产品推荐

