Reputation: 1974
I have a react component that starts a webcam when a component called VideoPage is mounted.
However, when I navigate to another page, the webcam is still running in the background. I know this because the webcam activity light is still activated on my laptop.
I believe I will to 'kill' the webcam in the React lifecycle method ComponentWillUnmount when the component unmounts. How can I achieve that?
My code is below. I appreciate the advice. Thanks!
import React from "react";
export default class VideoPage extends React.Component {
constructor(props) {
super(props);
this.videoTag = React.createRef();
this.state = {
loading: false
};
}
componentDidMount() {
navigator.mediaDevices
.getUserMedia({ video: true })
.then(this.handleStream)
.catch(err => console.log(err));
}
handleStream = async stream => {
// start receiving stream from webcam
this.videoTag.current.srcObject = stream;
console.log("The video is ready");
};
render() {
return (
<div>
<div style={{ paddingTop: 20 }}>
<video
id="myvideo"
ref={this.videoTag}
width={426}
height={240}
autoPlay
title="video"
/>
</div>
</div>
);
}
}
Upvotes: 4
Views: 5168
Reputation: 1974
Thanks to @Kalido answer, my final working code is as below...
Here's a link to a github repo with my solution... Github Repo
constructor(props) {
// set up constructor
super(props);
// create video ref
this.videoTag = React.createRef();
this.myStream = null;
// set up initial state
this.state = {
guess: "",
probability: null,
loading: false,
scale: defaultValue
};
}
componentDidMount() {
// set up webcam when component mounting
navigator.mediaDevices
.getUserMedia({ video: true })
.then(this.handleStream)
.catch(err => console.log(err));
}
componentWillUnmount() {
this.myStream.getTracks().forEach(track => track.stop());
}
handleStream = async stream => {
this.myStream = stream;
// start receiving stream from webcam
this.videoTag.current.srcObject = stream;
// prepare classifier and assign myClassifier in global scope
myClassifier = await this.prepareClassifier(this.videoTag.current);
console.log(myClassifier);
console.log("The video is ready");
};
Upvotes: 0
Reputation: 136658
To stop a getUserMedia request, you need to call the stop()
method of the MediaStreamTracks it generated.
To access these MediaStreamTracks, you need to call the getTracks()
method of the stream
MediaStream you received in your handleStream
method.
So it would be good to save your stream somewhere in your instance, e.g as this.stream
.
Then in your componentWillUnmount
, you will call
this.stream.getTracks()
.forEach((track) => track.stop());
Upvotes: 5