getUserMedia()返回后可以立即使用MediaStream吗?

时间:2017-10-25 16:09:15

标签: javascript webrtc

我正在尝试从网站用户的手机中捕获音频,并将其传输到远程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();
    });
  });

1 个答案:

答案 0 :(得分:2)

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

在你的例子中

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

目前还不清楚如何定义stream。它可以是未定义的吗?

为什么不能使用以下内容?

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