【问题标题】:Can a MediaStream be used immediately after getUserMedia() returns?getUserMedia() 返回后可以立即使用 MediaStream 吗?
【发布时间】:2017-10-25 16:09:14
【问题描述】:

我正在尝试从网站用户的手机中捕获音频,并将其传输到远程 RTCPeerConnection。

假设我有一个获取本地 MediaStream 的函数:

function getLocalAudioStream(): Promise<*> {
  const devices = navigator.mediaDevices;
  if (!devices) {
    return Promise.reject(new Error('[webrtc] Audio is not supported'));
  } else {
    return devices
      .getUserMedia({
        audio: true,
        video: false,
      })
      .then(function(stream) {
        return stream;
      });
  }
}

以下代码可以正常工作:

// variable is in 'global' scope
var LOCAL_STREAM: any = null;
// At application startup: 
getLocalAudioStream().then(function(stream) {
  LOCAL_STREAM = stream;
});
...
// Later, when the peer connection has been established:
// `pc` is an RTCPeerConnection
LOCAL_STREAM.getTracks().forEach(function(track) {
        pc.addTrack(track, LOCAL_STREAM);
      });

但是,我不想让 MediaStream 保持打开状态,我想 延迟稍后获取流,所以我尝试了这个:

getLocalAudioStream().then(function(localStream) {
    localStream.getTracks().forEach(function(track) {
      pc.addTrack(track, localStream);
    });
});

这不起作用(另一端没有收到声音。) 我尝试保留全局变量,以防出现奇怪的范围界定/垃圾收集问题:

// variable is in 'global' scope
var LOCAL_STREAM: any = null;

 getLocalAudioStream().then(function(localStream) {
    LOCAL_STREAM = localStream;
    localStream.getTracks().forEach(function(track) {
       pc.addTrack(track, localStream);
    });
});

我在这里缺少什么?

在 getUserMedia 承诺返回的那一刻和它可以添加到 RTCPeerConnection 的那一刻之间是否有等待延迟?或者我可以等待特定的事件吗?

-- 编辑--

正如@kontrollanten 建议的那样,我通过重置我对 RTCPeerConnection 的本地描述使其在 Chrome 下工作:

getLocalAudioStream().then(function(localStream) {
    localStream.getTracks().forEach(function(track) {
      pc.addTrack(track, localStream);
    });

    pc
      .createOffer({
        voiceActivityDetection: false,
      })
      .then(offer => {
        return pc.setLocalDescription(offer);
      })
  });

但是:

  • 它不适用于 Firefox
  • 我肯定还是做错了什么,因为我想挂断时停不下来:

我尝试停止:

  getLocalAudioStream().then(stream => {
    stream.getTracks().forEach(track => {
      track.stop();
    });
  });

【问题讨论】:

    标签: javascript webrtc


    【解决方案1】:

    不,没有这样的延迟。媒体返回后,您可以将其发送到 RTCPeerConnection。

    在你的例子中

    getLocalAudioStream().then(function(localStream) {
        pc.addTrack(track, localStream);
    });
    

    尚不清楚stream 是如何定义的。会不会是未定义的?

    为什么你不能用下面的?

    getLocalAudioStream()
      .then(function (stream) {
        stream
          .getTracks()
          .forEach(function(track) {
            pc.addTrack(track, stream);
          });
      });
    

    【讨论】:

    • 你说得对,我在我的问题中复制粘贴了错误的代码。我实际上正在按照您的建议进行操作;但在我的情况下它仍然不起作用。知道我应该调查什么吗?
    • 您是否将流添加到 RTCPeerConnection,然后使用信号器发送新的 SDP?
    • 我已经能够让它工作,但只能在 Chrome 上(查看我的编辑)
    • 您是否尝试过从您的 RTCPeerConnection 实例调用 getLocalStreams 而不是 navigator.mediaDevices
    • 尝试获取流时?通常 pc.getLocalStreams() 在我调用 addTrack 之前不会返回任何内容。而且我仍然不明白为什么更改 pc 的 localDescription 会使事情在 chrome 而不是 FF 上工作......
    猜你喜欢
    • 2013-02-16
    • 2021-11-16
    • 1970-01-01
    • 2012-01-04
    • 2021-01-07
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2015-04-30
    相关资源
    最近更新 更多