Ich entwickle eine Web-Plattform mit WebRTC, um eine Peer-to-Peer-Video-Konversation für Interviews zu erstellen. Die Kommunikation wird mit ASP.NET SignalR hergestellt. Hier ist die Javascript für den Verbindungsaufbau:WebRTC Firefox: Nicht genug Argumente zu RTCPeerConnection.setLocalDescription
function initInterview() {
//Gets user's media
navigator.getUserMedia({ video: true, audio: true }, function (stream) {
// Display local stream to the user
var localMediaElem = document.querySelector('video#me');
localMediaElem.volume = 0.0;
localMediaElem.srcObject = stream;
// Assign stream
_myMediaStream = stream;
showUI(true);
console.log("Added local media stream");
// No startInterview call (waiting for interviewee to create offer)
}, function (event) {
// Something failed
console.log(event);
});
};
function _createConnection() {
console.log('Creating RTCPeerConnection...');
// Create a new PeerConnection
var connection = new RTCPeerConnection(null); // null = no ICE servers
// A new ICE candidate was found
connection.onicecandidate = function (event) {
if (event.candidate) {
// Let's send it to our peer via SignalR
interview.server.send(interviewGuid, JSON.stringify({ "candidate": event.candidate }));
}
};
// New remote media stream was added
connection.onaddstream = function (event) {
// Get other video element
var newVideoElement = document.querySelector('video#other');
// Attach the stream to the Video element via adapter.js
newVideoElement.srcObject = event.stream;
};
return connection;
}
// Callback that receives notifications from the SignalR server
interview.client.newMessage = function (data) {
console.log("Received message");
console.log(data);
var message = JSON.parse(data),
connection = _myConnection || _createConnection(null);
// An SDP message contains connection and media information, and is either an 'offer' or an 'answer'
if (message.sdp) {
console.log("Received session description");
connection.setRemoteDescription(new RTCSessionDescription(message.sdp), function() {
console.log("Description:");
console.log(connection.remoteDescription);
if (connection.remoteDescription.type == 'offer') {
console.log('received offer, sending answer...');
// Add our stream to the connection to be shared
connection.addStream(_myMediaStream);
// Create an SDP response
connection.createAnswer(function (desc) {
// Which becomes our local session description
connection.setLocalDescription(desc, function() {
// And send it to the originator, where it will become their RemoteDescription
interview.server.send(interviewGuid, JSON.stringify({ 'sdp': connection.localDescription }));
});
}, function (error) { console.log('Error creating session description: ' + error); });
} else if (connection.remoteDescription.type == 'answer') {
console.log('got an answer');
}
});
} else if (message.candidate) {
console.log('adding ice candidate...');
connection.addIceCandidate(new RTCIceCandidate(message.candidate));
}
_myConnection = connection;
};
function startInterview() {
console.log("Starting interview");
_myConnection = _myConnection || _createConnection(null);
// Add our stream to the peer connection
_myConnection.addStream(_myMediaStream);
// Create an offer to send our peer
_myConnection.createOffer(function (desc) {
// Set the generated SDP to be our local session description
console.log(desc);
_myConnection.setLocalDescription(desc, function() {
// And send it to our peer, where it will become their RemoteDescription
interview.server.send(interviewGuid, JSON.stringify({ "sdp": desc }));
});
}, function (error) { console.log('Error creating session description: ' + error); });
};
Der Interviewte schafft ein Angebot auf folgende Weise:
function initInterview() {
//Gets user's media
navigator.getUserMedia({ video: true, audio: true }, function (stream) {
// Display local stream to the user
var localMediaElem = document.querySelector('video#me');
localMediaElem.volume = 0.0;
localMediaElem.srcObject = stream;
// Assign stream
_myMediaStream = stream;
showUI(true);
console.log("Added local media stream");
// Create offer for interviewer
startInterview();
}, function (event) {
// Something failed
console.log(event);
});
};
Es funktioniert perfekt, wenn wir Google Chrome verwenden, aber wenn wir Firefox verwenden wir bekommen der folgende Fehler:
Started SignalR hub b39c24ad-bd2d-42bf-829a-176bda8e3905:224:21
Added local media stream b39c24ad-bd2d-42bf-829a-176bda8e3905:344:25
Starting interview b39c24ad-bd2d-42bf-829a-176bda8e3905:355:21
Creating RTCPeerConnection... b39c24ad-bd2d-42bf-829a-176bda8e3905:265:21
onaddstream is deprecated! Use peerConnection.ontrack instead.
RTCSessionDescription { type: "offer", sdp: "v=0 o=mozilla...THIS_IS_SDPARTA-47.…" } b39c24ad-bd2d-42bf-829a-176bda8e3905:365:25
Received message b39c24ad-bd2d-42bf-829a-176bda8e3905:292:21
"{"sdp":{"type":"offer","sdp":"v=[...]a0f1\r\n"}}" b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21
Received session description b39c24ad-bd2d-42bf-829a-176bda8e3905:299:25
Received message b39c24ad-bd2d-42bf-829a-176bda8e3905:292:21
{"candidate":{"candidate":"candidate:2880323124 2 udp 2122260222 192.168.1.116 43234 typ host generation 0 ufrag bg8D7wuLUvtu/QjB network-id 1","sdpMid":"audio","sdpMLineIndex":0}} b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21
adding ice candidate... b39c24ad-bd2d-42bf-829a-176bda8e3905:322:25
Received message b39c24ad-bd2d-42bf-829a-176bda8e3905:292:21
{"candidate":{"candidate":"candidate:2880323124 1 udp 2122260223 192.168.1.116 56886 typ host generation 0 ufrag bg8D7wuLUvtu/QjB network-id 1","sdpMid":"audio","sdpMLineIndex":0}} b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21
[...]
{"candidate":{"candidate":"candidate:3844981444 2 tcp 1518280446 192.168.1.116 9 typ host tcptype active generation 0 ufrag bg8D7wuLUvtu/QjB network-id 1","sdpMid":"video","sdpMLineIndex":1}} b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21
adding ice candidate... b39c24ad-bd2d-42bf-829a-176bda8e3905:322:25
TypeError: Not enough arguments to RTCPeerConnection.setLocalDescription.
Dieser Code wird verwendet und verändert die connection.onicecandidate es funktioniert: 'interview.server.send (interviewGuid, JSON.stringify ({ "sdpMLineIndex": event.label "Kandidat": event.candidate})); ' – Zomtorg
@Zomtorg Hmm, [sdpMLineIndex] (http://w3c.github.io/webrtc-pc/#dom-rtcicecandidate-sdpmlineindex) ist normalerweise eine Eigenschaft von' event.candidate' selbst und ist eine Zahl . Ich nehme an, Sie können das, was Sie möchten, für die Signalisierung stringifizieren, aber es ist ein merkwürdiger Name, den Sie verwenden können, und hat im Browser AFAIK keine besondere Bedeutung. – jib