Reputation: 13
I am creating multiple webrtc peer connections and creating a single mediastream using
if (mediaStream == undefined) {
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
}).then(function (stream) {
mediaStream = stream;
mediaStream.getTracks().forEach(function (track) {
rtcPeerConns[userName].addTrack(track, mediaStream);
});
}).catch(function (err) {
console.log("get user media " + err.name + ": " + err.message);
});
} else {
console.log("using the existing local stream");
mediaStream.getTracks().forEach(function (track) {
rtcPeerConns[userName].addTrack(track, mediaStream);
});
}
Everything works perfectly until the last peer connection is closed and I want to close the mediastream.
if (mediaStream != undefined) {
if (mediaStream.active) {
mediaStream.getTracks().forEach(function (track) {
track.stop();
});
mediaStream = null;
}
}
If only 1 peer connection has been used then everything shuts down as planned. If more than 1 peer connection has used the MediaStream then the MediaStream becomes null , but the camera indicator on the browser and the camera light both stay on.
What am I missing?
Upvotes: 1
Views: 1298
Reputation: 136658
That's a bit of a guess, but seems like the most possible reason, so while having more code would help...
If you do enter that first code block
if (mediaStream == undefined) {
navigator.mediaDevices.getUserMedia({
...
again before the first Promise returned by getUserMedia
gets resolved, then you will have actually multiple different MediaStreams coming from your device.
The global variable mediaStream
will only represent the last MediaStream got from getUserMedia
, and all the previous ones while inaccessible from your code, will still lock your device.
In other words, you need to refactor your code.
You need to keep better track of when a request to get the MediaStream has been made, so to make the less changes in your code, I can propose you to actually store the Promise that gets returned by getUserMedia
[instead of / along with] storing the MediaStream.
This way, next calls will just have to then()
this Promise, in order to access the same MediaStream.
// outer scope
var stream_request = null;
// [...]
function requestStream() {
if(!stream_request) {
stream_request = navigator.mediaDevices.getUserMedia(options);
}
return stream_request
.then(doSomethingWithTheMediaStream);
}
// and to kill it
function kill_stream() {
return stream_request.then(stream => {
stream.getTracks().forEach(t => t.stop());
}
}
Upvotes: 3