I want to show the webcam feed from a specific device by defining the vendorid and productid of that device. What is the best library? I looked into opencv and webcamjs but there are not tutorials for electron. Thanks in advance.
I want to show the webcam feed from a specific device by defining the vendorid and productid of that device. What is the best library? I looked into opencv and webcamjs but there are not tutorials for 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. Although it will allow you to select the device via the deviceId.
First, we create a video element
<video ref="vid" />
Next, we create our 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.
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.
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 need to watch deviceID for changes so that when a user selects a video input the correct source is loaded.
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
You can use 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
var video = document.querySelector("#videoElement");
then accessing the 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!");
});
}