在WebRTC中使用getScreenId.js为两个对等方共享屏幕

在WebRTC中使用getScreenId.js为两个对等方共享屏幕,webrtc,getusermedia,video-conferencing,screensharing,xsocket,Webrtc,Getusermedia,Video Conferencing,Screensharing,Xsocket,我正在尝试在webrtc视频会议中实现共享屏幕功能。根据建议,我现在使用muaz khan的解决方案。我可以轻松地捕获一个对等方的应用程序图像,并用捕获流替换视频流。但这是一个视频会议实验,所以两个浏览器需要进行视频会议。例如,浏览器1具有视频流A(本地视频)、视频流B(远程视频);浏览器2具有视频流B(本地视频)、视频流A(远程视频)。因此,当我在浏览器1中尝试共享屏幕时,共享屏幕流应替换浏览器1中的本地视频和浏览器2中的远程视频 但现在,我只能让共享屏幕替换浏览器1中的本地视频,浏览器2没有

我正在尝试在webrtc视频会议中实现共享屏幕功能。根据建议,我现在使用muaz khan的解决方案。我可以轻松地捕获一个对等方的应用程序图像,并用捕获流替换视频流。但这是一个视频会议实验,所以两个浏览器需要进行视频会议。例如,浏览器1具有视频流A(本地视频)、视频流B(远程视频);浏览器2具有视频流B(本地视频)、视频流A(远程视频)。因此,当我在浏览器1中尝试共享屏幕时,共享屏幕流应替换浏览器1中的本地视频和浏览器2中的远程视频

但现在,我只能让共享屏幕替换浏览器1中的本地视频,浏览器2没有任何更改,在其远程视频(即浏览器1中的本地视频)中看不到任何更改。我也不知道如何触发浏览器2中的更改。我是否需要向服务器发送共享屏幕流信号?并相应地更改远程流

以下是我的javascript代码:

$(function() {
    var brokerController, ws, webRTC, localid; 
    // ws = new XSockets.WebSocket("wss://rtcplaygrouund.azurewebsites.net:443", ["connectionbroker"], {
    ws = new XSockets.WebSocket("ws://localhost:4502", ["connectionbroker"], {
        ctx: "152300ed-4d84-4e72-bc99-965052dc1e95"
    }); 

    var addRemoteVideo = function(peerId,mediaStream) {
        var remoteVideo = document.createElement("video");
        remoteVideo.setAttribute("autoplay", "true");
        remoteVideo.setAttribute("rel",peerId);
        attachMediaStream(remoteVideo, mediaStream);                       
        remoteVideo.setAttribute("class", "col-md-3");
        remoteVideo.setAttribute("height", $( document ).height() * 0.3);
        remoteVideo.setAttribute("id", 'remoteVideo');                      
        $("#videoscreen").append(remoteVideo);
    };

    var onConnectionLost = function (remotePeer) {
        console.log("onconnectionlost");
        var peerId = remotePeer.PeerId;
        var videoToRemove = $("video[rel='" + peerId + "']");
        videoToRemove.remove();
    };

    var oncConnectionCreated = function() {
        console.log("oncconnectioncreated", arguments);
    }

    var onGetUerMedia = function(stream) {
    console.log("Successfully got some userMedia , hopefully a goat will appear..");
    webRTC.connectToContext(); // connect to the current context?
    };

    var onRemoteStream = function (remotePeer) {      
    addRemoteVideo(remotePeer.PeerId, remotePeer.stream);
    console.log("Opps, we got a remote stream. lets see if its a goat..");

    };

    var onLocalStream = function(mediaStream) {
    console.log("Got a localStream", mediaStream.id);
    localid = mediaStream.id;
    console.log("check this id:  meadiastram id ", mediaStream.id);

    var video = document.createElement("video");
    video.setAttribute("height", "100%");
    video.setAttribute("autoplay", "true");
    video.setAttribute("id", "localvideo");
    video.setAttribute("name", mediaStream.id);

    attachMediaStream(video, mediaStream);                  
    $("#videoscreen").append(video);

    $('#share').click(function() {

        getScreenId(function (error, sourceId, screen_constraints) {

            navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
            navigator.getUserMedia(screen_constraints, function (stream) {
                $('#localvideo').attr('src', URL.createObjectURL(stream));                     

            }, function (error) {
                console.error(error);
                });
            });
        });

    };

    var onContextCreated = function(ctx) {
    console.log("RTC object created, and a context is created - ", ctx);
    webRTC.getUserMedia(webRTC.userMediaConstraints.hd(true), onGetUerMedia, onError);
    };

    var onOpen = function() {
        console.log("Connected to the brokerController - 'connectionBroker'");

        webRTC = new XSockets.WebRTC(this);
        webRTC.onlocalstream = onLocalStream;
        webRTC.oncontextcreated = onContextCreated;
        webRTC.onconnectioncreated = oncConnectionCreated;
        webRTC.onconnectionlost = onConnectionLost;       
        webRTC.onremotestream = onRemoteStream;
    };

    var onConnected = function() {
        console.log("connection to the 'broker' server is established");
        console.log("Try get the broker controller form server..");
        brokerController = ws.controller("connectionbroker");
        brokerController.onopen = onOpen;

    };              
    ws.onconnected = onConnected;

}); 
我使用xsocket作为服务器,单击共享和使用共享屏幕流更改本地流的代码非常简单,如下所示:

