Share screen using getScreenId.js in WebRTC for two peers

1.6k views Asked by At

I am trying to implement share screen function in webrtc video conferencing. From suggestion, I am now following muaz-khan's solution using https://www.webrtc-experiment.com/getScreenId/ . I can easily capture the application images of one peer, and replace the video stream with the capture stream. But it is a video conferencing experiment, so two browsers need to video conference with each other. For example, browser 1, has video streams A (local video), video streams B (remote video); browser 2 has video streams B (local video), video streams A (remote video). So when I am in browser 1 and trying to share the screen, the share screen stream should replace the local video in browser 1, and remote video in browser 2.

But right now, I can only make the share screen replace the local video in browser 1, browser 2 doesn't have any changes, cann't see any changes in its remote video (which is the local video in browser 1). I don't know how to trigger the changes in browser 2 as well. do i need to signal the share screen streams to server? and change the remote stream accordingly?

Here is my code in 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;

}); 

I am using xsocket as the server, and the codes for click share and change the local stream with the share screen streams are just very simple as this:

$('#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);
           });
    });

Any help or suggestion would be grateful.

Thanks for pointing out the other post: How to addTrack in MediaStream in WebRTC, but I don't think they are the same. And also I am not sure how to renegotiate the remote connection in this case.

Xsocket.webrtc.js file for webrtc connection: https://github.com/XSockets/XSockets.WebRTC/blob/master/src/js/XSockets.WebRTC.latest.js

How I could I renegotiate the remote connection in this case?

2

There are 2 answers

0
Pengzhi Zhou On

I figured out a work around solution by myself for this question, do not replace the local stream with the sharescreen stream, instead remove the old local stream from local div, then add the new sharescreen stream to local div. In the meantime, send the old local stream id by datachanel to the other peer, and remove that old remote video as well.

The most important thing is reflesh the streams (renegotiation), then sharescreen stream would display in remote peer.

Code:

$('#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);
           });
   });            
}); 

after get the command to remove that old video stream from the server:

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

This solution works for me. Although if only like to replace the local video stream with share screen stream, we need to re create the offer with sdp, and send sdp to remote peer. It is more complicated.

0
Bulut Ağırman On
 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);
  });
});