连接多个远程对等后如何关闭媒体流?

时间:2018-11-22 12:31:09

标签: javascript webrtc mediastream rtcpeerconnection

我正在创建多个webrtc对等连接,并使用

创建一个媒体流
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);
            });
        }

一切正常,直到最后一个对等连接关闭并且我想关闭媒体流为止。

if (mediaStream != undefined) {
        if (mediaStream.active) {
            mediaStream.getTracks().forEach(function (track) {
                track.stop();
            });
            mediaStream = null;
        }
    }

如果仅使用了1个对等连接,则一切将按计划关闭。如果使用MediaStream的对等连接超过1个,则MediaStream变为null,但浏览器上的摄像头指示灯和摄像头指示灯均保持点亮。

我想念什么?

1 个答案:

答案 0 :(得分:2)

这只是一个猜测,但似乎是最可能的原因,因此拥有更多代码会有所帮助...

如果您输入了第一个代码块

if (mediaStream == undefined) {
    navigator.mediaDevices.getUserMedia({
      ...
再次

getUserMedia返回的第一个Promise被解决之前,您实际上将有来自设备的多个不同的MediaStream。

全局变量mediaStream仅代表从getUserMedia获取的最后一个MediaStream,并且所有先前的变量虽然无法从代码中访问,但仍会锁定设备。

Here is an MCVE

换句话说,您需要重构代码

您需要更好地跟踪何时发出获取MediaStream的请求,因此,为了减少代码更改,我建议您实际存储getUserMedia返回的Promise [代替/一起存储MediaStream。

这样,下一次调用只需then()此Promise,即可访问相同的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());
  }
}

live example