WebRTC多对等连接视频不工作



所以我找到了一种方法来多次建立对等连接。。但我无法使视频工作,尽管没有显示错误。。。

更新:演示,但这个演示不允许使用localStream,所以请在自己的浏览器index.html 中尝试

首先假设我们有这个html文件

// This one is for multiple videos
<div class="item-videos">
//This first video is a start video
<video id="video1" playsinline autoplay muted></video>
//This is join videos
</div>
<div>
<button id="start"> Start </button>
<button id="join"> Join </button>
<button id="hangup"> Hang Up </button>
</div>

首先,我将在script.js 中获取启动器的初始输入

let containers = document.querySelector('.item-videos');
const startButton = document.querySelector('#start')
const joinButton = document.querySelector("#join")
const video1 = document.querySelector('video#video1');
let localStream;
// This is the RTCPeerConnections arrays.
let pcLocals = [];
let pcRemotes = [];
const offerOptions = {
offerToReceiveAudio: 1,
offerToReceiveVideo: 1
};
const servers = {
iceServers: [
{
urls: ['stun:stun1.l.google.com:19302', 'stun:stun2.l.google.com:19302'],
},
],
iceCandidatePoolSize: 10,
};

然后假设我们将首先启动呼叫服务器。。其将被创建。所以现在我们将开始点击,然后我们的代码


...
function gotStream(stream) {
console.log('Received local stream');
video1.srcObject = stream;
localStream = stream;
joinButton.disabled = false;
}
function start() {
console.log('Requesting local stream');
startButton.disabled = true;
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true
})
.then(gotStream)
.catch(e => console.log('getUserMedia() error: ', e));
}
startButton.addEventListener("click",start)

现在这是服务器中的加入按钮。。。假设我有let count = 0我会createElement每个视频我点击按钮所以我们点击加入按钮的代码是

let count = 0;
joinButton.addEventListener("click",() => {
count += 1
//Creating Video Element
const addVideo = document.createElement('video')

addVideo.setAttribute('id',`video${count + 1}`)
addVideo.setAttribute('class',`try-${count + 1}`)
// Here I believe this part was my error where in the video is set up yet for the RTCPeerConnection functions. 
containers.appendChild(addVideo)
const videoCall = containers.querySelectorAll('video')[count]

// Here I will create RTCPeerConnections and push it in the pcLocals and pcRemotes;
const init_localStreams = new RTCPeerConnection(servers);
const init_remoteStreams = new RTCPeerConnection(servers);

pcLocals.push(init_localStreams)
pcRemotes.push(init_remoteStreams)
console.log(pcLocals)    
console.log(pcRemotes)  

//Here I'm passing the stream videos in RTCPeer Arrays...
pcRemotes[count - 1].ontrack = (ev) => {
function gotRemoteStream(e,video,idx) {
if (video.srcObject !== e.streams[0]) {
video.srcObject = e.streams[0]
console.log(`pc${idx+1}: received remote stream`);
}
}
gotRemoteStream(ev,videoCall,count - 1)
}
//Here I'm passing the tracks of the video in each locals
localStream.getTracks().forEach((track) => 
{
pcLocals[count - 1].addTrack(track, localStream)
});
function onAddIceCandidateSuccess() {
console.log('AddIceCandidate success.');
}
function onAddIceCandidateError(error) {
console.log(`Failed to add ICE candidate: ${error.toString()}`);
}
function handleCandidate(candidate, dest, prefix, type) {
dest.addIceCandidate(candidate)
.then(onAddIceCandidateSuccess, onAddIceCandidateError);
console.log(`${prefix}New ${type} ICE candidate: ${candidate ? candidate.candidate : '(null)'}`);
}
function iceCallbackRemote(e,local_) {
handleCandidate(e.candidate,local_,`pc${count}: `, 'remote')
}
function iceCallbackLocal(e,remote_) {
handleCandidate(e.candidate,remote_,`pc${count}: `, 'local')
}
pcLocals[count - 1].onicecandidate = (ev) => {
iceCallbackRemote(ev,pcLocals[count - 1])
}
pcRemotes[count - 1].onicecandidate = (ev) => {
iceCallbackLocal(ev,pcRemotes[count - 1])
}

function gotDescriptionRemote(desc) {
pcRemotes[count-1].setLocalDescription(desc);
// console.log(`Answer from pc1Remoten${desc.sdp}`);
pcLocals[count-1].setRemoteDescription(desc);
}
function gotDescriptionLocal(desc) {
pcLocals[count-1].setLocalDescription(desc);
// console.log(`Answer from pc1Remoten${desc.sdp}`);
pcRemotes[count-1].setRemoteDescription(desc);

pcRemotes[count-1].createAnswer().then(gotDescriptionRemote,onCreateSessionDescriptionError)
}
function onCreateSessionDescriptionError(error) {
console.log(`Failed to create session description: ${error.toString()}`);
}
pcLocals[count - 1].
createOffer(offerOptions)
.then(gotDescriptionLocal, onCreateSessionDescriptionError)
})

不知何故,我怀疑我的视频是否在RTCPeerConnection操作发生之前还没有通过。。我不知道我的错误在哪里。。。我只是想在WEBRTC TUTORIAL 做一个多同行的联系

我查看了您的codesandbox代码,发现了两个问题:

  1. 从未开始播放您创建的视频
  2. 您的icecandidate设置在错误的对等连接上

要解决第一个问题,您需要使用自动播放或addVideo.play()启动播放。对于自动播放解决方案,您可以简单地添加:

addVideo.setAttribute("autoplay", true);
addVideo.setAttribute("playsinline", true);

为了解决第二个问题,您需要更改onicecandidate事件处理程序中传递的对等连接:

pcLocals[count - 1].onicecandidate = (ev) => {
//old: iceCallbackRemote(ev, pcLocals[count - 1]);
//new:
iceCallbackRemote(ev, pcRemotes[count - 1]);
};
pcRemotes[count - 1].onicecandidate = (ev) => {
//old: iceCallbackRemote(ev, pcRemotes[count - 1]);
//new:
iceCallbackLocal(ev, pcLocals[count - 1]);
};

ice候选人需要交换,这意味着本地收集的ice候选人必须传递到远程,反之亦然。之前,您将本地的ice候选者添加到您的本地连接,这就是为什么它不起作用。这就是为什么connectionState是";连接";,并且从未改变为";"连接";,因为该连接从未完全连接并且仍然期望ice候选交换。

最新更新