peerConnection.addIceCandidate给出错误:无效的字符串

Arj*_*jaj 5 html5 websocket node.js socket.io webrtc

我正在尝试实现仅限语音的WebRTC应用.我在Chrome上运行它Version 29.0.1547.0 dev.我的应用程序使用Socket.IO作为信令机制.

peerConnection.addIceCandidate() 给我这个错误: Uncaught SyntaxError: An invalid or illegal string was specified.

和另外,peerConnection.setRemoteDescription();给我这个错误:Uncaught TypeMismatchError: The type of an object was incompatible with the expected type of the parameter associated to the object.

这是我的代码:

SERVER(在CoffeeScript中)

app = require("express")()
server = require("http").createServer(app).listen(3000)
io = require("socket.io").listen(server)

app.get "/", (req, res) -> res.sendfile("index.html")
app.get "/client.js", (req, res) -> res.sendfile("client.js")

io.sockets.on "connection", (socket) ->
    socket.on "message", (data) ->
        socket.broadcast.emit "message", data
Run Code Online (Sandbox Code Playgroud)

CLIENT(用JavaScript)

var socket = io.connect("http://localhost:3000");

var pc = new webkitRTCPeerConnection({
    "iceServers": [{"url": "stun:stun.l.google.com:19302"}]
});


navigator.getUserMedia = navigator.webkitGetUserMedia ||
    navigator.mozGetUserMedia;

navigator.getUserMedia({audio: true}, function (stream) {
    pc.addStream(stream);
}, function (error) { console.log(error); });


pc.onicecandidate = function (event) {
    if (!event || !event.candidate) return;
    socket.emit("message", {
        type: "iceCandidate",
        "candidate": event.candidate
    });
};


pc.onaddstream = function(event) {
    var audioElem = document.createElement("audio");
    audioElem.src = webkitURL.createObjectURL(event.stream);
    audioElem.autoplay = true;
    document.appendChild(audioElem);
    console.log("Got Remote Stream");
};


socket.on("message", function(data) {
    if (data.type === "iceCandidate") {
        console.log(data.candidate);

        candidate = new RTCIceCandidate(data.candidate);
        console.log(candidate);

        pc.addIceCandidate(candidate);

    } else if (data.type === "offer") {
        pc.setRemoteDescription(data.description);
        pc.createAnswer(function(description) {
            pc.setLocalDescription(description);
            socket.emit("message", {type: "answer", description: description});
        });
    } else if (data.type === "answer") {
        pc.setRemoteDescription(data.description);
    }
});


function offer() {
    pc.createOffer( function (description) {
        pc.setLocalDescription(description);
        socket.emit("message", {type: "offer", "description": description});
    });
};
Run Code Online (Sandbox Code Playgroud)

HTML只包含一个调用按钮offer().

我可以确认ICECandidates并且SessionDescriptions正在从一个客户端成功转移到另一个客户端.

我究竟做错了什么?我应该如何修复这些和任何其他错误,以便我可以将音频从一个客户端传输到另一个客户端?

PS:如果您了解记录WebRTC API的良好来源(W3C文档除外),请告诉我相关信息!

谢谢!

Mer*_*tce 14

对于该错误,重点是,只有在成功设置远程描述后才能添加ICE Candidates.

请注意,在创建Offer(由Offerer)之后,立即生成冰候选者.因此,如果回答者以某种方式接收这些候选人,在设置远程描述(理论上将在候选人之前到达)之前,您会收到错误.

对于提议者来说也是如此.它必须在添加任何冰候选者之前设置远程描述.

我在你的javascript代码中看到你并不能保证在添加冰候选者之前设置了远程描述.

首先,pc.addIceCandidate(candidate);如果设置了pc的remoteDescription ,你可以在之前检查.如果您看到它为null(或未定义),则可以在设置remoteDescription后在本地存储已接收的冰候选者(或等待提交者在适当的时间发送它们).