Javascript 如何在连接多个远程对等点后关闭mediastream?

Javascript 如何在连接多个远程对等点后关闭mediastream?,javascript,webrtc,mediastream,rtcpeerconnection,Javascript,Webrtc,Mediastream,Rtcpeerconnection,我正在创建多个webrtc对等连接,并使用 if (mediaStream == undefined) { navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(function (stream) { mediaStream = stream;

我正在创建多个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);
            });
        }
在最后一个对等连接关闭并且我想关闭mediastream之前,一切都正常工作

if (mediaStream != undefined) {
        if (mediaStream.active) {
            mediaStream.getTracks().forEach(function (track) {
                track.stop();
            });
            mediaStream = null;
        }
    }
如果只使用了1个对等连接,则所有连接都会按计划关闭。如果有1个以上的对等连接使用了MediaStream,则MediaStream将变为null,但浏览器上的摄像头指示灯和摄像头指示灯都将保持亮起


我遗漏了什么?

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

如果输入第一个代码块

if (mediaStream == undefined) {
    navigator.mediaDevices.getUserMedia({
      ...
同样,在
getUserMedia
返回的第一个承诺得到解决之前,您的设备实际上会有多个不同的媒体流

全局变量
mediaStream
将仅表示从
getUserMedia
获取的最后一个mediaStream,并且之前的所有mediaStream在代码无法访问时仍将锁定设备

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

您需要更好地跟踪何时发出获取MediaStream的请求,以便在代码中进行更少的更改,我可以建议您实际存储通过存储MediaStream而不是/连同存储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());
  }
}
这样,下一个调用只需
then()
这个承诺,就可以访问相同的媒体流

// 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());
  }
}

我尝试先设置mediastream,然后将其添加到peerConnections。不可能创建多个mediaStream。似乎是将mediastream添加到多个对等方的行为,这是中断mediastream引用和媒体之间链接的问题。@Croftie正如我在回答中所说的,为了100%确定发生了什么,我们需要更多关于您的设置的详细信息,您应该将其作为编辑添加到原始问题中。但再一次,这是最合理的理由。无论您以后对该媒体流做什么,都不应该影响它的轨迹,也不应该影响它们如何锁定设备。作为调试步骤,您可以在获取和停止mediaStream曲目时记录它们的
id
。如果它们确实不同,那么您就有来自同一设备的多个流。对代码进行了重构,现在却令人尴尬地工作了。在完整的代码中,有两个地方可以调用mediastream,具体取决于客户是要约人还是受要约人。其中一个正在调用新的媒体流,这就是问题所在。感谢凯伊多的毅力