You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:31:24