Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebRTC remote video is shown as black

While developing a WebRTC video chat application I have encountered receiving remote the video stream. The video stream blob is received, but the video is just black.

I have gone through these answers and tried almost everything I could to get it to work https://stackoverflow.com/a/17424224/923109 Remote VideoStream not working with WebRTC

......
Globalvars.socket.on('call', function (signal) {
    if(!Globalvars.pc){
        Methods.startCall(false, signal);
    }

    if(signal.sdp){
        temp = new RTCSessionDescription({"sdp" : decodeURIComponent(signal.sdp), "type" : signal.type});
        Globalvars.pc.setRemoteDescription(temp);
        for(i = 0; i < Globalvars.iceCandidateArray.length; i++){
            Globalvars.pc.addIceCandidate(new RTCIceCandidate({
                sdpMLineIndex: decodeURIComponent(signal.sdpMLineIndex),
                candidate: decodeURIComponent(signal.candidate)
            }));
        }

        Globalvars.iceCandidateArray = [];
    }
    else{
        if(Globalvars.pc.remoteDescription){
            Globalvars.pc.addIceCandidate(new RTCIceCandidate({
                sdpMLineIndex: decodeURIComponent(signal.sdpMLineIndex),
                candidate: decodeURIComponent(signal.candidate)
            }));
            console.log("remot");
        }
        else{
            Globalvars.iceCandidateArray.push(new RTCIceCandidate({
                sdpMLineIndex: decodeURIComponent(signal.sdpMLineIndex),
                candidate: decodeURIComponent(signal.candidate)
            }));
            console.log("ice candidate to temp array");
        }
    }
});


$("#roster-wrap").on("click", ".roster-list-item", function(e){
    //Globalvars.socket.emit('call', {"receiver_id" : $(this).attr("data-id"), "caller_id" : Globalvars.me.id});
    params = {"receiver_id" : $(this).attr("data-id"), "caller_id" : Globalvars.me.id};
    Methods.startCall(true, params);
    e.preventDefault();
});
.....


.....
// run start(true) to initiate a call
"startCall" : function (isCaller, params) {
    var configuration = {"iceServers": [{"url": "stun:stun.l.google.com:19302"}]};
    Globalvars.pc = new RTCPeerConnection(configuration);

    // send any ice candidates to the other peer
    Globalvars.pc.onicecandidate = function (evt) {
        //alert("ice candidate");
        if (!Globalvars.pc || !evt || !evt.candidate) return;
        var candidate = evt.candidate;
        Globalvars.socket.emit("call",{ "candidate": encodeURIComponent(candidate.candidate), "sdpMLineIndex" : encodeURIComponent(candidate.sdpMLineIndex), "receiver_id" :  params.receiver_id, "caller_id" : params.caller_id});
    };

    // once remote stream arrives, show it in the remote video element
    Globalvars.pc.onaddstream = function (evt) {
        console.log("add stream");
        if (!event) return;
        $("#remote-video").attr("src",URL.createObjectURL(evt.stream));
        Methods.waitUntilRemoteStreamStartsFlowing();
    };

    // get the local stream, show it in the local video element and send it
    navigator.getUserMedia({ "audio": false, "video": true }, function (stream) {
        $("#my-video").attr("src", URL.createObjectURL(stream));
        Globalvars.pc.addStream(stream);

        if (isCaller){
            Globalvars.pc.createOffer(getDescription, null, { 'mandatory': { 'OfferToReceiveAudio': true, 'OfferToReceiveVideo': true } });
        }
        else{
            console.log("Got Remote Description");
            console.log(Globalvars.pc.remoteDescription);               
            //Globalvars.pc.createAnswer(Globalvars.pc.remoteDescription, getDescription);
            Globalvars.pc.createAnswer(getDescription, null, { 'mandatory': { 'OfferToReceiveAudio': true, 'OfferToReceiveVideo': true } });
        }

        function getDescription(desc) {
            Globalvars.pc.setLocalDescription(desc);
            console.log("my desc");
            console.log(desc);
            Globalvars.socket.emit("call", {"sdp": encodeURIComponent(desc.sdp), "type": desc.type, "receiver_id" :  params.receiver_id, "caller_id" : params.caller_id});
            //signalingChannel.send(JSON.stringify({ "sdp": desc }));
        }
    });
},
......

The complete code is available at https://bitbucket.org/ajaybc/meetchat-client and https://bitbucket.org/ajaybc/meetchat-server

like image 279
ajaybc Avatar asked Sep 20 '13 09:09

ajaybc


2 Answers

You may need to add

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />

into your AndroidManifest.xml

I verified WebRTC works with https://download.01.org/crosswalk/releases/crosswalk/android/beta/7.36.154.12/ and https://apprtc.appspot.com/ on my Nexus 5.

Hope it works for you.

like image 69
Anuj Gupta Avatar answered Nov 19 '22 14:11

Anuj Gupta


I had the same issues as you, but only for some clients, and I explored the same avenues that you did. The last thing (and probably the ultimate cause of my issues) was related to the NAT situation behind at least one of the clients. There will always be the possibility of a situation where one of the clients cannot get a hole punched in their NAT, and therefore a STUN server will not work. In these cases, you need a TURN server to relay the video to that client.

What configuration do you have for your iceServers in your peerConnection? Does it contain any TURN servers that you know to work?

You can create a free account on this site http://xirsys.com/simplewebrtc/, and follow the simple instructions on getting credentials for a TURN server on their hosting, which you can then use to test if this is the issue.

like image 42
hynsey Avatar answered Nov 19 '22 15:11

hynsey