1

hello to all I am new in this I have all almost done,but just on my initiator for say something I don't know the way for receiver the remote video stream after receiver the answer, can some one help me please ?

this is my client

$(document).ready(() => {

    const configuration = {
        iceServers: [{ url: 'stun:stun2.1.google.com:19302' }]
    }

    var peerConection = null;
    // var btnCall = $('body #call');
    var list = $('#mylist');
    var TitlePrint = $('#titleUser');
    var localVideo = document.getElementById('local');
    var remoteVideo = document.getElementById('remote');
    var userid = null;

    var socket = io();


    socket.on('connect', () => {
        userid = socket.id
        TitlePrint.text(userid);
    });



    socket.on('users', data => {
        var users = [];
        list.empty();
        for (let index = 0; index < data.user.length; index++) {
            if (data.user[index] != userid) {
                users.push(`<button id="call" class="list-group-item list-group-item-action" data-ids="${data.user[index]}">${data.user[index]}</button>`);
            }
        }
        if (users.length != 0) {

            list.html(users);
        } else {
            list.html(`<div class="list-group-item"> Any users connected! </div>`);
        }
    });


    $('body').on('click', '#call', function () {
        let toId = $(this).attr('data-ids');
        socket.emit('initiator', { initiatorid: userid, receiverid: toId });
    });


    socket.on('initiator', data => {

        peerConection = createRTC(socket);

        if (data.initiatorid === userid) {
            console.log('this is the initiator');
            initiateSignaling(socket, peerConection, data.receiverid, data.initiatorid);
        } else {
            console.log('this is the receiver');
            prepareToReceiveOffer(socket, peerConection, data.initiatorid, data.receiverid);
        }
    });


    // =============== HELPERS =====================//

    function createRTC(socket) {
        console.log('createRTC')
        var peerConection = new RTCPeerConnection(configuration);
        peerConection.onicecandidate = (e) => {
            if (e.candidate) {
                console.log('emit candidate')
                socket.emit('send-candidate', e.candidate);
            }
        }

        socket.on('receiver-candidate', (candidate) => {
            peerConection.addIceCandidate(candidate);
        });

        return peerConection;
    }

    function initiateSignaling(socket, peerConection, targetID, from) {
        navigator.mediaDevices.getUserMedia({ video: true, audio: false }).then((stream) => {
            stream.getTracks().forEach(function (track) {
                peerConection.addTrack(track, stream);
            });
            localVideo.srcObject = stream;
            peerConection.createOffer().then(function (offer) {
                return peerConection.setLocalDescription(offer);
            })
                .then(function () {
                    socket.emit('send-offer', {
                        from: from,
                        target: targetID,
                        type: "send-offer",
                        sdp: peerConection.localDescription
                    });
                })
                .catch(function (reason) {
                    console.log('error on create offer', reason);
                });

        })

        socket.on('receiver-answer', (answer) => {
            console.log(answer);
            peerConection.setRemoteDescription(answer.sdp);
            peerConection.ontrack = function (event) {
                remoteVideo.srcObject = event.streams[0];
            };
        });


    }



    function prepareToReceiveOffer(socket, peerConection, targetID, from) {
        socket.on('receiver-offer', (offer) => {
            console.log(offer);
            peerConection.setRemoteDescription(offer.sdp);
            peerConection.createAnswer().then(function (answer) {
                return peerConection.setLocalDescription(answer);
            })
                .then(function () {
                    socket.emit('send-answer', {
                        from: from,
                        target: targetID,
                        type: "send-answer",
                        sdp: peerConection.localDescription
                    });
                });

            peerConection.ontrack = function (event) {
                remoteVideo.srcObject = event.streams[0];
            };
            navigator.mediaDevices.getUserMedia({ video: true, audio: false }).then((stream) => {
                localVideo.srcObject = stream;
            })
        });
    }

});

I just using socket.io I am handle the offer and answer then on my socket server I just set like this

socket.on('initiator', (init) => {
        console.log(init);
        io.to('video').emit('initiator', init);
    });

    socket.on('send-offer', offer => {
        console.log('sending offer', offer);
        socket.broadcast.emit('receiver-offer', offer);
    });

    socket.on('send-answer', answer => {
        console.log('sending answer', answer);
        socket.broadcast.emit('receiver-answer', answer);
    });

    socket.on('send-candidate', candidate => {
       console.log(candidate);
       socket.broadcast.emit('receiver-candidate',candidate);
    });

I am get video remote on my receiver from the initiator but not in the initiator, I don't know what I miss for getting the remote video thanks so mush guys

2 Answers2

2

The initiator calls addTrack(), but not the receiver doesn't, so this is only sending media one way.

In prepareToReceiveOffer you call getUserMedia() but never add resulting tracks to the peer connection. If you want a two-way call, it needs to call addTrack() as part of the offer/answer negotiation.

Just be sure to call getUserMedia() after setRemoteDescription to not miss ICE candidates:

function prepareToReceiveOffer(socket, peerConection, targetID, from) {
    socket.on('receiver-offer', (offer) => {
        console.log(offer);
        peerConection.setRemoteDescription(offer.sdp)
            .then(() => navigator.mediaDevices.getUserMedia({video: true, audio: false}))
            .then(stream => {
                localVideo.srcObject = stream;
                for (const track of stream.getTracks()) {
                    peerConection.addTrack(track, stream);
                }
                return peerConection.createAnswer();
            })
            .then(function (answer) {
                return peerConection.setLocalDescription(answer);
            })
            .then(function () {
                socket.emit('send-answer', {
                    from: from,
                    target: targetID,
                    type: "send-answer",
                    sdp: peerConection.localDescription
                });
            })
            .catch(err => console.log(err.message));

        peerConection.ontrack = function (event) {
            remoteVideo.srcObject = event.streams[0];
        };
    });
}
jib
  • 40,579
  • 17
  • 100
  • 158
  • Sorry to hear that. I'd personally move the two `peerConection.ontrack =` to one in `createRTC()`, but I don't see anything immediately wrong here. Here's a working [fiddle](https://jsfiddle.net/jib1/ges8uqom/) if it helps. – jib Mar 08 '19 at 22:47
0

I get resolve it, in this particular case I my initiateSignaling function when I receiver the offer I has to include this

socket.on('receiver-answer', (answer) => {
    console.log(answer);
    peerConection.setRemoteDescription(answer.sdp)
    .then(function () {
        return navigator.mediaDevices.getUserMedia({video:true, audio: false});
    })
    .then(function (stream) {
        return peerConection.addStream(stream);
    })

    peerConection.ontrack = function (event) {
        remoteVideo.srcObject = event.streams[0];
    };
});

now is working for me