根据我们的网络 RTC 要求,有两个不同的客户端
- 播放器(播放由捕获客户端共享的屏幕)
- 捕获(共享屏幕) 两个 Web 客户端使用 WebSocket 通信和交换报价和 ICE 候选人。
在 Chrome [版本 84.0.4147.105(官方构建)(64 位)]
chrome 中的Player和Capture javascript 控制台中没有错误。但是如果我们检查chrome://webrtc-internals/我们可以看到以下事件和传输图:
在这里,我可以看到视频流正在传输但未在付款人端播放,并且在事件日志中显示 ICE Candidate 错误。这是视频流在付款人端不起作用的问题吗?
Firefox (v79.0) 在控制台中显示错误:
DOMException: No remoteDescription.
在 player.js 行号:33。任何想法为什么两个不同的浏览器有不同的错误?
播放器.js
(function(){
var localVideo, remoteVideo, localConnection, remoteConnection;
const MESSAGE_TYPE = {
SDP: 'SDP',
CANDIDATE_LOCAL: 'LOCAL_CANDIDATE',
CANDIDATE_REMOTE: 'REMOTE_CANDIDATE'
};
const signaling = new WebSocket('ws://127.0.0.1:1337');
var configuration = {
offerToReceiveAudio: true,
offerToReceiveVideo: true
}
remoteConnection = new RTCPeerConnection({configuration: configuration, iceServers: [{ urls: 'stun:aalimoshaver.com:3478' }]});
remoteConnection.onicecandidate = function(e) { !e.candidate
|| signaling.send(JSON.stringify({message_type:MESSAGE_TYPE.CANDIDATE_REMOTE, content: e.candidate.toJSON()}));
}
remoteConnection.ontrack = function (e) {
const remoteVideo = document.getElementById('remote-view');
if (!remoteVideo.srcObject) {
remoteVideo.srcObject = e.streams[0];
}
};
signaling.onmessage = function (message){
const data = JSON.parse(message.data);
const message_type = data.message_type;
const content = data.content;
try {
if (message_type === MESSAGE_TYPE.CANDIDATE_LOCAL && content) {
remoteConnection.addIceCandidate(content)
.catch(function (e) {
console.error(e)
});
}else if (message_type === MESSAGE_TYPE.SDP && content) {
if (content.type === 'offer') {
remoteConnection.setRemoteDescription(content);
remoteConnection.createAnswer()
.then(function(answer){
remoteConnection.setLocalDescription(answer);
signaling.send(JSON.stringify({
message_type: MESSAGE_TYPE.SDP,
content: answer
}));
});
} else {
console.log('Unsupported SDP type.');
}
}
} catch (err) {
console.error(err);
}
};
})()
捕获.js
/**
* Created by Sowvik Roy on 30-07-2020.
*/
(function () {
var localVideo, remoteVideo, localConnection, remoteConnection;
const MESSAGE_TYPE = {
SDP_LOCAL: 'SDP',
CANDIDATE_LOCAL: 'LOCAL_CANDIDATE',
CANDIDATE_REMOTE: 'REMOTE_CANDIDATE'
};
var configuration = {
offerToReceiveAudio: true,
offerToReceiveVideo: true
};
const signaling = new WebSocket('ws://127.0.0.1:1337');
signaling.onmessage = function (message){
const data = JSON.parse(message.data);
const message_type = data.message_type;
const content = data.content;
try {
if (message_type === MESSAGE_TYPE.CANDIDATE_REMOTE && content) {
localConnection.addIceCandidate(content)
.catch(function (e) {
console.error(e)
});
} else if (message_type === MESSAGE_TYPE.SDP_LOCAL) {
if (content.type === 'answer') {
localConnection.setRemoteDescription(content);
} else {
console.log('Unsupported SDP type.');
}
}
} catch (err) {
console.error(err);
}
};
document.addEventListener('click', function (event) {
if (event.target.id === 'start') {
startChat();
localVideo = document.getElementById('self-view');
remoteVideo = document.getElementById('remote-view');
}
});
function startConnection(){
localConnection = new RTCPeerConnection({configuration: configuration, iceServers: [{ urls: 'stun:aalimoshaver.com:3478' }]});
localConnection.onicecandidate = function (e) {
!e.candidate
|| signaling.send(JSON.stringify({message_type:MESSAGE_TYPE.CANDIDATE_LOCAL, content: e.candidate.toJSON()}));
};
localConnection.createOffer()
.then(function (offer) {
if(offer){
localConnection.setLocalDescription(offer);
signaling.send(JSON.stringify({message_type:MESSAGE_TYPE.SDP_LOCAL, content: localConnection.localDescription}));
if (navigator.getDisplayMedia) {
navigator.getDisplayMedia({video: true}).then(onCaptureSuccess);
} else if (navigator.mediaDevices.getDisplayMedia) {
navigator.mediaDevices.getDisplayMedia({video: true}).then(onCaptureSuccess);
} else {
navigator.mediaDevices.getUserMedia({video: {mediaSource: 'screen'}}).then(onCaptureSuccess);
}
}
else{
console.error("RTC offer is null");
}
})
.catch(function (e) {
console.error(e)
});
}
function onCaptureSuccess(stream){
localVideo.srcObject = stream;
stream.getTracks().forEach(
function (track) {
localConnection.addTrack(
track,
stream
);
}
);
}
function startChat() {
if (navigator.getDisplayMedia) {
navigator.getDisplayMedia({video: true}).then(onMediaSuccess);
} else if (navigator.mediaDevices.getDisplayMedia) {
navigator.mediaDevices.getDisplayMedia({video: true}).then(onMediaSuccess);
} else {
navigator.mediaDevices.getUserMedia({video: {mediaSource: 'screen'}}).then(onMediaSuccess);
}
}
function onMediaSuccess(stream) {
localVideo.srcObject = stream;
// Set up the ICE candidates for the two peers
localConnection = new RTCPeerConnection({configuration: configuration, iceServers: [{ urls: 'stun:stun.xten.com:19302' }]});
localConnection.onicecandidate = function (e) {
!e.candidate
|| signaling.send(JSON.stringify({message_type:MESSAGE_TYPE.CANDIDATE_LOCAL, content: e.candidate.toJSON()}));
};
stream.getTracks().forEach(
function (track) {
localConnection.addTrack(
track,
stream
);
}
);
localConnection.createOffer()
.then(function (offer) {
if(offer){
localConnection.setLocalDescription(offer);
signaling.send(JSON.stringify({message_type:MESSAGE_TYPE.SDP_LOCAL, content: localConnection.localDescription}));
}
else{
console.error("RTC offer is null");
}
})
.catch(function (e) {
console.error(e)
});
}
})();
任何人都可以解释或找出代码中的漏洞吗?如果您需要更多信息,请告诉我。