代码之家  ›  专栏  ›  技术社区  ›  Mark Perry

WebRTC双向视频无法设置远程应答sdp:调用的状态错误:kStable

  •  0
  • Mark Perry  · 技术社区  · 6 年前

    https://github.com/ScaleDrone/webrtc 错误是:

    setRemoteDescription:InvalidStateError:无法设置远程应答 pc.setRemoteDescription.error@ webrtc.js:1012webrtc.js:26

    funct localDescCreated:OperationError:未能设置本地应答sdp: 调用状态错误:kStable onError@webrtc.js:26 pc.setLocalDescription.error@ webrtc.js:115三webrtc.js:26

    createAnswer:InvalidStateError:PeerConnection无法创建

    还有我的js(对不起,一团糟!):

    // Generate random room name if needed
    if (!location.hash) {
        location.hash = Math.floor(Math.random() * 0xFFFFFF).toString(16);
    }
    const roomHash = location.hash.substring(1);
    
    const roomName = 'test';
    const configuration = {
        iceServers: [
            {
                'urls': [
                    'stun:74.125.142.127:19302',
                    'stun:23.21.150.121:3478'
    
                    ]
            }
        ]
    };
    let room;
    let pc;
    
    
    function onSuccess() { };
    function onError(context, error) {
        console.error(`${context} : ${error}`);
    };
    
    const connection = new signalR.HubConnectionBuilder()
        .withUrl("/video")
        .build();
    
    
    connection.on('Start', () => {
        connection.invoke('JoinRoom', roomName).catch(error => onError("on invoke join room",error));
        connection.invoke('GetMembers', roomName).catch(error => onError("on invoke GetMembers",error));
    });
    connection.on('members',
        users => {
            console.log('MEMBERS', users);
            // If we are the second or greater user to connect to the room we will be creating the offer
            users = JSON.parse(users);
            const isOfferer = users.length === 2 ? true : false;
            console.log("isOfferer", isOfferer);
            console.log("users length = ", users.length);
            startWebRTC(isOfferer);
        });
    
    // Send signaling data via signalr
    function sendMessage(message) {
        connection.invoke('send', message);
    }
    
    function startWebRTC(isOfferer) {
        pc = new RTCPeerConnection(configuration);
    
        // 'onicecandidate' notifies us whenever an ICE agent needs to deliver a
        // message to the other peer through the signaling server
        pc.onicecandidate = event => {
            if (event.candidate) {
                sendMessage(JSON.stringify({ 'candidate': event.candidate }));
                console.log("send message - ", { 'candidate': event.candidate });
            }
        };
    
        // If user is offerer let the 'negotiationneeded' event create the offer
        if (isOfferer) {
            pc.onnegotiationneeded = () => {
                pc.createOffer().then(localDescCreated).catch(error => onError("onnegotiationneeded",error));
            }
        }
    
        // When a remote stream arrives display it in the #remoteVideo element
        pc.ontrack = event => {
            const stream = event.streams[0];
            if (!remoteVideo.srcObject || remoteVideo.srcObject.id !== stream.id) {
                remoteVideo.srcObject = stream;
            }
        };
    
        navigator.mediaDevices.getUserMedia({
            audio: true,
            video: true,
        }).then(stream => {
            // Display your local video in #localVideo element
            localVideo.srcObject = stream;
            // Add your stream to be sent to the conneting peer
            stream.getTracks().forEach(track => pc.addTrack(track, stream));
        }, error => onError("adding media devices", error));
    
        // Listen to signaling data from Scaledrone
        connection.on('newMessage', (message) => {
            message = JSON.parse(message);
            if (message.sdp) {
                // This is called after receiving an offer or answer from another peer
                pc.setRemoteDescription(new RTCSessionDescription(message.sdp), () => {
                    // When receiving an offer lets answer it
                    if (pc.remoteDescription.type === 'offer') {
                        pc.createAnswer().then(localDescCreated).catch(error => onError("createAnswer", error));
                    }
                }, error => onError("setRemoteDescription", error));
            } else if (message.candidate) {
                // Add the new ICE candidate to our connections remote description
                pc.addIceCandidate(
                    new RTCIceCandidate(message.candidate), onSuccess, error => onError("addIceCandidate", error)
                );
            }
        });
    }
    
    function localDescCreated(desc) {
        pc.setLocalDescription(
            desc,
            () => sendMessage(JSON.stringify({ 'sdp': pc.localDescription })),
            error => onError("func localDescCreated", error)
        );
    }
    connection.start().catch(err => console.error(err.toString()));
    
    0 回复  |  直到 6 年前