专栏首页前端全栈开发者如何使用JavaScript访问设备摄像头(前后)

如何使用JavaScript访问设备摄像头(前后)

在这篇文章中,我将向您展示如何通过 JavaScript 在网页上访问设备的摄像头,并支持多种浏览器,而无需外部库。

如何使用相机 API

要访问用户的相机(或麦克风),我们使用 JavaScript MediaStream API。该 API 允许通过流访问这些设备捕获的视频和音频。

第一步是检查浏览器是否支持此 API:

if ("mediaDevices" in navigator && "getUserMedia" in navigator.mediaDevices) {
  // ok, 浏览器支持它
}

在现代浏览器中,支持是不错的(当然没有 Internet Explorer)。

捕获视频流

要捕获由摄像机生成的视频流,我们使用 mediaDevices 对象的 getUserMedia 方法。这个方法接收一个对象,其中包含我们要请求的媒体类型(视频或音频)和一些要求。首先,我们可以通过 {video: true} 来获取摄像机的视频。

const videoStream = await navigator.mediaDevices.getUserMedia({ video: true });

此调用将询问用户是否允许访问摄像机。如果用户拒绝,它将引发异常并且不返回流。因此,必须在 try/catch 块内完成处理这种情况。

请注意,它返回一个 Promise,因此您必须使用 async/awaitthen 块。在 Mac OS 系统上还会弹出授权

点击“好”,就可以访问电脑摄像头了,控制台输出的 videoStream 对象如下

视频规格(requirements)

我们可以通过传递有关所需分辨率以及最小和最大限制的信息来改善视频的要求:

const constraints = {
  video: {
    width: {
      min: 1280,
      ideal: 1920,
      max: 2560,
    },
    height: {
      min: 720,
      ideal: 1080,
      max: 1440,
    },
  },
};

const videoStream = await navigator.mediaDevices.getUserMedia(constraints);

这样,流以正确的宽度和高度比例进入,如果它是处于纵向模式的手机,则需要进行尺寸反转。

在页面上显示视频

既然有了流,我们该如何处理?

我们可以在页面上的 video 元素中显示视频:

// 页面中有一个 <video autoplay id="video"></video> 标签
const video = document.querySelector("#video");
const videoStream = await navigator.mediaDevices.getUserMedia(constraints);
video.srcObject = videoStream;

请注意 video 标签中的自动播放属性 autoplay,没有它,你需要调用 video.play() 才能真正开始显示图像。

访问手机的前后摄像头

默认情况下,getUserMedia 将使用系统默认的视频录制设备。如果是有两个摄像头的手机,它使用前置摄像头。

要访问后置摄像头,我们必须在视频规格中包括 faceModeMode:"environment"

const constraints = {
  video: {
    width: { ... },
    height: { ... },
    facingMode: "environment"
  },
};

默认值为 faceingMode:"user",即前置摄像头。

需要注意的是,如果你想在已经播放视频的情况下更换摄像机,你需要先停止当前的视频流,然后再将其替换成另一台摄像机的视频流。

videoStream.getTracks().forEach((track) => {
  track.stop();
});

截屏

你可以做的另一件很酷的事情是捕获视频的图像(屏幕快照)。

你可以在 canvas 上绘制当前视频帧,例如:

// 页面中有一个 <canvas id="canvas"></canvas> 标签
const canvas = document.querySelector("#canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext("2d").drawImage(video, 0, 0);

你还可以在 img 元素中显示画布内容。

在本教程创建的示例中,我添加了一个按钮,该按钮可从画布动态创建图像并将其添加到页面:

const img = document.createElement("img");
img.src = canvas.toDataURL("image/png");
screenshotsContainer.prepend(img);

完整示例和代码

在线效果及源代码:https://coding.zhangbing.site/view.html?url=./list/camera-api/index.html

PC 效果:

PC

手机 QQ 中浏览效果:

手机QQ中浏览效果

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • HTML5 VideoAPI,打造自己的Web视频播放器

    注意:audio和video元素必须同时包含开始和结束标签,不能使用<audio />这样的空元素语法形式。

    张张
  • 【译】构建RESTful API的13种最佳实践

    Facebook、GitHub、Google 以及其他许多巨头都需要一种服务和消费数据的方式。在当今的开发环境中,RESTful API 仍然是服务和消费数据的...

    张张
  • 7个能提高你生产力的隐藏Chrome DevTools功能

    开发人员工具对于软件开发是必不可少的。我们需要它们来开发、测试和调试我们的工作。作为web应用程序开发人员,您使用Chrome DevTools的几率非常高。

    张张
  • 硬盘状态检测工具 CrystalDiskInfo 8.2.1 标准版

    CrystalDiskInfo 是一款支持检测HDD/SSD硬盘信息,健康度监控的应用程序。支持显示HDD基本信息,监控S.M.A.R.T.技术及磁盘的温度。C...

    萌海无涯
  • 使用python 爬梨视频

    刚开始学习python 勿喷 第一步 去官网下载python3^ 版本 下载链接 https://www.python.org/downlo... ...

    py3study
  • Confluence 6 MySQL 3.x 字符集编码问题

    MySQL 3.x is 已知在大写和小写转换的时候有些问题(non-ASCII)。

    HoneyMoose
  • Django-6 用户注册表单验证

    今天我们将学习如何使用表单并通过创建用户注册页面来验证用户输入。我们还将学习如何安装和使用Crispy Form,以便我们的表单符合我们应用程序的现代风格。 接...

    亚乐记
  • 我用30分钟做出了一个“公众号”

    身边技术大牛有很多,但是在搞博客搞公众号的却只是较少一部分,为什么呢?是的,因为懒惰,从未想着去尝试。

    后端技术探索
  • Scalaz(3)- 基础篇:函数概括化-Generalizing Functions

      Scalaz是个通用的函数式编程组件库。它提供的类型、函数组件都必须具有高度的概括性才能同时支持不同数据类型的操作。可以说,scalaz提供了一整套所有编程...

    用户1150956
  • Dr.Elephant实战常见问题及解决方法

    通过之前一系列的文章叙述,想必大家都对dr.elephant有了一个较为清晰的了解。通过自己线上经验的积累,以及和一些读者的交流,我汇总了一些大家在实战中遇到的...

    一条老狗

扫码关注云+社区

领取腾讯云代金券