Only works on one-to-one of which was to be many-to-many, webrtc

孤街醉人 提交于 2019-11-28 08:58:18

问题


I am developing a conference style application (many-to-many) for video calls this style. The code is available on GitHub but I do not have much node.js experience, hence I decided to create my own server using PHP.

I created the server using WebSockets. It is simple - it receives messages and forwards them to all other connected clients (i.e., not the client that sent the message). Just that - nothing more; nothing less.

But my problem is that this architecture does not allow clients to connect with more than one person, i.e., when a client tries to connect with the third person, the additional streams fail. Clients can only connect one-to-one.

I do not know whether the error is in JavaScript or if I need to improve the server. What can I do to make it connect to all clients who join?

See my code:

HTML

<script type="text/javascript" src="http://127.0.0.1/scr/js/jquery.js"></script>

JavaScript

var Server = new WebSocket('ws://127.0.0.1:1805/'),
    myStream = null,
    peerConn = null,
    mediaConstraints = {
        'mandatory': {
            'OfferToReceiveAudio': true,
            'OfferToReceiveVideo': true
        }
    };


navigator.webkitGetUserMedia({
    audio: true,
    video: true
}, function(stream) {
    myStream = stream;

    $("body").append('<video width="320" height="240" muted="muted" autoplay="true" src="' + window.URL.createObjectURL(stream) + '"></video>');

    createPeerConnection();

    peerConn.addStream(myStream);
    peerConn.createOffer(function(sessionDescription) {
        peerConn.setLocalDescription(sessionDescription);
        console.log("Sending offer description");
        Server.send(JSON.stringify(sessionDescription));
    }, null, mediaConstraints);
}, function() {
    console.error('Error in my stream');
});

function createPeerConnection() {
    console.log('Creating peer connection');

    peerConn = new webkitRTCPeerConnection({
        'iceServers': [{
            'url': 'stun:stun.l.google.com:19302'
        }, {
            'url': 'turn:107.150.19.220:3478',
            'credential': 'turnserver',
            'username': 'subrosa'
        }]
    }, {
        'optional': [{
            'DtlsSrtpKeyAgreement': 'true'
        }]
    });

    peerConn.onicecandidate = function(event) {
        if (event.candidate) {
            Server.send(JSON.stringify({
                type: 'candidate',
                label: event.candidate.sdpMLineIndex,
                id: event.candidate.sdpMid,
                candidate: event.candidate.candidate
            }));
        } else {
            console.error('Candidate denied');
        }
    };
    peerConn.onaddstream = function(event) {
        console.log("Adding remote strem");
        $("body").append('<video width="320" height="240" autoplay="true" src="' + window.URL.createObjectURL(event.stream) + '"></video>');
    };
    peerConn.onremovestream = function(event) {
        console.log("Removing remote stream");
    };
}
Server.addEventListener("message", function(message) {
    var msg = JSON.parse(message.data);

    if(!myStream) {
        console.error('Error in my stream');
    }

    if (msg.type === 'offer') {
        createPeerConnection();

        console.log('Adding local stream...');

        peerConn.addStream(myStream);
        peerConn.setRemoteDescription(new RTCSessionDescription(msg));

        console.log("Sending answer to peer.");

        peerConn.createAnswer(function(sessionDescription) {
            peerConn.setLocalDescription(sessionDescription);
            Server.send(JSON.stringify(sessionDescription));
        }, null, mediaConstraints);
    } else if (msg.type === 'answer') {
        peerConn.setRemoteDescription(new RTCSessionDescription(msg));
    } else if (msg.type === 'candidate') {
        var candidate = new RTCIceCandidate({
            sdpMLineIndex: msg.label,
            candidate: msg.candidate
        });
        peerConn.addIceCandidate(candidate);
    }
}, false);

回答1:


The problem is that you're trying to use a single Peer Connection, but that will only work for a single connected party. You'll have to have an additional peer connection for each other party, and be able to associate websocket messages with users and a particular peer connection. You could do this yourself, or use a library like SimpleWebRTC that manages multiple user sessions for you.

Edit:

A very simplified explanation of how SimpleWebRTC works is this, which is one option for creating a mesh network of connected clients (all clients are connected to each other client):

  1. A client joins a "room"
  2. The client is notified about each client who has previously joined the room
  3. For each other client, the client creates a new peer connection and stores it in an array of connected peers
  4. When messages are received over the websocket, they must be associated with an Id, used to map to the proper peer connection

The critical difference in this architecture to yours is that you are creating a single peer connection, but you need to create, store, and track an array of peer connections, and you have to map your websocket messages to particular peers.




回答2:


RTCPeerConnection is inherently a one-to-one connection between two clients (peers), so if you want to go beyond that you have to get clever.

The simplest step up is creating a mesh, essentially setting up one PeerConnection to each of the other participants, with all of the participants doing the same thing. You're going to hit a wall in client upload speed pretty fast this way though, usually topping out at 3-4 participants, typically based on the participant with the lowest upload speed.

For groups bigger than that you'd probably want some special setup like an MCU or Router solution, where essentially a special server acts as a super-participant that everyone connects to, which then either mixes together a video of everyone (usually with whomever is speaking as a larger video), or forwards everyone's video to everyone (since upload speed is usually the bottleneck).



来源:https://stackoverflow.com/questions/31479356/only-works-on-one-to-one-of-which-was-to-be-many-to-many-webrtc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!