首页 > 解决方案 > 在 WebRTC 中添加和接收曲目时遇到问题

问题描述

我正在基于此示例构建 p2p 群组视频聊天:https ://github.com/eugenp/tutorials/tree/master/webrtc

我更改了代码,为每个用户提供了一个 ID,并创建了一个字典,在其中保存了为每个对等点创建的连接(键:id,值:RTCPeerConnection)。

它的工作原理是,当用户进入房间时,他会获得所有当前连接用户的列表,然后为每个连接的用户创建连接并发送优惠。当用户得到答案时,每个用户之间建立连接。我可以使用连接发送和接收短信,但是在尝试 .addTracks() 到各个连接时没有任何反应。使用 onTrack 或 eventlistener("track") 我无法检索流。

当它是 1on1 时,我能够实现视频和音频,但在尝试建立多个连接时,它不再工作了。我认为这与报价有关,因为它们似乎缺少接收音频/视频,我尝试使用 offerToReceiveAudio:1, offerToReceiveVideo:1 但似乎并没有改善这种情况。

var conn = new WebSocket('wss://192.168.5.11:8443/socket');

const messageBox = document.getElementById('messageBox')
const videoGrid = document.getElementById('video-grid')
const myVideo = document.createElement('video')
myVideo.muted = true
var input = document.getElementById("messageInput");

let myID;


const configuration = {
    "iceServers": [{
        "urls": "stun:stun.l.google.com:19302"
    }]
};
connections = {}
dataChannels = {}


conn.onopen = function() {
    console.log("Connected to the signaling server");
};

conn.onmessage = function(msg) {
    console.log("Got message", msg.data);
    var content = JSON.parse(msg.data);
    var data = content.data;
    switch (content.event) {
        //upon a new user joining we will be getting an offer from them
        case "offer":
            if(content.to!=myID) break;
            var from = content.from;
            peerConnecting(content.from);
            handleOffer(data,connections[from],from);
            break;
        //the joined user gets answers and handles them
        case "answer":
            if(content.to!=myID) break;
            handleAnswer(data,connections[content.from]);
            break;
        // when a remote peer sends an ice candidate to us
        case "candidate":
            if(content.to!=myID) break;
            handleCandidate(data,connections[content.from]);
            break;
        //when a user joins he gets list of all users with the event of NEW_CONNECTION, he creates offers which are sent
        // to all the users
        case "NEW_CONNECTION":
            peerConnecting(data);
            createOffer(connections[data],data);
            console.log(data);
            break;
        //upon joining the room we get sent our own id so we can check which messages are meant for us
        case "OWN_ID":
            myID=data;
            break;
        default:
            break;
    }
};

//sends message to the socket handler
function send(message) {
    conn.send(JSON.stringify(message));
}

//creating new RTCPeerConnection for user with the ID
function peerConnecting(ID){
    connections[ID]= new RTCPeerConnection(configuration);

    navigator.mediaDevices.getUserMedia({
        video: true,
        audio: true
    }).
    then(stream => {
        addVideoStream(myVideo, stream)
        stream.getTracks().forEach(track => connections[ID].addTrack(track,stream),console.log("track added"))
    }).catch(function(err) {
        /* handle the error */
    });
    connections[ID].onicecandidate = function(event) {
        if (event.candidate) {
            send({
                event : "candidate",
                data : event.candidate,
                from : myID,
                to : ID
            });
        }
    };

    dataChannels[ID] = connections[ID].createDataChannel("dataChannel",{
        reliable : true
    });

    dataChannels[ID].onerror = function(error) {
        console.log("Error occured on datachannel:", error);
    };

    // when we receive a message from the other peer, printing it on the console
    dataChannels[ID].onmessage = function(event) {
        console.log("message:", event.data);
        messageBox.append("them:"+event.data);
    };

    dataChannels[ID].onclose = function() {
        console.log("data channel is closed");
    };

    connections[ID].ondatachannel = function (event) {
        console.log("data channel is open");
        dataChannels[ID] = event.channel;
    };

    //addind src to remotevideo element
    const remoteStream = new MediaStream();
    const remoteVideo = document.querySelector('#remoteVideo');
    remoteVideo.srcObject = remoteStream;

    connections[ID].addEventListener('track', async (event) => {
        remoteStream.addTrack(event.track);
    });


}


function createOffer(peerConnection,ID) {
    peerConnection.createOffer({
        offerToReceiveAudio:1,
        offerToReceiveVideo:1
    }).then(offer => {
        send({
            event : "offer",
            data : offer,
            from : myID,
            to : ID
        });
        peerConnection.setLocalDescription(offer);
    }, function(error) {
        alert("Error creating an offer");
    });
}

function handleOffer(offer,peerConnection,ID) {
    peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
    // create and send an answer to an offer
    peerConnection.createAnswer({
        offerToReceiveAudio:1,
        offerToReceiveVideo:1
    }).then(answer=> {
        peerConnection.setLocalDescription(answer);
        send({
            event : "answer",
            data : answer,
            from : myID,
            to : ID
        });
    }, function(error) {
        alert("Error creating an answer");
    });

};

function handleCandidate(candidate,peerConnection) {
    peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
};

function handleAnswer(answer, peerConnection) {
    peerConnection.setRemoteDescription(new RTCSessionDescription(answer));
    console.log("connection established successfully!!");
};

function sendMessage() {
    for (const [key, value] of Object.entries(dataChannels)) {
       value.send(input.value)
    }
    messageBox.append("me:"+input.value);
    input.value = "";
}


function addVideoStream(video, stream) {
    video.srcObject = stream
    video.addEventListener('loadedmetadata', () => {
        video.play()
    })
    videoGrid.append(video)
}```

标签: javascriptwebrtcspring-websocket

解决方案


推荐阅读