如何将getUserMedia捕获的视频保存为文件后上传至服务器?
如何在浏览器中录制视频并保存/上传文件?
看起来你已经搞定了媒体流的获取和实时显示,但要保存录制的视频,直接操作MediaStreamTrack是行不通的——这些track只是实时的媒体源,不是已经编码好的文件数据。你需要用MediaRecorder API来捕获并编码整个流的内容,生成可保存的Blob文件。
下面是调整后的完整代码,我会标注关键修改点:
<html> <body> <video id="video" playsinline autoplay></video> <button onclick="start()">Start</button> <button onclick="stop()">Stop</button> <!-- 可选:添加下载链接 --> <a id="downloadLink" style="display:block;margin-top:10px;">下载录制视频</a> <script> // 全局变量存储录制器和数据块 let mediaRecorder; let recordedChunks = []; function hasGetUserMedia() { return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia); } if (hasGetUserMedia()) { console.log("Good to go"); } else { console.log('Not supported'); } const constraints = { video: true, audio: true }; function start(){ navigator.mediaDevices.getUserMedia(constraints) .then((stream) => { const videoEl = document.getElementById('video'); videoEl.srcObject = stream; // 初始化MediaRecorder,指定录制格式(webm是主流支持的格式) mediaRecorder = new MediaRecorder(stream); // 监听数据可用事件,收集录制的媒体块 mediaRecorder.ondataavailable = (e) => { if (e.data.size > 0) { recordedChunks.push(e.data); } }; // 录制结束后处理生成文件 mediaRecorder.onstop = () => { // 将收集的块合并成Blob const recordedBlob = new Blob(recordedChunks, { type: 'video/webm' }); // 重置数据块,方便下次录制 recordedChunks = []; // 生成下载链接 const downloadLink = document.getElementById('downloadLink'); downloadLink.href = URL.createObjectURL(recordedBlob); downloadLink.download = 'my-recording.webm'; // --- 这里可以添加上传到服务器的代码 --- // 使用fetch发送Blob到服务器 fetch('/upload-video', { method: 'POST', body: recordedBlob, headers: { 'Content-Type': 'video/webm' // 根据实际格式调整 } }) .then(response => response.json()) .then(data => console.log('上传成功:', data)) .catch(error => console.error('上传失败:', error)); }; // 开始录制(时间片可选,这里设为1000ms,不设也可以) mediaRecorder.start(1000); console.log("录制已开始"); }) .catch(err => console.error('获取媒体流失败:', err)); } function stop(){ if (mediaRecorder && mediaRecorder.state !== 'inactive') { // 停止录制,会触发onstop事件 mediaRecorder.stop(); // 同时停止媒体流的track,释放设备资源 const videoEl = document.getElementById('video'); const stream = videoEl.srcObject; stream.getTracks().forEach(track => track.stop()); console.log("录制已停止"); } } </script> </body> </html>
关键修改说明:
- MediaRecorder初始化:在获取到媒体流后,创建
MediaRecorder实例,它负责把实时流编码成可保存的媒体文件。 - 数据收集:通过
ondataavailable事件收集录制过程中的媒体数据块,这些块会在录制停止后合并成完整的Blob。 - 录制结束处理:
onstop事件触发时,把收集的数据块合并成Blob,这时候就可以生成下载链接,或者直接用fetch上传到服务器。 - 停止流:停止录制后,别忘了停止媒体流的track,释放摄像头和麦克风资源。
额外注意点:
- 格式兼容性:
video/webm是大多数现代浏览器支持的格式,如果需要兼容更多浏览器,可以检查不同的MIME类型支持:const supportedMimeTypes = [ 'video/webm;codecs=vp9', 'video/webm;codecs=vp8', 'video/webm' ]; const mimeType = supportedMimeTypes.find(type => MediaRecorder.isTypeSupported(type)); - 错误处理:实际开发中要给
getUserMedia和MediaRecorder添加完整的错误捕获,避免页面崩溃。 - 上传后端:后端需要对应接口接收Blob文件,比如用Node.js/Express的话,可以用
multer中间件处理文件上传逻辑。
这样修改后,点击Stop按钮就能生成可下载的视频文件,同时也能直接将录制内容上传到服务器了。
内容的提问来源于stack exchange,提问作者Tony Goodchild
相关产品推荐
相关产品推荐

