多点视频

问题描述 投票:0回答:1

这个问题以前也问过几次,但我一直无法使任何解决方案发挥作用。我正在创建一个多对等的视频聊天。然而,每当一个对等体试图连接时,我都会收到这个错误。

DOMException: Failed to execute 'setRemoteDescription' on 'RTCPeerConnection': Failed to set remote answer sdp: 调用错误的状态:kStable

奇怪的是,如果用户重新加载页面,我就不会出现这个错误,视频也会显示。两个客户端都需要进行重新加载。我猜浏览器已经缓存了 东西 并在第二次尝试时重新使用。

// When a remote user joins, an object of this class is created.
// Its job is to create am RTCPeerConnection between the local user
// and the remote user.
class VideoChat
{
    constructor(name, remoteView)
    {
        this.remoteName = name;   // ID of remote peer used by signal server
        this.remoteView = remoteView;  // html video object to display remote video

        var configuration = {"iceServers": [
            {urls: "stun:stun.l.google.com:19302"}
            {urls: "turn:numb.viagenie.ca", username: "xxx", credential: "xxx"}
        ]};

        this.pc = new RTCPeerConnection(configuration);

        // 'onicecandidate' notifies us whenever an ICE agent needs to deliver a
        // message to the other peer through the signaling server
        this.pc.onicecandidate = event => {
            if (event.candidate) {
                ChatRoom.relay("signal", this.remoteName, event.candidate);
                console.log(`onicecadidate (${this.remoteName}): ${event.candidate}`);
            }
        };

        // let the 'negotiationneeded' event create the offer
        this.pc.onnegotiationneeded = async () => {
            try {
                await this.pc.setLocalDescription();
                ChatRoom.relay("signal", this.remoteName, {desc: this.pc.localDescription})
            } catch (err) {
                console.error(err);
            }
        }

        // When a remote stream arrives display it in the #remoteView element
        this.pc.ontrack = (track, streams) => {
            log("adding remote TRACK to video element");
            // don't set srcObject again if it is already set.
            if (this.remoteView.srcObject) return;
            this.remoteView.srcObject = event.streams[0];
        };
    }

    // This is called by main program when a remote user has signed on
    // This initiates everything....
    // localVideo is html video element connected to local camera
    // stream is the main (local) user's mediaStream
    async start(localVideo, stream) {
        try {
            for (const track of stream.getTracks()) {
                this.pc.addTrack(track, stream);
            }
            localVideo.srcObject = stream;
        } catch (err) {
            console.error(err);
        }
    }

    // A message from the signal server
    async onmessage(message) {
        try {
            if (message.desc) {
                await this.pc.setRemoteDescription(message.desc);
                if (message.desc.type == "offer") {
                    await this.pc.setLocalDescription();
                    ChatRoom.relay("signal", this.remoteName, {desc: this.pc.localDescription});
                }
            }
            else if (message.candidate) {
                await this.pc.addIceCandidate(message);
            }
        } catch (err) {
            console.error(err);
        }
    }
}

注意这个功能。ChatRoom.relay("signal", this.remoteName, something) 向信号服务器发送一个消息,只转发到远程的id为: this.remoteName.

另外,我使用的是我自己用Java创建的信号服务器。

javascript websocket webrtc
1个回答
1
投票

如果你在同一个peerconnection上设置不同对等体的远程描述,那是行不通的。正如 "peerconnection "这个名字所暗示的那样,它是针对一个对等体的。

调用 this.pc.setLocalDescription() 在不创建报价的情况下,一些浏览器可能会支持,但要小心。而且你从来没有创建一个答案,只是标志着本地描述。你也没有对答案做任何事情。

https:/webrtc.github.iosamplessrccontentpeerconnectionmultiple 是如何做好事情的典范。

© www.soinside.com 2019 - 2024. All rights reserved.