简体   繁体   English

WebRTC 多对等连接视频不工作

[英]WebRTC Multiple Peer connection video is not working

So I found a way to make a peer connection multiple times by a lot..but I can't make the video work although there is no error shown...所以我找到了一种多次建立对等连接的方法......但是我无法制作视频,尽管没有显示错误......

UPDATE: DEMO but this demo is not allow working localStream so try it in your own browser index.html更新: 演示,但此演示不允许使用 localStream,因此请在您自己的浏览器 index.html 中尝试

First let say we have this html file首先假设我们有这个 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>

First I will takes the initial inputs for starter in script.js首先,我将在 script.js 中为 starter 获取初始输入

        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,
        };

And then let say first we will start our call server..which will be created.然后让我们先说我们将启动我们的呼叫服务器..这将被创建。 So now we will make a start click then our code所以现在我们将点击开始然后我们的代码


...
        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)

Now this is for join button in the server...let say I have let count = 0 and I will createElement each video I click the button So our code for the join button click is现在这是服务器中的加入按钮...假设我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 pc1Remote\n${desc.sdp}`);
                pcLocals[count-1].setRemoteDescription(desc);
            }

            function gotDescriptionLocal(desc) {
                pcLocals[count-1].setLocalDescription(desc);
                // console.log(`Answer from pc1Remote\n${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)

        })

I'm somehow doubt my if my video was not to pass yet before the RTCPeerConnection operations happening..I don't know if where my errors here... I just tried to make a multiple peerconnection that was documentary here at WEBRTC TUTORIAL我有点怀疑我的视频是否在 RTCPeerConnection 操作发生之前还没有通过..我不知道我的错误在哪里...我只是试图建立一个多重对等连接,这是WEBRTC TUTORIAL的纪录片

I've look at you codesand box example and found two issues:我查看了您的代码和框示例,发现了两个问题:

  1. The playback of your created video is never started从未开始播放您创建的视频
  2. Your icecandidates are set on the wrong peerconnection您的 icecandidates 设置在错误的 peerconnection 上

To adress the first problem, you need to start your playback either with autoplay or by starting it with addVideo.play() .要解决第一个问题,您需要使用自动播放或使用addVideo.play()开始播放。 For the autoplay solution, you can simply add:对于自动播放解决方案,您只需添加:

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

To address the second problem, you need to change the passed peerconnections in the onicecandidate event handlers:要解决第二个问题,您需要更改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]);
  };

The ice candidates need to be exchanged, meaning, ice candidates gathered by local must be passed to the remote and vice versa.候选冰需要交换,也就是说,本地收集的冰候选必须传递给远程,反之亦然。 Before, you added the ice candidates from local to your local connection, thats why it didn't work.之前,您将来自本地的候选冰添加到您的本地连接,这就是它不起作用的原因。 This why the connectionState was "connecting", and never changed to "connected", as the connection was never fully connected and was still expecting ice candidate exchange.这就是为什么 connectionState 是“正在连接”,并且从未更改为“已连接”的原因,因为连接从未完全连接,并且仍在等待 ice 候选交换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM