【问题标题】:WebRTC video chat for Firefox-to-Chrome and Chrome-to-Firefox not workingFirefox 到 Chrome 和 Chrome 到 Firefox 的 WebRTC 视频聊天不起作用
【发布时间】:2016-03-19 16:55:24
【问题描述】:

我正在尝试基于 WebRTC API 实现一个非常简单的视频聊天。 不幸的是,到目前为止,我的代码只能从 Chrome 到 Chrome 以及从 Firefox 到 Firefox 运行。

如果我从 Chrome 到 Firefox 或从 Firefox 到 Chrome 尝试它,我会得到以下错误输出:

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***

我是否可能遗漏了什么,或者我需要 Chrome 或 Firefox 浏览器中的一些标志?

你有什么想法吗?如果我能得到任何帮助来解决这个问题,我将不胜感激。

提前谢谢大家!


我的helloWebRtc.js 看起来像这样:

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);
        }
    );
}

我的 NodeJS 服务器(使用 express.io)如下所示:

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);

【问题讨论】:

  • 您是否在同一台机器上同时运行 chrome 和 firefox 浏览器?
  • 对于开发,是的,我愿意——这有什么不同吗?
  • 我认为这是问题所在,他们共享同一个摄像头/麦克风可能会导致问题...
  • 可能是一个原因。但为什么它适用于 Chrome-to-Chrome 或 Firefox-to-Firefox?在这些情况下,两者是否也使用相同的摄像头/麦克风?
  • 但是在同一个程序中,我的猜测是像相机这样的硬件不能在程序之间共享

标签: google-chrome firefox webrtc


【解决方案1】:

你可以比较一下chrome和firefox生成的offer SDP,可能会有一些不兼容的差异。

【讨论】:

    【解决方案2】:

    编辑下面的旧答案:Chrome 和 Firefox 之间的互操作性存在几个错误。 webrtc 团队的某个人给了我一个建议,让我把要约人留在同一个聚会上。因此,如果 A 在建立到 B 的流时创建了一个报价,那么 B 在建立到 A 的流时会要求 A 创建一个新的报价,而不是创建一个自己。

    另见此处: https://bugs.chromium.org/p/webrtc/issues/detail?id=5499#c15

    我确实注意到,如果 Firefox 启动会话,Chrome 会将来自 Firefox 的流踢出视频元素,但您可以在流上创建一个新的对象 URL 并将其设置为源。

    希望对您有所帮助。

    旧消息:

    我正在经历同样的事情,所以如果你有答案,我很好奇。

    我确实认为 FireFox 和 Chrome 在设置 DTLS 角色时存在不匹配(错误),另请参阅:

    https://bugs.chromium.org/p/webrtc/issues/detail?id=2782#c26

    【讨论】:

      【解决方案3】:

      只需检查您是否在创建对等连接时将 DtlsSrtpKeyAgreement 参数设置为 true。

      pc = new RTCPeerConnection(pc_config,{optional: [{RtpDataChannels: true},{
              DtlsSrtpKeyAgreement: true}]});
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-28
        • 1970-01-01
        • 2012-01-07
        • 1970-01-01
        • 2016-06-30
        • 2020-12-30
        相关资源
        最近更新 更多