Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebRTC video chat for Firefox-to-Chrome and Chrome-to-Firefox not working

I'm trying to implement a very simple video chat based on the WebRTC API. Unfortunately my Code is just working from Chrome-to-Chrome and from Firefox-to-Firefox so far.

If I try it from Chrome-to-Firefox or from Firefox-to-Chrome I get the following error output:

Failed to set local offer sdp: Session error code: ERROR_CONTENT. Session error description: Failed to set local video description recv parameters..(anonymous function) @ helloWebRtc.js:126***

Did I possibly missed something or do I need some flags in the Chrome or Firefox browser?

Do you have any idea? I would be grateful for any help I can get to solve this issue.

Thank you all in advance!


My helloWebRtc.js looks like this:

var localVideo = document.querySelector("#localVideo");
var remoteVideo = document.querySelector("#remoteVideo");

var SIGNAL_ROOM = "signal_room";
var CHAT_ROOM = "chat_room";
var serverConfig = {
    "iceServers": [
        {
            "urls": "stun:stun.l.google.com:19302"
        }
    ]
};

var optionalConfig = {
    optional: [
        {
            RtpDataChannels: true
        },
        {
            DtlsSrtpKeyAgreement: true
        }
    ]
};

var rtcPeerConn,
    localStream;

io = io.connect();
io.emit("ready", {"chat_room": CHAT_ROOM, "signal_room":   SIGNAL_ROOM});
io.emit("signal", {
    "room": SIGNAL_ROOM,
    "type": "user_here",
    "message": "new user joined the room"
});

io.on("rtcSignaling", function(data) {
    if(!rtcPeerConn) {
        startSignaling();
    }
    if(data.type !== "user_here" && data.message) {
        var message = JSON.parse(data.message);

        if(message.description) {
            var remoteDesc = new RTCSessionDescription(message.description);
            rtcPeerConn.setRemoteDescription(remoteDesc, function() {
                // if we receive an offer we need to answer
                if(rtcPeerConn.remoteDescription.type === "offer") {
                    rtcPeerConn.createAnswer(sendLocalDescription, function(error) {
                    console.error("error on creating answer", error);
                });
            }
        }, function(error) {
            console.error("error on set remote description", error);
        });
        } else if(message.candidate) {
            var iceCandidate = new RTCIceCandidate(message.candidate);
            rtcPeerConn.addIceCandidate(iceCandidate);
        }
    }
});

function startSignaling() {
    rtcPeerConn = new RTCPeerConnection(serverConfig, optionalConfig);

    //send any ice candidate to the other peer
    rtcPeerConn.onicecandidate = function(event) {
        if(event.candidate) {
            io.emit("signal", {
                "room": SIGNAL_ROOM,
                "type": "candidate",
                "message": JSON.stringify({
                    "candidate": event.candidate
                })
            });
        }
    };


    rtcPeerConn.onnegotiationneeded = function() {
        rtcPeerConn.createOffer(sendLocalDescription, function(error) {
            console.error("error on creating offer", error);
        });
    };

    // add the other peer's stream
    rtcPeerConn.onaddstream = function(event) {
        console.info("on add stream called");
        remoteVideo.srcObject = event.stream;
    };

    // add local stream
    navigator.mediaDevices.getUserMedia({
        audio: true,
        video: true
    })
    .then(function(stream) {
        localVideo.srcObject = stream;
        localStream = stream;
        rtcPeerConn.addStream(localStream);
    })
    .catch(function(e) {
        alert('getUserMedia() error: ' + e.name);
    });
}

function sendLocalDescription(description) {
    rtcPeerConn.setLocalDescription(
        description,
        function() {
            io.emit("signal", {
                "room": SIGNAL_ROOM,
                "type": "description",
                "message": JSON.stringify({
                    "description": rtcPeerConn.localDescription
                })
            });
        },
        function(error) {
            console.error("error to set local desc", error);
        }
    );
}

My NodeJS server (using express.io) looks like the following:

var express = require('express.io');
var app = express();
var PORT = 8686;

app.http().io();
console.log('server started @ localhost:8686');

// declaring folders to access i.e.g html files
app.use(express.static(__dirname + '/views'));
app.use('/scripts', express.static(__dirname + '/scripts'));

// root url i.e. "localhost:8686/"
app.get('/', function(req, res) {
    res.sendFile('index.html');
});


/**
* Socket.IO Routes for signaling pruposes
*/

app.io.route('ready', function(req) {
    req.io.join(req.data.chat_room);
    req.io.join(req.data.signal_room);
    app.io.room(req.data.chat_room).broadcast('announce', {
        message: 'New client in the ' + req.data.chat_room + ' room.'
    });
});

app.io.route('send', function(req) {
    app.io.room(req.data.room).broadcast('message', {
        message: req.data.message,
        author: req.data.author
    });
});

app.io.route('signal', function(req) {
    // Note: req means just broadcasting without letting the sender also receive their own message
    if(req.data.type === "description" || req.data.type === "candidate")
        req.io.room(req.data.room).broadcast('rtcSignaling', {
            type: req.data.type,
            message: req.data.message
        });
    else
        req.io.room(req.data.room).broadcast('rtcSignaling', {
            type: req.data.type
        });
});

app.listen(PORT);
like image 200
Dominic Avatar asked Nov 08 '22 23:11

Dominic


1 Answers

You can compare the offer SDP generated by the chrome and firefox, there might be some difference which is not interoperable to other.

like image 171
Palash Borhan Uddin Avatar answered Nov 15 '22 08:11

Palash Borhan Uddin