【译】如何使用Vue捕获网络摄像头视频

几个月前,我一直关注着比特币的爆发并且在GDAX网站上注册账号。在注册验证的过程中,网站提示要通过计算机的网络摄像头提交我自己的一张照片作为照片ID。这是一个很酷的做法,让我思考一个问题:在网络浏览器上集成网络摄像头使用需要怎么做?

事实上,有一些HTML5的API可用于通过JavaScript与网络摄像头进行交互。

下面,我们来看下如何创建一个VueJS的Web应用,在Web浏览器上通过网络摄像头直接捕获。

使用Vue CLI创建Vue项目

为了使项目更易于的理解,我们将从头开始搭建项目。为方便起见,我们使用Vue CLI脚手架来构建项目。(安装Vue CLI 详见官网)

安装好CLI之后,执行以下命令:

vue init webpack camera-project

在脚手架处理的过程中会提示一些问题。对于这个特别的项目,如果你选择了包含编译器和运行时或只有运行时,都无关重要。我们不会创建多个组件,所以路由对于这个项目不是必要的。

此时,我们可以开始开发应用了。

为图像捕获编写应用逻辑和接口

对于这个特定的项目,我们有一些目标。我们希望能够把网络摄像头流传输到UI并且按需捕获帧。下面是一张我们所希望实现的功能的截图。
image

每次我们捕获一张图片,将会加到下面小的列表中。如果有需要,我们可以通过HTTP API将捕获图片发送到数据库。
所以,我们要怎么实现这些项目的目标?

打开项目的src/App.vue文件,加入以下内容开始:

<template>
    <div id="app">
    </div>
</template>

<script>
    export default {
        name: 'app',
        data() {
            return {
                video: {},
                canvas: {},
                captures: []
            }
        },
        mounted() { },
        methods: { }
    }
</script>

<style>
    body: {
        background-color: #F0F0F0;
    }
    #app {
        text-align: center;
        color: #2c3e50;
        margin-top: 60px;
    }
    #video {
        background-color: #000000;
    }
    #canvas {
        display: none;
    }
    li {
        display: inline;
        padding: 5px;
    }
</style>

该template块暂时先保留为空。相反,我们先看看script标签部分的内容。
我们需要初始化一些用于UI的变量,这可以通过data方法完成。video变量将绑定到一个video元素,canvas变量将绑定到一个canvas元素,而captures数组则用于存储已捕获的图像列表。

mouted方法将会在应用加载完使触发调用。此方法内容如下:

mounted() {
    this.video = this.$refs.video;
    if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
            this.video.src = window.URL.createObjectURL(stream);
            this.video.play();
        });
    }
},

我们需要和UI中的HTML元素进行交互,可以使用Vue.js的refs,而不是试图直接访问DOM。你将会很快看到,但HTML元素将会有ref属性,值为video。

一旦我们获取了元素的引用,就可以检测来确保该值是否支持媒体捕获。如果支持媒体捕获,我们将可以从网络摄像头获取流并把流加载到HTML Video元素中。

事实上,以上代码的灵感来自David Walsh的教程,使用HTML5控制摄像头和视频,我只是用refs和Vue改写了。

下面来到我们的methods中,将会有一个capture方法,代码如下:

methods: {
    capture() {
        this.canvas = this.$refs.canvas;
        var context = this.canvas.getContext("2d").drawImage(this.video, 0, 0, 640, 480);
        this.captures.push(canvas.toDataURL("image/png"));
    }
}

同样地,我们将refs用于HTML元素,一旦我们获得了canvas元素的引用,就可以获得Video元素的图像,将其转换成一张图片,并且放到captures数组中。

那么,与JavaScript逻辑对应的HTML是怎么样的?
在项目的src/App.vue文件中,我们来看下template块的内容:

<template>
    <div id="app">
        <div><video ref="video" id="video" width="640" height="480" autoplay></video></div>
        <div><button id="snap" v-on:click="capture()">Snap Photo</button></div>
        <canvas ref="canvas" id="canvas" width="640" height="480"></canvas>
        <ul>
            <li v-for="c in captures">
                <img v-bind:src="c" height="50" />
            </li>
        </ul>
    </div>
</template>

还记得之前提到过的refs吗?这就是分配的地方

<div>
    <video ref="video" id="video" width="640" height="480" autoplay></video>
</div>

video标签有ref="video",同样canvas标签也类似。

当按钮按下时,该capture方法会调用。captures变量循环遍历,每张图片渲染到屏幕上。
还可以,对吧?

结论

刚刚了解了如何使用Vue.js Web应用程序中的Web浏览器从Web摄像头捕获图像。大多数繁重的工作都是通过HTML5 JavaScript API完成的,但Vue.js使得事情变得非常简单。
在这篇特定的文章中使用了一些重要的Vue.js概念。refHTML元素的属性允许我们从JavaScript访问它们。通过v-bind:src在标签上使用,我们能够显示我们捕获的图像。

原文链接

https://x-team.com/blog/webcam-capture-vue/

Review

以上是简单翻译的一篇文件,主要是使用HTML5API与摄像头进行交互,本篇文件内容相对简单,只是大概了解到摄像头捕获图像转成图片的功能。目前在Web开发场景,一般会使用到拍照上传等功能,对于视频人脸识别等场景也会有用到,所以搜到这篇文章做了大概了解。

posted @ 2019-03-24 19:50 LINJIAJUN 阅读(...) 评论(...) 编辑 收藏