简体   繁体   English

如何在 electron 应用程序中显示网络摄像头视频源?

[英]How can I show webcam video feed inside an electron application?

I want to show the webcam feed from a specific device by defining the vendorid and productid of that device.我想通过定义该设备的vendoridproductid来显示来自特定设备的网络摄像头提要。 What is the best library?最好的图书馆是什么? I looked into opencv and webcamjs but there are not tutorials for electron.我查看了 opencv 和 webcamjs,但没有 electron 的教程。 Thanks in advance.提前致谢。

There are two ways you can accomplish this.有两种方法可以做到这一点。 However, neither way meets your criteria of selecting a camera by defining the vendorid and productid .但是,这两种方式都不符合您by defining the vendorid and productid来选择相机的标准。 Although it will allow you to select the device via the deviceId .虽然它允许您通过deviceId select 设备。

Method 1 implement manually方法一手动实现

First we will create a video element首先我们将创建一个视频元素

<video ref="vid" />

Next, we will create our select接下来,我们将创建我们的 select

<select
    v-model="deviceID"
    v-if="videoDevices.length >= 1"
    style="border:1px black solid"
  >
    <option
      v-for="i in videoDevices"
      :key="i.deviceId"
      :value="i.deviceId"
      :selected="(deviceID = i.deviceId)"
      >
        {{ i.label }}
    </option>
  </select>  

Then in our script, we will need the videoDevices and deviceID variables in our data object.然后在我们的脚本中,我们需要数据 object 中的videoDevicesdeviceID变量。

data() {
  return {
    videoDevices: [],
    deviceID: null,
  };
}

When the Vue instance is mounted we need to look for all the media devices attached to our computer, and filter out all of the devices that are a videoinput .安装 Vue 实例后,我们需要查找连接到我们计算机的所有媒体设备,并过滤掉所有属于videoinput的设备。

async mounted() {
  //Get all mediaDevices attached to the computer
  let devices = await navigator.mediaDevices.enumerateDevices();

  //Iterate over all of the devices
  for (let index = 0; index < devices.length; index++) {
    const device = devices[index];
    if (device.kind == "videoinput") {
      //Add the video device because it is a videoDevice. Manually create a new object with device details instead of passing device.
      this.videoDevices.push({
        deviceId: device.deviceId,
        kind: device.kind,
        label: device.label,
      });
    }
  }
}

Finally, we will need to watch deviceID for changes so that when a user selects a video input the correct source is loaded.最后,我们需要观察deviceID的变化,以便在用户选择视频输入时加载正确的源。

watch: {
  async deviceID(v) {
    //Start the video with the exact deviceId we are trying to observe
    var constraints = {
      deviceId: { exact: v.deviceID },
    };

    //Create a stream with the webcam selected by the constraints above.
    let stream = await navigator.mediaDevices.getUserMedia({
      video: constraints,
    });

    //Get the ref pointing towards our video tag
    let video = this.$refs.vid;

    //Set the source to be the stream we are capturing above
    video.srcObject = stream;
 
    //When the stream is loaded, begin playing the stream
    video.onloadedmetadata = function() {
      video.play();
    };
  },
}

Here is code sandbox with a full example这是带有完整示例的代码沙箱

Method 2 use vue-web-cam方法2使用vue-web-cam

You can use vue-web-cam .您可以使用vue-web-cam

Here is how you can use it, directly from the examples这是直接从示例中使用它的方法

npm i vue-web-cam --save

Template:模板:

<div class="container">
    <div class="row">
        <div class="col-md-6">
            <h2>Current Camera</h2>
            <code v-if="device">{{ device.label }}</code>
            <div class="border">
                <vue-web-cam
                    ref="webcam"
                    :device-id="deviceId"
                    width="100%"
                    @started="onStarted"
                    @stopped="onStopped"
                    @error="onError"
                    @cameras="onCameras"
                    @camera-change="onCameraChange"
                />
            </div>

            <div class="row">
                <div class="col-md-12">
                    <select v-model="camera">
                        <option>-- Select Device --</option>
                        <option
                            v-for="device in devices"
                            :key="device.deviceId"
                            :value="device.deviceId"
                        >{{ device.label }}</option>
                    </select>
                </div>
                <div class="col-md-12">
                    <button type="button" class="btn btn-primary" @click="onCapture">Capture Photo</button>
                    <button type="button" class="btn btn-danger" @click="onStop">Stop Camera</button>
                    <button type="button" class="btn btn-success" @click="onStart">Start Camera</button>
                </div>
            </div>
        </div>
        <div class="col-md-6">
            <h2>Captured Image</h2>
            <figure class="figure">
                <img :src="img" class="img-responsive" />
            </figure>
        </div>
    </div>
</div>

Script脚本

import { WebCam } from "vue-web-cam";
export default {
    name: "App",
    components: {
        "vue-web-cam": WebCam
    },
    data() {
        return {
            img: null,
            camera: null,
            deviceId: null,
            devices: []
        };
    },
    computed: {
        device: function() {
            return this.devices.find(n => n.deviceId === this.deviceId);
        }
    },
    watch: {
        camera: function(id) {
            this.deviceId = id;
        },
        devices: function() {
            // Once we have a list select the first one
            const [first, ...tail] = this.devices;
            if (first) {
                this.camera = first.deviceId;
                this.deviceId = first.deviceId;
            }
        }
    },
    methods: {
        onCapture() {
            this.img = this.$refs.webcam.capture();
        },
        onStarted(stream) {
            console.log("On Started Event", stream);
        },
        onStopped(stream) {
            console.log("On Stopped Event", stream);
        },
        onStop() {
            this.$refs.webcam.stop();
        },
        onStart() {
            this.$refs.webcam.start();
        },
        onError(error) {
            console.log("On Error Event", error);
        },
        onCameras(cameras) {
            this.devices = cameras;
            console.log("On Cameras Event", cameras);
        },
        onCameraChange(deviceId) {
            this.deviceId = deviceId;
            this.camera = deviceId;
            console.log("On Camera Change Event", deviceId);
        }
    }
};

You can use this code您可以使用此代码

 var video = document.querySelector("#videoElement"); if (navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) { video.srcObject = stream; }).catch(function (err0r) { console.log("Something went wrong;"); }). } // this functions to stop function stop(e) { var stream = video;srcObject. var tracks = stream;getTracks(); for (var i = 0. i < tracks;length; i++) { var track = tracks[i]. track;stop(). } video;srcObject = null; }
 #container { margin: 0px auto; width: 500px; height: 375px; border: 10px #333 solid; } #videoElement { width: 500px; height: 375px; background-color: #666; }
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Display Webcam Stream</title> </head> <body> <div id="container"> <video autoplay="true" id="videoElement"> </video> </div> </body> </html>

How it works?这个怎么运作?

select video tag select 视频标签

var video = document.querySelector("#videoElement");

then accessing the getUserMedia API然后访问 getUserMedia API

    if (navigator.mediaDevices.getUserMedia) {
  navigator.mediaDevices.getUserMedia({ video: true })
    .then(function (stream) {
      video.srcObject = stream;
    })
    .catch(function (err0r) {
      console.log("Something went wrong!");
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM