【问题标题】:how to close mediastream after multiple remote peers attached?连接多个远程对等点后如何关闭媒体流?
【发布时间】:2018-11-22 12:31:08
【问题描述】:

我正在创建多个 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 个对等连接,那么一切都会按计划关闭。如果超过 1 个对等连接使用了 MediaStream,则 MediaStream 变为 null ,但浏览器上的摄像头指示灯和摄像头灯都亮着。

我错过了什么?

【问题讨论】:

  • 重构了代码,现在令人尴尬的是它可以工作了。在完整的代码中,有两个地方可以调用媒体流,具体取决于客户是要约人还是要约人。其中一个正在调用新的媒体流,这就是问题所在。感谢凯多的坚持

标签: javascript webrtc mediastream rtcpeerconnection


【解决方案1】:

这有点猜测,但似乎是最可能的原因,所以虽然有更多代码会有所帮助...

如果你确实输入了第一个代码块

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

再次在getUserMedia 返回的第一个 Promise 得到解决之前,您实际上将有多个不同的 MediaStreams 来自您的设备。

全局变量 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

【讨论】:

  • 我已经尝试先设置媒体流,然后将其添加到 peerConnections。不可能创建多个 mediaStream。似乎是将媒体流添加到多个对等点的行为是破坏媒体流引用和媒体之间链接的问题。
  • @Croftie 正如我在回答中所说,为了 100% 确定会发生什么,我们需要有关您的设置的更多详细信息,您应该将其添加为原始问题的编辑。但再一次,这是最合理的理由。之后你对这个 MediaStream 所做的任何事情都应该不会影响它的轨道,以及它们如何锁定设备。作为调试步骤,您可以在获取和停止它们时记录 mediaStream 轨道 id。如果它们确实不同,则说明您有来自同一设备的多个流。
猜你喜欢
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多