WebRTC videocall移动热点错误
我正在尝试使用WebRTC和SocketIO为消息传递构建一个简单的p2p视频通话。当两个客户端都连接到不同的WIFI网络时,视频聊天可以正常工作,但当其中一个客户端使用移动热点时,无法建立连接。以下是一些可能有助于发现问题的关键代码块: 开始通话/createOfferWebRTC videocall移动热点错误,webrtc,stun,Webrtc,Stun,我正在尝试使用WebRTC和SocketIO为消息传递构建一个简单的p2p视频通话。当两个客户端都连接到不同的WIFI网络时,视频聊天可以正常工作,但当其中一个客户端使用移动热点时,无法建立连接。以下是一些可能有助于发现问题的关键代码块: 开始通话/createOffer function callNeighbor(){ if(buddy=={}){console.log('CALL_NEIGHBOR Neighbor NULL')} else{ const servers =
function callNeighbor(){
if(buddy=={}){console.log('CALL_NEIGHBOR Neighbor NULL')}
else{
const servers = {iceServers: [{urls: 'stun:stun1.l.google.com:19305'}]};
pc=new RTCPeerConnection(servers);
pc.onicecandidate = e => onIceCandidate(pc, e);
pc.ontrack=gotRemoteStream;
pc.onnegotiationneeded=function(){
pc.createOffer().then(success=>{
console.log(success)
pc.setLocalDescription(success).then(success=>{
socket.emit('rtcRequest',{from:name,to:buddy.name,body:pc.localDescription});
},error=>{
console.log(failure);
});
},
failure=>{
console.log(failure);
})
}
navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);
}
}
function handleCall(stream) {
console.log(stream);
localOut.srcObject = stream;
localStream = stream;
const audioTracks = localStream.getAudioTracks();
if (audioTracks.length > 0) {
// console.log(`Using Audio device: ${audioTracks[0].label}`);
}
localStream.getTracks().forEach(track => pc.addTrack(track, localStream));
// console.log('Adding Local Stream to peer connection');
pc.createAnswer().then(answer=>{
pc.setLocalDescription(answer).then(success=>{
socket.emit('rtcResponse',{from:name,to:buddy.name,body:pc.localDescription});
},error=>{console.log(error)})
},error=>{console.log(error)})
}
onICECandidate
function onIceCandidate(pc, event) {
const candidate=event.candidate
if(candidate==null){return}
console.log('**SENDING ICE** '+candidate)
console.log(candidate)
socket.emit("rtcICE",{from:name,to:buddy.name, body:candidate});
console.log(`PC ICE candidate:\n${candidate ? candidate.candidate : '(null)'}`);
}
socket.on('rtcICE',function(data){//rtcICE is via socketIO see onICECandidate above
pc.addIceCandidate((data.body)).then(success=>console.log(success),error=>console.log(error));
})
接听来电/createAnswer
function callNeighbor(){
if(buddy=={}){console.log('CALL_NEIGHBOR Neighbor NULL')}
else{
const servers = {iceServers: [{urls: 'stun:stun1.l.google.com:19305'}]};
pc=new RTCPeerConnection(servers);
pc.onicecandidate = e => onIceCandidate(pc, e);
pc.ontrack=gotRemoteStream;
pc.onnegotiationneeded=function(){
pc.createOffer().then(success=>{
console.log(success)
pc.setLocalDescription(success).then(success=>{
socket.emit('rtcRequest',{from:name,to:buddy.name,body:pc.localDescription});
},error=>{
console.log(failure);
});
},
failure=>{
console.log(failure);
})
}
navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);
}
}
function handleCall(stream) {
console.log(stream);
localOut.srcObject = stream;
localStream = stream;
const audioTracks = localStream.getAudioTracks();
if (audioTracks.length > 0) {
// console.log(`Using Audio device: ${audioTracks[0].label}`);
}
localStream.getTracks().forEach(track => pc.addTrack(track, localStream));
// console.log('Adding Local Stream to peer connection');
pc.createAnswer().then(answer=>{
pc.setLocalDescription(answer).then(success=>{
socket.emit('rtcResponse',{from:name,to:buddy.name,body:pc.localDescription});
},error=>{console.log(error)})
},error=>{console.log(error)})
}
添加Ice候选者
function onIceCandidate(pc, event) {
const candidate=event.candidate
if(candidate==null){return}
console.log('**SENDING ICE** '+candidate)
console.log(candidate)
socket.emit("rtcICE",{from:name,to:buddy.name, body:candidate});
console.log(`PC ICE candidate:\n${candidate ? candidate.candidate : '(null)'}`);
}
socket.on('rtcICE',function(data){//rtcICE is via socketIO see onICECandidate above
pc.addIceCandidate((data.body)).then(success=>console.log(success),error=>console.log(error));
})
日志
来电者
接受者
编辑以下是设置远程描述的代码
socket.on('rtcRequest',function(data){
const offer=data.body;
const servers = {iceServers: [{urls: 'stun:stun1.l.google.com:19305'}]};;
pc=new RTCPeerConnection(servers);
pc.onicecandidate = e => onIceCandidate(pc, e);
pc.ontrack=gotRemoteStream;
pc.onnegotiationneeded=function(){
console.log('NEGOTIATION NEEDED!!!')}
pc.setRemoteDescription(data.body).then(success=>{
navigator.mediaDevices.getUserMedia(constraints).then(handleCall).catch(handleError);
},
error=>{console.log(error)
}
);
})
我也有同样的问题。如果您控制自己的TURN服务器,请检查所有需要的端口UDP和TCP端口。在我的例子中,我忘了在我只打开UDP的TCP端口中打开3748。我也有同样的问题。如果您控制自己的TURN服务器,请检查所有需要的端口UDP和TCP端口。在我的例子中,我忘了在只打开UDP的TCP端口中打开3748。什么时候在接收器端执行setRemoteDescription()?@kenjitanaka刚刚在底部添加了它更新,该代码在两个不同的wifi网络上工作,但在移动热点上断开。在OnGotiationNeeded事件中不执行setRemoteDescription()。我不是,很抱歉,格式不正确,onnegotiationneeded只是控制台记录“需要协商”;我只是想看看它什么时候着火,所以这就是为什么我添加了在接收器端执行setRemoteDescription()的logWhen?@kenjitanaka刚刚在底部添加了它更新,代码在两个不同的wifi网络上工作,但在移动热点上断开。在OnGetiationRequired事件中不执行setRemoteDescription()。我不是,很抱歉,格式不正确,onnegotiationneeded只是控制台记录“需要协商”;我只是想看看它什么时候着火,所以我加了那个日志