将WebRTC与Socket.io一起使用
我正在尝试创建一个用于在浏览器中进行音频通话的应用程序。我找到了本教程并开始使用它作为基础: 经过一些调整以满足我的需要。我的结论如下:将WebRTC与Socket.io一起使用,socket.io,webrtc,Socket.io,Webrtc,我正在尝试创建一个用于在浏览器中进行音频通话的应用程序。我找到了本教程并开始使用它作为基础: 经过一些调整以满足我的需要。我的结论如下: var iceServers = [ { url: 'stun:stun1.l.google.com:19302' }, { url: 'turn:numb.viagenie.ca', credential: 'muazkh', username: 'webrtc@live.com' } ]; var sdpConstraints = {
var iceServers = [
{ url: 'stun:stun1.l.google.com:19302' },
{ url: 'turn:numb.viagenie.ca', credential: 'muazkh', username: 'webrtc@live.com' }
];
var sdpConstraints = {
optional: [],
mandatory: {
OfferToReceiveAudio: true,
OfferToReceiveVideo: false
}
};
var DtlsSrtpKeyAgreement = {
DtlsSrtpKeyAgreement: true
};
var optional = {
optional: [DtlsSrtpKeyAgreement]
};
var peer = new webkitRTCPeerConnection({
'iceServers': iceServers,
optional
});
function getAudio(successCallback, errorCallback){
navigator.webkitGetUserMedia(
{
audio: true,
video: false
},
successCallback,
errorCallback
);
}
function send_SDP() {
console.log('now emitting send sdp message');
SocketService.emit('message', {
'conversation_id': me.conversation_id,
'targetUser': to,
'sdp': peer.localDescription
});
}
function startCall(){
getAudio(
function(stream){
console.log('peer');
console.log(peer);
console.log('adding local stream');
peer.addStream(stream);
peer.createOffer(function(offerSDP) {
console.log('now creating offer');
peer.setLocalDescription(offerSDP, function(){
console.log('local description is set. now informing peer');
SocketService.emit('message', {
'conversation_id': me.conversation_id,
'targetUser': to,
'offerSDP': offerSDP
});
},
function(){
console.log('error setting local description')
});
console.log('now emitting offerSDP message');
},
function(){
console.log('error occured while creating offer');
},
sdpConstraints
);
console.log('now calling ' + to);
},
function(err){
console.log('an error occured while getting the audio');
}
);
};
function createAnswer(offerSDP) {
getAudio(
function(stream){
console.log('now creating answer');
console.log(stream);
console.log('NOW ADDING STREAM');
peer.addStream(stream);
var remoteDescription = new RTCSessionDescription(offerSDP);
peer.setRemoteDescription(remoteDescription);
peer.createAnswer(function(answerSDP) {
peer.setLocalDescription(answerSDP, function(){
console.log('done setting local description');
console.log('now emitting answer sdp message');
SocketService.emit('message', {
'conversation_id': me.conversation_id,
'targetUser': to,
'answerSDP': answerSDP
});
},
function(){
console.log('error setting local description');
});
}, function(err){
alert('error occured while creating answer');
console.log(err);
}, sdpConstraints);
},
function(err){
alert('error occured while getting the audio for answer');
}
);
};
SocketService.on('message', function(msg){
if(msg.offerSDP){
var remoteDescription = new RTCSessionDescription(msg.offerSDP);
peer.setRemoteDescription(remoteDescription, function(){
console.log('done setting remote description');
createAnswer(msg.offerSDP);
},
function(){
console.log('error setting remote description');
});
}
if(msg.answerSDP) {
var remoteDescription = new RTCSessionDescription(msg.answerSDP);
peer.setRemoteDescription(remoteDescription, function(){
console.log('finished signaling offers and answers!');
},
function(){
console.log('error signaling offers and answers');
});
}
if(msg.candidate) {
var candidate = msg.candidate.candidate;
var sdpMLineIndex = msg.candidate.sdpMLineIndex;
peer.addIceCandidate(new RTCIceCandidate({
sdpMLineIndex: sdpMLineIndex,
candidate: candidate
}));
}
});
peer.onaddstream = function(stream){
console.log('now adding remote stream');
console.log(stream);
audio.src = window.URL.createObjectURL(stream); //this is where the error occurs
};
peer.onicecandidate = function(event) {
console.log('on ice candidate');
var candidate = event.candidate;
console.log(candidate);
console.log('after ice candidate');
if(candidate) {
console.log('now emitting candidate message');
SocketService.emit('message', {
'conversation_id': me.conversation_id,
'targetUser': to,
'candidate': candidate
});
}
console.log(typeof candidate);
if(typeof candidate == 'undefined') {
console.log('now sending sdp');
send_SDP();
}
};
peer.ongatheringchange = function(e) {
if (e.currentTarget && e.currentTarget.iceGatheringState === 'complete') {
send_SDP();
}
};
这里发生的事情是,首先在单击调用按钮时调用startCall
方法。这会触发浏览器请求访问网络摄像头和麦克风。一旦用户接受它,就会使用addStream
方法添加本地流。之后,将创建一个报价并设置本地描述。然后,我使用socket.io向对等方发送消息以发送报价。收到要约后,使用通过socket.io发送的要约DP设置远程rtc会话描述。一旦完成,答案就开始了。这将触发浏览器请求网络摄像头和麦克风。此时,错误发生在接收呼叫的对等方。然后将流添加到对等方。然后设置会话描述,对等方创建一个答案。完成后,将设置本地描述,并将包含答案的消息发送给呼叫对等方。然后设置会话描述并最终确定信令部分。此时,错误发生在调用的对等方上
但是,每当我到达添加来自另一个对等方的远程流的部分时,就会出现以下错误
未能对“URL”执行“createObjectURL”:未找到与提供的签名匹配的函数
有什么想法吗?
peer.onaddstream
不是用流激发的,而是用包含流的事件对象激发的:
更改此项:
peer.onaddstream = function(stream){
console.log('now adding remote stream');
console.log(stream);
audio.src = window.URL.createObjectURL(stream);
};
为此:
peer.onaddstream = function(event){
console.log('now adding remote stream');
console.log(event);
console.log(event.stream);
audio.src = window.URL.createObjectURL(event.stream);
};
传递给
createObjectUrl
的stream
的值是多少?你确定这是一个流吗?你已经在哪个浏览器上运行了测试?@ObscureGeek我主要在Ubuntu中使用Chrome和Chrome@是的,这是一条小溪。我使用了console.log
check@Kyokasuigetsu由于您仅在Chrome和Chrome上进行测试,因此尝试使用webkitURL.createObjectURL(stream)代码>?是的,它说它已经被弃用了。如果我使用了URL.createObjectURL
,我认为它会退回到使用URL.createObjectURL。然后我得到了同样的错误