$('#share').click(function() {
    getScreenId(function (error, sourceId, screen_constraints) {
        navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
        navigator.getUserMedia(screen_constraints, function (stream) {
            $('#localvideo').attr('src', URL.createObjectURL(stream));

        }, function (error) {
               console.error(error);
           });
    });
任何帮助或建议都将不胜感激

谢谢你指出另一个帖子:,但我觉得它们不一样。而且我也不知道在这种情况下如何重新协商远程连接

用于webrtc连接的Xsocket.webrtc.js文件:


在这种情况下,我如何重新协商远程连接?

我为这个问题找到了一个解决方案,不要用sharescreen流替换本地流,而是从本地div中删除旧的本地流,然后将新的sharescreen流添加到本地div。同时,通过datachanel将旧的本地流id发送到另一个对等方,并删除旧的远程视频

最重要的是重新刷新流(重新协商),然后sharescreen流将显示在远程对等机中

代码:

$('#share').click(function() {
    getScreenId(function (error, sourceId, screen_constraints) {
        navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
        navigator.getUserMedia(screen_constraints, function (stream) {
            webRTC.removeStream(webRTC.getLocalStreams()[0]);
            var id = $('#localvideo').attr('name');
            $('#localvideo').remove();
            brokerController.invoke('updateremotevideo', id);
            webRTC.addLocalStream(stream);
            webRTC.getRemotePeers().forEach(function (p) {
                webRTC.refreshStreams(p);
            });
        }, function (error) {
               console.error(error);
           });
   });            
}); 
获取从服务器中删除旧视频流的命令后:

brokerController.on('updateremotevideo', function(streamid){
    $(document.getElementById(streamid)).remove();
});

这个解决方案对我有效。虽然我们只想用共享屏幕流替换本地视频流,但我们需要用sdp重新创建报价,并将sdp发送给远程对等方。它更复杂

如果您使用的是Firefox,您也可以使用。@jib,感谢您指出另一篇文章:如何在WebRTC的MediaStream中添加Track,这似乎有帮助,但还不能确定它们是否相同,因为使用重新协商可以帮助刷新浏览器2中的远程流。。所以,您的意思是当在浏览器1的本地流中共享应用程序时,触发一个命令到服务器,并通知浏览器2更新其远程流(它=浏览器1中的本地流)。但在本例中,在浏览器2中,远程流仍然使用旧的getusermedia配置。因为我只是更新了本地流中的源代码,没有别的了。远程流不是来自getUserMedia,而是来自RTPeerConnection。您必须切换要发送到另一端的流。不幸的是,正如另一个答案所提到的那样,如何在不同的浏览器中实现这一点各不相同。@jib,从你发给我的帖子中,正在使用pc.onGetationNeedfrom remote stream在浏览器2中,我理解正确吗?因为在我的代码中,我使用一个warp-xsocket-webrtc-javascript文件来建立连接,您能解释一下我如何对远程流进行重新协商吗?我在我的原始帖子中附上了关键的xsocket webrtc代码。谢谢
 getScreenId(function (error, sourceId, screen_constraints) {
  navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
  navigator.getUserMedia(screen_constraints, function (stream) {
    navigator.getUserMedia({audio: true}, function (audioStream) {
      stream.addTrack(audioStream.getAudioTracks()[0]);
      var mediaRecorder = new MediaStreamRecorder(stream);
      mediaRecorder.mimeType = 'video/mp4'
      mediaRecorder.stream = stream;
      self.setState({recorder: mediaRecorder, startRecord: true,  shareVideo: true, pauseRecord: false, resumeRecord: false, stopRecord: false, downloadRecord: false, updateRecord: false});
      document.querySelector('video').src = URL.createObjectURL(stream);
      var video =  document.getElementById('screen-video')
      if (video) {
        video.src = URL.createObjectURL(stream);
        video.width = 360;
        video.height = 300;
      }
    }, function (error) {
      alert(error);
    });
  }, function (error) {
    alert(error);
  });
});