如何使用 HTML5 将网络摄像头捕获的 jpg 图像/视频保存在本地硬盘中

2024-03-06

问题看似简单,但我找不到合适的解决方案 因为我缺乏 HTML 和 Javascript 知识。

任务只是设计一个网页,其中的按钮将激活网络摄像头并将静态图像或视频(最好)存储在本地硬盘驱动器中。暂时不需要上传/下载。

经过一番尝试,我可以使用 getusermedia() api 激活网络摄像头并在浏览器窗口中渲染视频,但无法保存它。这就是我的代码的样子。

if (navigator.getUserMedia) {       
    navigator.getUserMedia({video: true}, handleVideo, videoError);
}

function handleVideo(stream) {
    video.src = window.URL.createObjectURL(stream);
}

那么,关于如何将以相同方式捕获的静态图像或视频保存在硬盘驱动器中,有什么想法吗?


首先,navigator.getUserMedia https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getUserMediaAPI 已被弃用,您现在应该使用navigator.mediaDevices.getUserMedia https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia method.

然后要拍摄静态图像,您确实可以使用画布,它可以draw https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/drawImage视频元素。

const vid = document.querySelector('video');
navigator.mediaDevices.getUserMedia({video: true}) // request cam
.then(stream => {
  vid.srcObject = stream; // don't use createObjectURL(MediaStream)
  return vid.play(); // returns a Promise
})
.then(()=>{ // enable the button
  const btn = document.querySelector('button');
  btn.disabled = false;
  btn.onclick = e => {
    takeASnap()
    .then(download);
  };
})
.catch(e=>console.log('please use the fiddle instead'));

function takeASnap(){
  const canvas = document.createElement('canvas'); // create a canvas
  const ctx = canvas.getContext('2d'); // get its context
  canvas.width = vid.videoWidth; // set its size to the one of the video
  canvas.height = vid.videoHeight;
  ctx.drawImage(vid, 0,0); // the video
  return new Promise((res, rej)=>{
    canvas.toBlob(res, 'image/jpeg'); // request a Blob from the canvas
  });
}
function download(blob){
  // uses the <a download> to download a Blob
  let a = document.createElement('a'); 
  a.href = URL.createObjectURL(blob);
  a.download = 'screenshot.jpg';
  document.body.appendChild(a);
  a.click();
}
<button>take a snapshot</button>
<video id="vid"></video>

作为小提琴 https://jsfiddle.net/pnrew67t/因为 Stacksnippets 可能会阻止 gUM 请求...

