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

如何用JavaScript逐帧保存摄像头直播视频为序列图片至目录

嘿,我来帮你搞定摄像头直播逐帧保存的问题!其实核心思路是用canvas捕获视频帧,再把canvas内容转为图片文件下载。浏览器出于安全限制没法直接保存到你指定的本地目录,但可以触发下载让用户选择保存路径;如果是后端场景,也可以把帧上传到服务器再存到指定目录。

下面是完整的实现方案,我拆成步骤给你讲:

第一步:准备HTML结构

先加个隐藏的canvas用来绘制帧,还有控制按钮:

<video id="vid" autoplay playsinline></video>
<canvas id="frameCanvas" style="display: none;"></canvas>
<button onclick="start()">启动摄像头</button>
<button onclick="startCapture()">开始逐帧保存</button>
<button onclick="stopCapture()">停止捕获</button>

第二步:完善JavaScript逻辑

我把你的代码补全,加上帧捕获和保存的核心逻辑:

let localStream;
let captureInterval;
let frameCount = 1;
const canvas = document.getElementById('frameCanvas');
const ctx = canvas.getContext('2d');

function start() {
  // 优先用标准API,兼容主流浏览器
  if (navigator.mediaDevices?.getUserMedia) {
    const options = { video: true, audio: false };
    navigator.mediaDevices.getUserMedia(options)
      .then(stream => {
        const vid = document.getElementById('vid');
        // 用srcObject替代老的createObjectURL,更简洁高效
        vid.srcObject = stream;
        localStream = stream;
      })
      .catch(err => {
        console.error('访问摄像头失败:', err);
        alert('请允许浏览器访问摄像头权限哦');
      });
  } else {
    alert('你的浏览器版本太老啦,不支持摄像头访问功能');
  }
}

function startCapture() {
  const vid = document.getElementById('vid');
  // 等视频加载完成再获取真实尺寸,避免帧拉伸或空白
  if (!vid.videoWidth) {
    alert('视频还没加载好,稍等一下再点击哦');
    return;
  }
  
  canvas.width = vid.videoWidth;
  canvas.height = vid.videoHeight;
  
  // 这里设置每1000ms捕获一帧,可根据需求调整间隔(比如200ms=5帧/秒)
  captureInterval = setInterval(() => {
    // 将当前视频帧绘制到canvas上
    ctx.drawImage(vid, 0, 0, canvas.width, canvas.height);
    
    // 把canvas内容转为JPEG格式Blob(0.9是图片质量,范围0-1)
    canvas.toBlob(blob => {
      // 创建临时下载链接
      const downloadUrl = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = downloadUrl;
      // 设置文件名:frame1.jpg、frame2.jpg...
      link.download = `frame${frameCount}.jpg`;
      // 触发浏览器下载
      link.click();
      
      // 清理临时URL,避免内存泄漏
      URL.revokeObjectURL(downloadUrl);
      frameCount++;
    }, 'image/jpeg', 0.9);
  }, 1000);
}

function stopCapture() {
  // 清除定时捕获的定时器
  if (captureInterval) {
    clearInterval(captureInterval);
    captureInterval = null;
    console.log('已停止帧捕获');
  }
}

几个关键细节说明:

  • 浏览器安全限制:不能自动保存到本地指定目录,必须通过用户点击按钮触发下载(这是浏览器的安全规则,防止恶意网站乱存文件)
  • 帧率调整:修改setInterval的第二个参数(毫秒数)就能改变捕获频率,比如100就是每秒10帧
  • 视频尺寸适配:一定要等视频加载后再设置canvas尺寸,不然会出现帧拉伸或者空白的问题
  • API兼容性:现在主流浏览器都支持标准的navigator.mediaDevices.getUserMedia,老的webkit前缀已经没必要啦

如果你的需求是把帧保存到服务器指定目录,那可以在canvas.toBlob之后,用fetch把Blob上传到后端接口,后端用Node.js的fs模块或者其他语言的文件操作API存到指定路径就行。

内容的提问来源于stack exchange,提问作者Zaid Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:45:19