使用JavaScript访问你的设备相机

各位好,在这篇博客中我将向你展示如何在一个网页上通过JavaScript, 且支持众多浏览器不需要额外的库访问当前的设备相机。
access camera in the page

如何访问相机

我们使用JavaScript 的 Media Stream API去访问用户的相机(不止是在电脑上,手机上也是如此),这个API允许通过去访问设备捕获的视频和音频。

第一步是检测当前浏览器是否支持该API:

if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) {
    // 表明当前浏览器支持该API
}

事实上,现代浏览器对该API的支持相当不错(当然,是不包括Internet Explorer)

捕获视频流

为了捕获设备生成的视频流,我们使用mediaDevices对象上的getUserMedia方法。

此方法接收一个对象,该对象包含我们所请求的媒体类型(视频或音频)和一些需求条件,首先,我们可以传递参数{video: true}从摄像机获取视频。

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

执行这条语句将会要求用户授权程序访问相机的权限,如果用户拒绝,这将会抛出一个异常并且不会有期望的视频流返回。因此我们必须在try/catch语法块中处理这种情况。
camera promise
注:该方法将会返回一个Promise,因此你可以必须使用async/await或者then语法。

获取视频流的其他参数

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

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元素,将视频显示到页面上。

// considering there is a
// <video autoplay id="video"></video>
// tag in the page
const video = document.querySelector('#video')
const videoStream = await navigator.mediaDevices.getUserMedia(constraints)
video.srcObject = videoStream

注:在video元素中有autoplay属性,如果没有,你需要显式地调用video.play()方法来显示图像

访问手机上的前后相机

getUserMedia方法默认会使用操作系统默认的视频录制设备,在有两个摄像头的手机中,它使用的是前置摄像头。

为了访问后置相机,我们需要在传递视频参数时包含facingMode: "environment":

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

默认facingMode字段的值是'user',它表明是前置相机

请注意,如果您想在播放视频时更换相机,你需要停止当前流,然后用其他相机的流替换它。

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

制作截图

另外很酷的一点是,你可以捕获视频的截图。

你可以将当前的视频帧图像绘制到canvas元素上,如下:

// considering there is a
// <canvas id="canvas"></canvas>
// tag in the page
const canvas = document.querySelector('#canvas')
canvas.width = video.videoWidth
canvas.height = video.videoHeight
canvas.getContext('2d').drawImage(video, 0, 0)

你也可以将显示到canvas元素上的内容放到一个img元素上。

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

const img = document.createElement('img')
img.src = canvas.toDataURL('image/png')
screenshotContainer.prepend(img)

结论

页面中的演示地址

完整的源代码地址

posted @ 2020-06-11 14:30  西河  阅读(31)  评论(0编辑  收藏  举报