我正在尝试在来电者和被叫者之间建立一个简单的p2p视频聊天。
这是代码:
var OnBroadcast
, i
, isCaller = true
//just for testing pourpose
, URLparams = $location.search()
, iceServers = {
'iceServers':[{
'url':'stun:stun.l.google.com:19302'
}]
}
, connOpt = {
'optional':[{
'DtlsSrtpKeyAgreement': true
}]
}
, sdpConstraints = {
'mandatory': {
'OfferToReceiveAudio': true,
'OfferToReceiveVideo': true
}
}
, localVideo = $window.document.getElementById('localVideo')
, remoteVideo = $window.document.getElementById('remoteVideo')
, peerConnection = new RTCPeerConnection(iceServers, connOpt);
if (URLparams && URLparams.stranger) {
isCaller = false;
}
peerConnection.onaddstream = function (stream) {
if (!isCaller) {
$log.info('Caller Stream is', stream);
peerConnection.addStream(stream.stream);
remoteVideo.src = $window.URL.createObjectURL(stream.stream);
}
};
peerConnection.onicecandidate = function (ices) {
if (isCaller) {
ws.broadcast({
'scope': 'callerICES',
'message': ices
});
} else {
ws.broadcast({
'scope': 'calleeICES',
'message': ices
});
}
};
navigator.getUserMedia({
'audio': true,
'video': true
}, function (stream) {
localVideo.src = $window.URL.createObjectURL(stream);
if (isCaller) {
/* VIDEO CHAT P2P----------
* create CALLER Peer
* CALLER addStream to peer
* create CALLER Offer and CALLER setLocalDescription
* send CALLER Offer to CALLEE and set CALLEE remoteDescription
* create Answer from CALLEE and CALLEE setLocalDescription
* send Answer to CALLER and set CALLER setRemoteDescription
* CALLER icecandidate and send it to CALLEE and CALLEE addIceCandidate
* CALLEE icecandidate and send it to CALLER and CALLER addIceCandidate
* CALLEE addStream
*/
peerConnection.addStream(stream);
peerConnection.createOffer(function (offer) {
peerConnection.setLocalDescription(offer, function () {
ws.broadcast({
'scope': 'callerOFFER',
'message': offer
});
});
}, function (err) {
$log.error('Unable to create Offer from Caller', err);
});
}
}, function (err) {
$log.error('Unable to getUserMedia', err);
});
OnBroadcast = $rootScope.$on('comunicator:toAll', function (eventInfo, message) {
if (message.what.scope === 'callerOFFER') {
if (!isCaller) {
peerConnection.setRemoteDescription(new RTCSessionDescription(message.what.message), function () {
peerConnection.createAnswer(function (answer) {
$log.info('Setup localDesc Callee');
peerConnection.setLocalDescription(new RTCSessionDescription(answer), function () {
ws.broadcast({
'scope':'calleeANSWER',
'message': answer
});
}, function (err) {
$log.info('Unable to set localDesc for Callee', err);
},
sdpConstraints);
}, function (err) {
$log.error('Unable to create Answer from Callee', err);
});
});
}
}
if (message.what.scope === 'calleeANSWER') {
if (isCaller) {
peerConnection.setRemoteDescription(new RTCSessionDescription(message.what.message), function () {
$log.info('Setup remoteDesc Callee');
});
}
}
if (message.what.scope === 'callerICES') {
if (!isCaller) {
for (i = 0; i < message.what.length; i += 1) {
peerConnection.addIceCandidate(new RTCIceCandidate(message.what[i]));
}
$log.info('Setup CALLEE ices', message.what);
}
}
if (message.what.scope === 'calleeICES') {
if (isCaller) {
for (i = 0; i < message.what.length; i += 1) {
peerConnection.addIceCandidate(new RTCIceCandidate(message.what[i]));
}
$log.info('Setup CALLER ices', message.what);
}
}
});
一切似乎都有效,但是当我将远程视频附加到<video id="remoteVideo"></video>
时,我只看到一个黑色视频,我正在同一个网址和相同的wifi上测试:
来电者:localhost:8000
callee:localhost:8000?stranger = true
有人可以解释一下我的问题是什么吗?
答案 0 :(得分:0)
我们应该注意,在设置remoteDescription之前,我们不会将ICECandidate
添加到PeerConnection
,假设这不是您当前的问题,可能是:
peerConnection.onaddstream = function (stream) {
if (!isCaller) {
$log.info('Caller Stream is', stream);
peerConnection.addStream(stream.stream); // ---> specially this line.
remoteVideo.src = $window.URL.createObjectURL(stream.stream);
}
};
我不确定为什么被叫方正在发回远程流,因为它的本地流,除了使用此代码时,调用方在接收到被叫方的流时,什么都不做。 peerConnection.addStream
用于与远程用户共享本地流。通常被叫者不必等待来电者的流来回应它的流。所以将上面的代码改为......
peerConnection.onaddstream = function (event) {
$log.info('add stream event:', event);
remoteVideo.src = $window.URL.createObjectURL(event.stream);
};
... // also add the retrieved stream to peerConnection for both caller and callee.
navigator.getUserMedia({
'audio': true,
'video': true
}, function (stream) {
peerConnection.addStream(stream); // before if (isCaller) check
localVideo.src = $window.URL.createObjectURL(stream);
if (isCaller) {
...
除此之外,我希望您编写的代码只是测试WebRTC工作的原型,它有一些设计问题,其中很少可能是: