I'm using the ZXing JS barcode scanner library https://github.com/zxing-js/library/ with a video stream input (webcam or phone camera), as detailed in the following code.
In general, how to add an event listener to a <video>
to do an action when a video stream has just started? (a video using the MediaDevices.getUserMedia
video stream API, started from ZXing's decodeFromInputVideoDevice
)?
const codeReader = new ZXing.BrowserQRCodeReader();
codeReader
.decodeFromInputVideoDevice(undefined, 'video') // uses the default input
.then(result => console.log(result.text)) // this happens when the barcode is found / recognized
.catch(err => console.error(err));
<script src="https://unpkg.com/@zxing/library@0.15.2/umd/index.min.js"></script>
<video id="video"></video>
Note: for now I'm using setTimeout(..., 2000)
when the user has clicked on the button to start the video, but obviously this fails in the case there is a dialog box "Do you want to allow this website to use the camera device?", then 2 seconds is not enough. A listener on event "VideoHasJustStarted" would be better.
Edit:
Here is a jsFiddle showing the issue: not working with various events: started
, devicechange
.
There are a few ways to detect if a video is playing, or can be played, using event listeners:
let video = document.querySelector('video');
// Video has been started/unpaused
video.addEventListener('play', function() {
...
})
// Video has resumed play/started/unpaused/finished buffering/finished seeking, etc
video.addEventListener('playing', function() {
...
})
// Video can start playing (but might not be playing)
video.addEventListener('canplay', function() {
...
})
// Video can be played without buffering (but might not be playing)
video.addEventListener('canplaythrough', function() {
...
})
Most similar to VideoHasJustStarted
is probably playing
. But depending on how you want to execute your function, one of the above methods should fit your needs.
More info on video events: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events
// Get video
var video = document.querySelector('video');
// Add event listener to monitor events
video.addEventListener('playing', () => {
console.log('Video is now streaming!')
});
// Add stream
navigator.mediaDevices.getUserMedia({
video: true
})
.then(function(stream) {
var videoTracks = stream.getVideoTracks();
stream.onremovetrack = function() {
console.log('Stream ended');
};
window.stream = stream;
video.srcObject = stream;
})
.catch(function(error) {
console.log(error);
});
<video id="video" autoplay muted></video>
Tested on Firefox on laptop - permission is requested to use webcam and the console.log
fires when the video starts. As StackOverflow blocks the above from running inline, link to working fiddle