Reputation: 16826
I am building a project that captures an image from the webcam in the browser. After the image is taken, I no longer need to use the camera, so I am trying to stop it with the following function:
function stopCamera(container) {
console.log("Stopping the camera.");
video = container.querySelector('.video-streamer');
console.log(video);
video.srcObject = null;
navigator.mediaDevices.getUserMedia({ video: true }).then(
function (stream) {
console.log(stream.getTracks().length);
stream.getTracks().forEach(function (track) {
console.log("Found a stream that needs to be stopped.")
track.stop();
});
console.log(stream.getTracks().length);
}).catch(
function (error) {
console.log('getUserMedia() error', error);
});
}
However, even after the function is called, the webcam access light stays on, and I see that the browser (both Firefox and Chrome) still show that the page is using the camera.
What is missing in the code above?
Upvotes: 7
Views: 4492
Reputation: 42450
navigator.mediaDevices.getUserMedia
returns a new stream (a clone), not the existing stream.
You have to stop all tracks from all stream clones returned from different calls to getUserMedia
, before the light goes out.
In your case, that includes the tracks of the stream you're already playing. Use the following:
function stopCamera(container) {
const video = container.querySelector('.video-streamer');
for (const track of video.srcObject.getTracks()) {
track.stop();
}
video.srcObject = null;
}
Once all tracks are stopped, the light should go out instantly.
If you neglect to do this, the light should still go out 3-10 seconds after video.srcObject = null
thanks to garbage collection (assuming it was the lone held reference to the stream).
If you've created any track clones, you need to stop them too.
Upvotes: 14