更改RTCPeerConnection的MediaStream

wpp*_*wpp 16 javascript google-chrome webrtc sipml

我想从音频/视频流更改为"屏幕共享"流:

peerConnection.removeStream(streamA) // __o_j_sep... in Screenshots below
peerConnection.addStream(streamB)  // SSTREAM in Screenshots below
Run Code Online (Sandbox Code Playgroud)
  • streamA 是来自我的相机和麦克风的视频/音频流.
  • streamB 是我从我的扩展中获得的屏幕截图.
  • 它们都是MediaStream对象,如下所示:

streamA

streamB

*1备注

但是,如果我删除streamApeerConnectionaddStream(streamB)喜欢上面好像没有什么改变.

以下按预期工作(两端的流被删除并重新添加)

peerConnection.removeStream(streamA) // __o_j_sep...
peerConnection.addStream(streamA) // __o_j_sep...
Run Code Online (Sandbox Code Playgroud)

更多细节

我发现这个例子是"反向"(从屏幕截图切换到带摄像头的音频/视频),但无法发现显着差异.

peerConnection RTCPeerConnection对象实际上是由这创造SIPML库 源可以在这里找到代码.我这样访问它:

var peerConnection = stack.o_stack.o_layer_dialog.ao_dialogs[1].o_msession_mgr.ao_sessions[0].o_pc
Run Code Online (Sandbox Code Playgroud)

(是的,这看起来不正确,但是没有正式的方法来访问Peer Connection,请参阅此处的讨论)和此处.

最初我试图用(视频)改变videoTrack of streamA videoTrack streamB.在这里查看问题.有人向我建议我应该尝试重新协商对等连接(通过删除/添加Streams),因为addTrack不会触发重新协商.

我也在这里寻求帮助,但维护者似乎很忙,没有机会回应.


*1 备注:为什么streamB没有videoTracks财产?流在HTML <video>元素中播放,似乎"有效".我是这样得到的:

navigator.webkitGetUserMedia({
  audio: false,
  video: {
    mandatory: {
      chromeMediaSource:  'desktop',
      chromeMediaSourceId: streamId,
      maxWidth: window.screen.width,
      maxHeight: window.screen.height
      //,   maxFrameRate: 3
    }
  }
  // success callback
}, function(localMediaStream) {
  SSTREAM = localMediaStream; //streamB

  // fail callback
}, function(error) {
  console.log(error);
});
Run Code Online (Sandbox Code Playgroud)

它似乎也有一个videoTrack:

streamB的videoTrack

我在跑:

  • OS X 10.9.3
  • Chrome版本35.0.1916.153

Ben*_*ent 9

要回答您的第一个问题,在活动对等连接中修改MediaStream时,peerconnection对象将触发onnegotiationneeded事件.您需要处理该事件并重新交换您的SDP.这背后的主要原因是双方都知道在它们之间发送了什么流.当交换SDP时,包括mediaStream ID,并且如果存在具有新ID的新流(具有所有其他条件相同的事件),则必须进行重新协商.

对于你的第二个问题(约SSTREAM).它确实包含视频轨道,但没有视频轨道属性webkitMediaStreams.但是,您可以通过其ID获取曲目.

由于每种媒体类型都有可能存在多个轨道,因此视频轨道或录音轨道没有单一属性,而是一系列类型.该.getVideoTracks()调用返回当前videoTracks的数组.因此,您可以通过指示其索引来获取特定视频轨道.getVideoTracks()[0].