更改RTCPeerConnection的MediaStream

时间:2014-06-16 08:35:18

标签: javascript google-chrome webrtc sipml

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

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

streamA

streamB

* 1备注

但是,如果我从streamApeerConnection移除addStream(streamB),则似乎没有发生任何事情。

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

peerConnection.removeStream(streamA) // __o_j_sep...
peerConnection.addStream(streamA) // __o_j_sep...

更多细节

我找到了this example,而#34;反向" (使用相机从屏幕截图切换到音频/视频)但无法发现显着差异。

peerConnection RTCPeerConnection对象实际上是由SIPML library source code available here创建的。我这样访问它:

var peerConnection = stack.o_stack.o_layer_dialog.ao_dialogs[1].o_msession_mgr.ao_sessions[0].o_pc

(是的,这看起来不正确,但没有官方方式可以访问对等连接see discussion here)和here

最初我尝试使用streamA的videoTrack(仅)(ex)更改streamB的videoTracks。 See question here。有人建议我尝试重新协商对等连接(通过删除/添加Streams),因为addTrack不会触发re-negotitation

I've also asked for help here但维护者似乎非常忙碌而且还没有机会做出回应。


* 1 备注:为什么streamB没有videoTracks属性?该流在HTML <video>元素中播放,似乎&#34;工作&#34;。我是这样得到的:

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

它似乎也有videoTrack

videoTrack of streamB

我正在跑步:

  • OS X 10.9.3
  • Chrome版本35.0.1916.153

2 个答案:

答案 0 :(得分:9)

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

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

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

答案 1 :(得分:1)

我做了类似的事情,点击按钮我删除了活动流并添加了另一个。

这就是我这样做的方式,它对我来说非常适合,

_this.rtc.localstream.stop();
_this.rtc.pc.removeStream(_this.rtc.localstream);

gotStream = function (localstream_aud){
var constraints_audio={
    audio:true
   }

_this.rtc.localstream_aud = localstream_aud;
_this.rtc.mediaConstraints= constraints_audio;   
_this.rtc.createOffer();
}
getUserMedia(constraints_audio, gotStream);

gotStream = function (localstream){
var constraints_screen={
        audio:false,
        video:{
            mandatory:{
                chromeMediaSource: 'screen'
            }
        }
    }
  _this.rtc.localstream = localstream;
  _this.rtc.mediaConstraints=constraints_video;


  _this.rtc.createStream();  
  _this.rtc.createOffer();
}
getUserMedia(constraints_video, gotStream);

Chrome不允许音频和“屏幕”,因此我为其创建了一个单独的流。 您需要执行相反操作才能切换回较旧的视频流或实际转换为您想要的任何其他流。

希望这有帮助