Remote stream doesn't show in Video tag

844 views
Skip to first unread message

Yaniv Hakim

unread,
Jul 17, 2016, 9:00:25 AM7/17/16
to discuss-webrtc
Hi all,

I'm trying to set a basic video chat example. currently trying to chat between two chrome tabs on the same computer.
Everything looks good  until i get the remote video stream. and when i put it in the remoteVideo element i just get blank... no video showing although i got the remote stream event...

what can cause this? any ideas? pls help!

this is the log of the caller:
VM7581:51 BY_WebRTC.startSession HOQfXIe3uoLMtDgSlHVH+A== true
VM7581:110 Created RTCPeerConnnection
VM7581:130 Sending offer to peer
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:75 Received answer
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:191 Remote stream added. MediaStreamEvent {stream: MediaStream, type: "addstream", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM7581:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: null, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}bubbles: falsecancelBubble: falsecancelable: falsecandidate: nullcurrentTarget: RTCPeerConnectiondefaultPrevented: falseeventPhase: 0path: Array[0]returnValue: truesrcElement: RTCPeerConnectiontarget: RTCPeerConnectiontimeStamp: 25776.495type: "icecandidate"__proto__: RTCIceCandidateEvent
VM7581:159 End of candidates.

this is the log of the calee:
BY_WebRTC.startSession HOQfXIe3uoLMtDgSlHVH+A== undefined
webrtc.js?v=2.22:65 Received offer
webrtc.js?v=2.22:110 Created RTCPeerConnnection
webrtc.js?v=2.22:135 Sending answer to peer.
webrtc.js?v=2.22:191 Remote stream added. MediaStreamEvent {stream: MediaStream, type: "addstream", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
webrtc.js?v=2.22:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
webrtc.js?v=2.22:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
webrtc.js?v=2.22:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
webrtc.js?v=2.22:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: RTCIceCandidate, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
webrtc.js?v=2.22:148 handleIceCandidate event:  RTCIceCandidateEvent {candidate: null, type: "icecandidate", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
webrtc.js?v=2.22:159 End of candidates.

Eric Davies

unread,
Jul 17, 2016, 1:29:21 PM7/17/16
to discuss-webrtc
1) Have you verified that you have a valid local media stream by displaying it?
2) You probably haven't added the remote candidates to the peer connection or the attempt to do so failed.

Posting your code would be helpful.

Yaniv Hakim

unread,
Jul 17, 2016, 5:11:02 PM7/17/16
to discuss-webrtc
thanks for the help!
1) yes. i see the the local video on both sides
2) here is an updated logs + code

<p><strong>caller:</strong></p>