要另存为视频,您可以使用 [MediaRecorder API](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorderà https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder%C3%A0,这将允许您将 MediaStream 保存为 webm:

const vid = document.querySelector('video');
navigator.mediaDevices.getUserMedia({video: true}) // request cam
.then(stream => {
  vid.srcObject = stream; // don't use createObjectURL(MediaStream)
  return vid.play(); // returns a Promise
})
.then(()=>{ // enable the button
  const btn = document.querySelector('button');
  btn.disabled = false;
  btn.onclick = startRecording;
})
.catch(e=>console.log('please use the fiddle instead'));

function startRecording(){
  // switch button's behavior
  const btn = this;
  btn.textContent = 'stop recording';
  btn.onclick = stopRecording;
  
  const chunks = []; // here we will save all video data
  const rec = new MediaRecorder(vid.srcObject);
  // this event contains our data
  rec.ondataavailable = e => chunks.push(e.data);
  // when done, concatenate our chunks in a single Blob
  rec.onstop = e => download(new Blob(chunks));
  rec.start();
  function stopRecording(){
    rec.stop();
    // switch button's behavior
    btn.textContent = 'start recording';
    btn.onclick = startRecording;
  }
}
function download(blob){
  // uses the <a download> to download a Blob
  let a = document.createElement('a'); 
  a.href = URL.createObjectURL(blob);
  a.download = 'recorded.webm';
  document.body.appendChild(a);
  a.click();
}
<button disabled>start recording</button>
<video></video>

And as a fiddle https://jsfiddle.net/pnrew67t/1


Notes:

MediaRecorder API 仍然是一个相当新的 API,[一小部分浏览器实现中仍然存在一些错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 HTML5 将网络摄像头捕获的 jpg 图像/视频保存在本地硬盘中 的相关文章

随机推荐

  • UserManager.Update(user) 方法不是线程安全的

    我正在尝试使用控制器中的 UserManager 更新用户 就在我更新用户之前 对外部服务的调用会触发一个 Webhook 该 Webhook 也会使用 UserManager 尝试更新同一用户 但这是一个不同的请求和应用程序的不同部分 w
  • 基础上的全高柱

    我正在使用 Foundation 5 Framework 需要创建 3 个相同高度的列 第二列包括 2 个面板 我需要将所有列拉伸到全高 在第二列中只有第二个面板拉伸到全高 任何想法 我不想为此使用块网格 My code div class
  • 准备好的陈述如何运作?

    我正在编写一些数据库例程 并且正在使用准备好的语句 我的环境是带有 PHP5 的 PDO 据我所知 准备好的语句主要提供性能优势 以及一些辅助优势 例如不必手动 SQL 转义输入数据 我的问题是关于性能部分 下面有两个 getPrice 函
  • 使用 PHP 进行 oAuth(适用于 google api)

    如何在 PHP 中使用 oAuth 我无法使用 pecl 安装 oauth 类 因为我使用的是共享托管 I found http code google com p oauth php http code google com p oaut
  • 带有 istream& 参数的函数 C++

    我希望我的程序使用下面的 readFile 函数读取文件 我试图找出如何使用 istream 参数调用函数 该函数的目标是通过接收文件名作为参数来读取文件 include
  • 基于线的热图或二维线直方图

    我有一个合成数据集 其中包含 1000 个不同阶的噪声多边形和 sin cos 曲线 我可以使用 python seaborn 将其绘制为线条 由于我有很多重叠的线 我想绘制某种线图的热图或直方图 我尝试过迭代列并聚合计数以使用 seabo
  • 检查是否可以在另一个数组中找到所有项目

    我需要检查一个数组中的所有项目是否可以在另一个数组中找到 也就是说 我需要检查一个数组是否是另一个数组的子集 Example var array 1 2 5 7 var otherArray 1 2 3 4 5 6 7 8 比较上面这两个数
  • LINQ 相当于Where 子句中的 SQL IsNull(..,.)

    在以下 OUTER JOIN LINQ 查询中 我在Where如果右侧行为空 则子句 如果 c CustomerID 与外连接中的 ord CustomerID 不匹配 Question 如果下面的 ord price 为 null 我该如
  • 添加字体后 Heroku Rails 资产管道无法预编译

    我正在尝试向我的 Rails 应用程序添加字体 这就是我所做的 添加字体到 app assets fonts SCSS font face font family LigatureSymbols src font url LigatureS
  • Markdown 中的 VS Code Latex 语法

    我目前正在使用 pandoc markdown 编写文档 因此使用 Latex 语法 在编写时如何获得 Latex 支持 自动完成 语法突出显示等 md file Latex Workshop 扩展适用于 tex文件 但我找不到添加文件类型
  • 在 WPF 中设置电话号码的文本框格式

    我在 WPF 窗口中有一个 DataGrid 如何在 DataGrid 中以 999 999 9999 的格式显示电话号码字符串列 DataGrid 中的电话号码列使用 CellTemplate 中的 TextBlock 和 CellEdi
  • 如何在java中将模式dd-MMM-yy的字符串日期值转换为模式dd/MM/yyyy的日期对象

    I have String dateAsString 15 May 84 我想将其转换为 Date date 15 05 1984 第一次尝试 new SimpleDateFormat dd MM yyyy format new Date
  • 如何在python中将jenkins作业配置config.xml转换为YAML格式以使用jenkins-job-builder?

    詹金斯工作建设者 http ci openstack org jenkins job builder 是一个很好的工具 可以帮助我维持工作YAML文件 参见示例配置 http ci openstack org jenkins job bui
  • Google Play Console:丢失了上传 APK 所需的上传密钥 [重复]

    这个问题在这里已经有答案了 我失去了我的上传密钥这是在 Google Play Console 上上传 Android APK 文件所必需的 尝试使用新钥匙 但由于指纹不匹配 因此不起作用 但是 我启用了 Google 的 应用程序签名 因
  • python 将ascii字符转换为有符号8位整数

    这感觉应该很简单 但我一直找不到答案 在 python 脚本中 我从 USB 设备读取数据 USB 鼠标的 x 和 y 移动 它以单个 ASCII 字符形式到达 我可以使用 ord 轻松转换为无符号整数 0 255 但是 我希望它作为有符号
  • “const”的使用是教条性的还是理性的?

    在 Delphi 中 您可以通过传递参数来加速代码const e g function A const AStr string integer or function B AStr string integer 假设两个函数内部都有相同的代
  • jinja2:渲染模板而不扩展

    如何在不扩展的情况下渲染模板 我有简单的渲染器 我想在发现这个请求是ajax后只渲染目标数据 我的模板 extends base html load i18n block extrahead endblock extrahead block
  • 超级开发模式重新编译后未检测到更改

    我设置了新的 Eclipse 工作区并从 SVN 下载了项目 我启动了超级开发模式 gwt 2 7 0 chrome 浏览器 当尝试重新编译时 它显示 跳过编译 因为没有输入文件已更改 它在旧工作区中运行良好 但在新工作区中则不然 我使用相
  • Laravel 与数据表:搜索加密数据

    我在使用 Laravel 数据表时遇到了一个很大的问题 我有一个模型 它有 3 个由 setter getter 自动加密 使用 Crypt 的值 我正在使用数据表来渲染表格 return datatables gt of Patient
  • 如何使用 HTML5 将网络摄像头捕获的 jpg 图像/视频保存在本地硬盘中

    问题看似简单 但我找不到合适的解决方案 因为我缺乏 HTML 和 Javascript 知识 任务只是设计一个网页 其中的按钮将激活网络摄像头并将静态图像或视频 最好 存储在本地硬盘驱动器中 暂时不需要上传 下载 经过一番尝试 我可以使用