Совместное использование экрана с помощью getScreenId.js в WebRTC для двух партнеров

Я пытаюсь реализовать функцию совместного использования экрана в видеоконференцсвязи webrtc. Из предложения я теперь следую за решением muaz-khan, используя https://www.webrtc-experiment.com/getScreenId/. Я могу легко захватить изображения приложений одного партнера и заменить видеопоток потоком захвата. Но это эксперимент по видеоконференцсвязи, поэтому два браузера должны проводить видеоконференцию друг с другом. Например, в браузере 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);
           });
    });

Любая помощь или предложение были бы благодарны.

Спасибо, что указали на другой пост: Как добавить трек в MediaStream в WebRTC, но я не думаю, что они такие же. И также я не уверен, как повторно согласовать удаленное соединение в этом случае.

Файл Xsocket.webrtc.js для подключения webrtc: https://github.com/XSockets/XSockets.WebRTC/blob/master/src/js/XSockets.WebRTC.latest.js

Как я мог бы повторно согласовать удаленное соединение в этом случае?


person Pengzhi Zhou    schedule 03.06.2016    source источник
comment
Возможный дубликат Как добавить трек в MediaStream в WebRTC   -  person jib    schedule 03.06.2016
comment
Если вы используете Firefox, вы также можете использовать replaceTrack.   -  person jib    schedule 03.06.2016
comment
@jib, Спасибо, что указали на другой пост: Как добавитьTrack в MediaStream в WebRTC, похоже, это может помочь, но пока не уверен, что они такие же, поскольку использование повторного согласования может помочь обновить удаленный поток в браузере 2 .. Итак Вы имеете в виду, когда делитесь приложением в локальном потоке браузера 1, затем запускаете команду на сервер и уведомляете браузер 2, чтобы обновить его удаленный поток (который = локальный поток в браузере 1). Но в этом случае в браузере 2 удаленный поток все еще использует старую конфигурацию getusermedia. Поскольку я просто обновляю источник в локальном потоке, не более того.   -  person Pengzhi Zhou    schedule 05.06.2016
comment
Удаленные потоки поступают не из getUserMedia, они исходят из RTCPeerConnection. Вы должны переключить, какой поток вы отправляете на другую сторону. К сожалению, как это сделать, зависит от браузера, как упоминается в другом ответе.   -  person jib    schedule 06.06.2016
comment
@jib, из сообщения, которое вы мне отправили, использует pc.onnegotiationneeded из удаленного потока в браузере 2, правильно ли я понимаю? Поскольку в моем коде я использую файл javascript warp xsocket webrtc для установления соединения, не могли бы вы объяснить больше, как я могу выполнить повторное согласование для удаленного потока? Я прикрепил ключевой код xsocket webrtc в своем исходном сообщении. Благодарю.   -  person Pengzhi Zhou    schedule 07.06.2016
comment
@jib, для файла xsocket.webrtc.js: github.com/XSockets/XSockets.WebRTC/blob/master/src/js/…, как я могу провести повторное согласование в этом случае? . В настоящее время я пытаюсь отправить команду на сервер, вернуть ее в браузере удаленного потока и обновить поток с помощью согласования, но не могу этого сделать. Происходят ошибки. И я использую только хром.   -  person Pengzhi Zhou    schedule 07.06.2016
comment
pc.onnegotiationneeded находится на стороне отправителя (на самом деле оба конца). У меня нет понимания или времени для отладки вашего конкретного случая, но я обновил свой ответ в повторяющемся вопросе на включить рабочее повторное согласование через демонстрацию канала данных. Надеюсь, это поможет!   -  person jib    schedule 07.06.2016


Ответы (1)


Я сам нашел решение для этого вопроса, не заменяйте локальный поток потоком sharecreen, вместо этого удалите старый локальный поток из локального div, а затем добавьте новый поток sharecreen в локальный div. Тем временем отправьте старый идентификатор локального потока через datachanel другому одноранговому узлу, а также удалите это старое удаленное видео.

Самая важная вещь - это обновить потоки (повторное согласование), тогда поток sharecreen будет отображаться на удаленном узле.

Код:

$('#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 удаленному узлу. Все сложнее.

person Pengzhi Zhou    schedule 07.06.2016