【问题标题】:WebRTC ontrack on caller side not firing after answer received收到应答后,呼叫方的 WebRTC ontrack 未触发
【发布时间】:2018-08-08 10:13:11
【问题描述】:

在我的多对等 webrtc 客户端(在 chrome 上测试)成功建立了稳定的连接,但是在我收到被调用方的回答后,ontrack 事件没有触发,因此流 sourceObj 没有附加到我的 DOM。为什么?被调用者显示两个视频(本地和远程),但在调用者端未添加远程视频,这似乎是由于 ontrack 事件未触发。

我在发送 Offer/Answer 之前创建了所有 RTCPeerConnection,并在将 ontrack 事件绑定到它之后在创建时将本地 Track 添加到它。然后我发送报价/答案并按照信令流程进行操作。

class WebRTC_Client {

    private serversCfg = {
        iceServers: [{
            urls: ["stun:stun.l.google.com:19302"]
        }]
    };

    ...

    private gotStream(stream) {
        window.localStream = stream;
        ...
    }

    private stopLocalTracks(){
        if (window.localStream) { 
            window.localStream.getTracks().forEach(function (track) {
                track.stop();
            });
            var videoTracks = window.localStream.getVideoTracks();
            for (var i = 0; i !== videoTracks.length; ++i) {
                videoTracks[i].stop();
            }
        }
    }

    private start() {
        var self = this;
        ...
        this.stopLocalTracks();
        ...
        navigator.mediaDevices.getUserMedia(this.getConstrains())
            .then((stream) => {
                self.gotStream(stream);
                trace('Send signal to peers that I am ready to be called: onReadyForTeamspeak');
                self.SignalingChannel.send(JSON.stringify({type: 'onReadyForTeamspeak'}));
            })
            .catch( self.errorHandler );
    }

    public addPeerId(peerId){
        this.availablePeerIds[peerId] = peerId;
        this.preparePeerConnection(peerId);
    }

    private preparePeerConnection(peerId){
        var self = this;

        if( this.peerConns[peerId] ){
            return;
        }

        this.peerConns[peerId] = new RTCPeerConnection(this.serversCfg);
        this.peerConns[peerId].ontrack = function (evt) { self.gotRemoteStream(evt, peerId); };
        this.peerConns[peerId].onicecandidate = function (evt) { self.iceCallback(evt, peerId); };

        this.addTracks(peerId);
    }

    private addTracks(peerId){
        var self = this;

        var localTracksCount = 0;
        window.localStream.getTracks().forEach(
            function (track) {
                self.peerConns[peerId].addTrack(
                    track,
                    window.localStream
                );
            }
        );
    }

    private call() {
        var self = this;

        for( let peerId in this.availablePeerIds ){
            if( !this.availablePeerIds.hasOwnProperty(peerId) ){
                continue;
            }
            if( this.isCaller(peerId) ) {
                this.preparePeerConnection(peerId);
                this.createOffer(peerId);
            }
        }
    }

    private createOffer(peerId){
        var self = this;

        this.peerConns[peerId].createOffer( this.offerOptions )
            .then( function (offer) { return self.peerConns[peerId].setLocalDescription(offer); } )
            .then( function () {
                self.SignalingChannel.send(JSON.stringify({ "sdp": self.peerConns[peerId].localDescription, "remotePeerId": peerId, "type": "onWebRTCPeerConn" }));
            })
            .catch( this.errorHandler );
    }

    private answerCall(peerId){
        var self = this;

        this.peerConns[peerId].createAnswer()
            .then( function (answer) { return self.peerConns[peerId].setLocalDescription(answer); } )
            .then( function () {
                self.SignalingChannel.send(JSON.stringify({ "sdp": self.peerConns[peerId].localDescription, "remotePeerId": peerId, "type": "onWebRTCPeerConn" }));
            })
            .catch( this.errorHandler );
    }

    ...

    private gotRemoteStream(e, peerId) {
        if (!this.videoBillboards[peerId]) {
            this.createMediaElements(peerId);
        }
        if (this.videoAssets[peerId].srcObject !== e.streams[0]) {
            this.videoAssets[peerId].srcObject = e.streams[0];
        }
    }

    private iceCallback(event, peerId) {
        this.SignalingChannel.send(JSON.stringify({ "candidate": event.candidate, "remotePeerId": peerId, "type": "onWebRTCPeerConn" }));
    }

    private handleCandidate(candidate, peerId) {
        this.peerConns[peerId].addIceCandidate(candidate)
            .then(
                this.onAddIceCandidateSuccess,
                this.onAddIceCandidateError
            );
    }

    ...

    private handleSignals(signal){
        var self = this,
            peerId = signal.connectionId;

        this.addPeerId(peerId);

        if( signal.sdp ) {
            var desc = new RTCSessionDescription(signal.sdp);

            this.peerConns[peerId].setRemoteDescription(desc)
                .then(function () {
                    if (desc.type === 'offer') {
                        self.answerCall(peerId);
                    }
                })
                .catch( this.errorHandler );
        } else if( signal.candidate ){
            this.handleCandidate(new RTCIceCandidate(signal.candidate), peerId);
        } else if( signal.closeConn ){
            this.endCall(peerId,true);
        }
    }
}

【问题讨论】:

  • 确保你也添加了一个眩晕/转向服务器......
  • 是的,我做到了。我编辑了上面的示例并添加了我正在使用的冰服务器(默认谷歌服务器)的代码部分。
  • 你只是在使用 stun,你还需要一个 TURN 服务器以防防火墙阻止它。您可以在这里创建一个帐户global.xirsys.net 来测试是否是这个问题
  • @KeyneViana 感谢 TURN 服务器的提示。我尝试添加了一个回合服务器。还是行不通。在我的客户端中,我还添加了能够切换源的代码,它将另一个报价发送给另一个对等点。如果我在被调用方执行此操作,以便调用方从被调用方获得新源的报价,则远程流将显示在调用方。所以连接正常,它只是在收到初始答案并初始化连接时不向调用者发送ontrack 事件。
  • 我可以对整个代码提供更多帮助,包括信号服务器。这样我就可以测试它了

标签: webrtc signaling


【解决方案1】:

找到了解决办法!我输入到this.peerConns[peerId].createOffer( this.offerOptions ) 的选项有问题。

实际上在我提供的代码中看不到它,但是动态创建我的类成员变量this.offerOptions 的方法有一个错误。这显然是在告诉被调用者不要将任何流发送回调用者。

【讨论】:

  • 有点晚了,但是你有没有机会在这里包括offerOptions,它实际上告诉被调用者不要将任何流发送回调用者?或多或少有同样的问题。
  • 如果你来到这里并且这个答案没有解决你的问题,这可能是:stackoverflow.com/questions/61354018/…
  • offerOptions 究竟定义了什么?
  • @ThalisK。那就是 offerToReceiveVideo。如果您不想返回任何流,请将其设置为 false。
猜你喜欢
  • 2023-02-09
  • 2021-02-09
  • 2014-12-18
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
相关资源
最近更新 更多