2013-06-27 2 views
5

Я пытаюсь реализовать приложение WebRTC с поддержкой голоса. Я запускаю его на Chrome Version 29.0.1547.0 dev. Мое приложение использует Socket.IO для механизма сигнализации.peerConnection.addIceCandidate, дающая ошибку: неверная строка

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 

КЛИЕНТ (в 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}); 
    }); 
}; 

HTML, просто содержит кнопку, которая вызывает offer().

Я могу подтвердить, что ICECandidates и SessionDescriptions успешно передаются от одного клиента к другому.

Что я делаю неправильно? И как мне исправить эти и любые другие ошибки, чтобы я мог передавать аудио с одного клиента на другой?

PS: Если вы знаете о хорошем источнике документирования API WebRTC (кроме документации W3C), сообщите мне об этом!

Спасибо!

+0

Можете ли вы вставить пример данных .candidate, что вы переходите к конструктору RTCIceCandidate? –

+0

Я не могу дать ответ на ваш конкретный вопрос, но я нашел [WebRTC-Series of html5rocks] (http://www.html5rocks.com/en/tutorials/webrtc/basics/) довольно хороший ресурс по этой теме. – Raoul

+0

Я не мог решить эту проблему даже путем кэширования удаленных кандидатов на лед, пока не будет установлено подробное описание. RTCIceCandidate {sdpMLineIndex: 1, sdpMid: "", кандидат: "a = кандидат: 924013166 1 tcp 1509957375 192.168.57.1 ​​0 тип генерации хоста 0 ↵"} app.js: 13895 Uncaught SyntaxError: указана недопустимая или незаконная строка , – Samson

ответ

13

Для этой ошибки необходимо указать, что ICE-кандидаты должны быть добавлены только после успешной настройки удаленного описания.

Обратите внимание, что сразу после создания Предложения (по предложению) кандидаты на льду производятся немедленно. Итак, если каким-то образом получатель получает этих кандидатов, перед тем, как установить удаленное описание (которое теоретически поступило бы перед кандидатами), вы получите ошибку.

То же самое можно сказать о приёмном. Он должен установить удаленное описание перед добавлением любого ледяного кандидата.

Я вижу, что в вашем javascript-коде вы не гарантируете, что удаленное описание задано перед добавлением кандидатов на лед.

Прежде всего, вы можете проверить перед pc.addIceCandidate(candidate);, если установлено дистанционное задание pc. Если вы видите, что он является нулевым (или неопределенным), вы можете локально хранить полученные ледяные кандидаты, чтобы добавить их после установки remoteDescription (или ждать, когда оферент будет отправлять их в нужное время.)

+0

Вы писали: 'который теоретически прибудет анте кандидатов. Я предполагаю, что «antes» - опечатка? Что ты хотел сказать? – Gili

+0

По ошибке я написал испанское слово. antes = before. Я исправил. –

+0

Итак, дайте мне знать, если я сделаю это правильно. 'onicecandidate' вызывается партией предложения сразу после создания« RTCPeerConnection ». Затем отвечающий одноранговый узел запускает 'addIceCandidate' с кандидатом сверстников предложения? – Costa