<pre><code>    Got userMedia
    Registered signaling room
    BY_WebRTC.startSession HOQfXIe3uoLMtDgSlHVH+A== true
    VM9840:128 tryStart: created peer connection.
    VM9840:150 Created RTCPeerConnnection
    VM9840:133 tryStart: added stream to peer connection.
    VM9840:170 Sending offer to peer
    VM9840:184 sending sdp RTCSessionDescription {type: "offer", sdp: "v=0
    ↵o=- 3416476007859143551 2 IN IP4 127.0.0.1
    ↵s…9521 label:a8a8592f-d78d-40b2-bc1c-1a7c33772201
    ↵"}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:3054232416 1 udp 2122260223 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:3708192848 1 udp 2122194687 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:3054232416 2 udp 2122260222 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:3708192848 2 udp 2122194686 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:3054232416 1 udp 2122260223 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "video", sdpMLineIndex: 1}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:3708192848 1 udp 2122194687 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "video", sdpMLineIndex: 1}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:3054232416 2 udp 2122260222 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "video", sdpMLineIndex: 1}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:3708192848 2 udp 2122194686 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "video", sdpMLineIndex: 1}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:4169670544 1 tcp 1518280447 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:2474996896 1 tcp 1518214911 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:4169670544 2 tcp 1518280446 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:2474996896 2 tcp 1518214910 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:4169670544 1 tcp 1518280447 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "video", sdpMLineIndex: 1}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:2474996896 1 tcp 1518214911 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "video", sdpMLineIndex: 1}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:4169670544 2 tcp 1518280446 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "video", sdpMLineIndex: 1}
    VM9840:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:2474996896 2 tcp 1518214910 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "video", sdpMLineIndex: 1}
    VM9840:110 Received answer
    VM9840:207 Remote stream added. MediaStreamEvent {stream: MediaStream, type: "addstream", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
    VM9840:191 handleIceCandidate event:  null
    VM9840:202 End of candidates.
</code></pre>

<p><strong>callee:</strong></p>

<pre><code>Got User Media
Registered signaling room
Received offer
webrtc.js?v=2.22:128 tryStart: created peer connection.
webrtc.js?v=2.22:150 Created RTCPeerConnnection
webrtc.js?v=2.22:133 tryStart: added stream to peer connection.
webrtc.js?v=2.22:175 Sending answer to peer.
webrtc.js?v=2.22:207 Remote stream added. MediaStreamEvent {stream: MediaStream, type: "addstream", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
webrtc.js?v=2.22:184 sending sdp RTCSessionDescription {type: "answer", sdp: "v=0
↵o=- 1405083852183288173 2 IN IP4 127.0.0.1
↵s…5319 label:9a0427e6-be00-4a66-a862-77c1deafb89d
↵"}
webrtc.js?v=2.22:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:3054232416 1 udp 2122260223 169.254.80.8… generation 0 ufrag wf8+wbbJ2eepjam8 network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
webrtc.js?v=2.22:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:3708192848 1 udp 2122194687 172.19.67.39… generation 0 ufrag wf8+wbbJ2eepjam8 network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
webrtc.js?v=2.22:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:4169670544 1 tcp 1518280447 169.254.80.8… generation 0 ufrag wf8+wbbJ2eepjam8 network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
webrtc.js?v=2.22:191 handleIceCandidate event:  RTCIceCandidate {candidate: "candidate:2474996896 1 tcp 1518214911 172.19.67.39… generation 0 ufrag wf8+wbbJ2eepjam8 network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
webrtc.js?v=2.22:191 handleIceCandidate event:  null
webrtc.js?v=2.22:202 End of candidates.
</code></pre>

<p><strong>code (starts at startSession with isInitiator=true for caller - after got local media):</strong></p>

<pre><code>var BY_WebRTC = {

    // consts
    pc_config: {
        'iceServers': [
                        { url: 'stun:stun1.l.google.com:19302' }]
    },
    pc_constraints: { 'optional': [{ 'DtlsSrtpKeyAgreement': true }] },
    sdpConstraints: {
        'mandatory': {
            // Set up audio and video regardless of what devices are present.
            'OfferToReceiveAudio': true,
            'OfferToReceiveVideo': true
        }
    },

    localStream: null,
    remoteStream: null,

    isStarted: false,
    isInitiator: false,

    realtimeEventId: null, // current conversation object realtime server room id

    pc: null, // peer connection

    getUserMedia: function (video, audio, callback) {
        var constraints = { video: video, audio: audio };       
        navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
            BY_WebRTC.localStream = stream;
            callback(stream);
        }).catch(function (error) {
            console.log("BY_WebRTC:getUserMedia Error!", error);
        });

    },

    startSession: function (encryptedObjectId, isInitiator) {

        // store the realtime event id
        BY_WebRTC.realtimeEventId = { groupType: 'object', groupId: encryptedObjectId, eventType: "webrtc" };
        BY_WebRTC.encryptedObjectId = encryptedObjectId;

        // register chat room for webrtc signaling
        nowManager.registerGroupEvents([BY_WebRTC.realtimeEventId], BY_WebRTC.realtimeWebRTC_EventHandler);

        console.log("BY_WebRTC.startSession", encryptedObjectId, isInitiator);

        if (isInitiator) {
            BY_WebRTC.isInitiator = true;
            BY_WebRTC.tryStart();
        }
    },

    realtimeWebRTC_EventHandler: function (message) {

        if (message === 'start') {
            BY_WebRTC.tryStart();
        }
        else if (message.type === 'offer') {
            console.log('Received offer');

            if (!BY_WebRTC.isInitiator &amp;&amp; !BY_WebRTC.isStarted) {
                BY_WebRTC.tryStart();
            }

            BY_WebRTC.pc.setRemoteDescription(new RTCSessionDescription(message));
            BY_WebRTC.sendAnswer();
        }
        else if (message.type === 'answer' &amp;&amp; isStarted) {
            console.log('Received answer');
            BY_WebRTC.pc.setRemoteDescription(new RTCSessionDescription(message));
        }
        else if (message.type === 'candidate' &amp;&amp; BY_WebRTC.isStarted) {
            var candidate = new RTCIceCandidate({
                sdpMLineIndex: message.label,
                candidate: message.candidate
            });
            BY_WebRTC.pc.addIceCandidate(candidate);
        }
        else if (message === 'bye' &amp;&amp; BY_WebRTC.isStarted) {
            BY_WebRTC.handleRemoteHangup();
        }
    },

    tryStart: function () {

        if (!BY_WebRTC.isStarted &amp;&amp; typeof BY_WebRTC.localStream != null) {
            console.log("tryStart: created peer connection.");

            BY_WebRTC.createPeerConnection();
            BY_WebRTC.pc.addStream(BY_WebRTC.localStream);

            console.log("tryStart: added stream to peer connection.");

            isStarted = true;

            if (BY_WebRTC.isInitiator) {
                BY_WebRTC.sendOffer();
            }
        }
    },

    createPeerConnection: function () {
        try {
            var pc = new RTCPeerConnection(this.pc_config);
            pc.onicecandidate = this.handleIceCandidate;
            pc.onaddstream = this.handleRemoteStreamAdded;
            pc.onremovestream = this.handleRemoteStreamRemoved;

            console.log('Created RTCPeerConnnection');

            BY_WebRTC.pc = pc;

        } catch (e) {
            console.log('Failed to create PeerConnection, exception: ' + e.message);
            alert('Cannot create RTCPeerConnection object.');
            return;
        }
    },

    handleCreateOfferError: function (event) {
        console.log('sendOffer() error: ', e);
    },

    handleSendAnswerError: function (event) {
        console.log('sendAnswer() error: ', e);
    },

    sendOffer: function () {
        console.log('Sending offer to peer');
        BY_WebRTC.pc.createOffer(BY_WebRTC.setLocalAndSendMessage, BY_WebRTC.handleCreateOfferError);
    },

    sendAnswer: function () {
        console.log('Sending answer to peer.');
        BY_WebRTC.pc.createAnswer(BY_WebRTC.setLocalAndSendMessage, BY_WebRTC.handleSendAnswerError, BY_WebRTC.sdpConstraints);
    },

    setLocalAndSendMessage: function (sessionDescription) {
        // Set Opus as the preferred codec in SDP if Opus is present.
        sessionDescription.sdp = BY_WebRTC.preferOpus(sessionDescription.sdp);
        BY_WebRTC.pc.setLocalDescription(sessionDescription);

        console.log("sending sdp", sessionDescription);

        nowManager.sendGroupEvent(BY_WebRTC.realtimeEventId, sessionDescription);
    },

    handleIceCandidate: function (event) {

        console.log('handleIceCandidate event: ', event.candidate);

        if (event.candidate) {
            nowManager.sendGroupEvent(BY_WebRTC.realtimeEventId, {
                type: 'candidate',
                label: event.candidate.sdpMLineIndex,
                id: event.candidate.sdpMid,
                candidate: event.candidate.candidate
            });
        }
        else {
            console.log('End of candidates.');
        }
    },

    handleRemoteStreamAdded: function (event) {
        console.log('Remote stream added.', event);

        // todo: send callback event after got remote stream
        document.querySelector('#remoteVideo').src = window.URL.createObjectURL(event.stream);
        BY_WebRTC.remoteStream = event.stream;

        $("#remoteVideo").show();
    },

    handleRemoteStreamRemoved: function (event) {
        console.log('Remote stream removed. Event: ', event);
    },

    hangup: function () {
        console.log('Hanging up.');
        this.stop();
        nowManager.sendGroupEvent(this.realtimeEventId, "bye");
    },

    handleRemoteHangup: function () {
        //  console.log('Session terminated.');
        // stop();
        // isInitiator = false;
    },

    stop: function () {
        BY_WebRTC.isStarted = false;
        BY_WebRTC.pc.close();
        BY_WebRTC.pc = null;
    }

}
</code></pre>

Yaniv Hakim

unread,
Jul 17, 2016, 5:45:34 PM7/17/16
to discuss-webrtc
Eric! thank you very much. thanks to you i found the problem... i didn't add the candidates because of a small bug.
thanks again!
Reply all
Reply to author
Forward
0 new messages