我正在尝试创建一个用于在浏览器中拨打音频的应用。我找到了本教程并开始使用它作为基础:https://www.webrtc-experiment.com/docs/WebRTC-PeerConnection.html
经过一些调整以满足我的需求。我最终得到了以下内容:
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发送的offerSDP设置远程rtc会话描述。完成后,即可启动答案。这将触发浏览器请求网络摄像头和麦克风。此时,错误发生在接收呼叫的对等方。然后将流添加到对等体。然后设置会话描述,并且对等体创建答案。完成后,将设置本地描述,并将包含答案的消息发送给主叫对等方。然后设置会话描述并最终确定信令部分。此时,调用对等体发生错误。
但是每当我到达从其他对等方添加远程流的部分时,我都会收到以下错误。
Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided
。
有什么想法吗?
答案 0 :(得分:2)
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);
};