Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagejs
themeRDark
const defaultConfig = {
    room: {
        url: "wss://127.0.0.1:8888",
        name: "ROOM1",
        pin: "1234",
        nickName: "Alice"
    },
    media: {
        audio: {
            tracks: [
                {
                    source: "mic",
                    channels: 1
                }
            ]
        },
        video: {
            tracks: [
                {
                    source: "camera",
                    width: 1280,
                    height: 720,
                    codec: "H264",
                    encodings: [
                        { rid: "h", active: true, maxBitrate: 900000 },
                        { rid: "m", active: true, maxBitrate: 300000, scaleResolutionDownBy: 2 }
                    ]
                }
            ]
        }
    }
};

Init function that is called when page is finished loading. The function will load config.json or default config, create local display and open entrance modal.

Code Block
languagejs
themeRDark
/**
 * load config and show entrance modal
 */
const init = function() {
    //read config
    $.getJSON("config.json", function(config){
        cControls = createControls(config);
    }).fail(function(){
        //use default config
        cControls = createControls(defaultConfig);
    });
    //create local display to show local streams
    localDisplay = initLocalDisplay(document.getElementById("localDisplay"));
    //open entrance modal
    $('#entranceModal').modal('show');
}

Connect function that is called once user clicks connect in entrance modal.

Code Block
languagejs
themeRDark
/**
 * connect to server
 */
function connect() {
    //hide modal
    $('#entranceModal').modal('hide');
    //disable controls
    cControls.muteInput();
    //create peer connection
    const pc = new RTCPeerConnection();
    //get config object for room creation
    const roomConfig = cControls.roomConfig();
    roomConfig.pc = pc;
    //kick off connect to server and local room creation
    const session = sfu.createRoom(roomConfig);
    session.on(constants.SFU_EVENT.CONNECTED, function(room) {
        //connected to server
        const chatDiv = document.getElementById('messages');
        const chatInput = document.getElementById('localMessage');
        const chatButton = document.getElementById('sendMessage');
        //create and bind chat to the new room
        createChat(room, chatDiv, chatInput, chatButton);

        room.on(constants.SFU_ROOM_EVENT.FAILED, function(e) {
            const errField = document.getElementById("errorMsg");
            errField.style.color = "red";
            errField.innerText = e;
        }).on(constants.SFU_ROOM_EVENT.OPERATION_FAILED, function (e) {
            const errField = document.getElementById("errorMsg");
            errField.style.color = "red";
            errField.innerText = e.operation + " failed: " + e.error;
        })
        //setup remote display for showing remote audio/video tracks
        const remoteDisplay = document.getElementById("display");
        initRemoteDisplay(room, remoteDisplay, pc);

        //get configured local video streams
        let streams = cControls.getVideoStreams();
        //combine local video streams with audio streams
        streams.push.apply(streams, cControls.getAudioStreams());
        //add our local streams to the room (to PeerConnection)
        streams.forEach(function (s) {
            //add local stream to local display
            localDisplay.add(s.stream.id, "local", s.stream);
            //add each track to PeerConnection
            s.stream.getTracks().forEach((track) => {
                addTrackToPeerConnection(pc, s.stream, track, s.encodings);
                subscribeTrackToEndedEvent(room, track, pc);
            });
        });
        //add callback for the new local stream to the local controls
        cControls.onTrack(function (s) {
            //add local stream to local display
            localDisplay.add(s.stream.id, "local", s.stream);
            //add each track to PeerConnection
            s.stream.getTracks().forEach((track) => {
                addTrackToPeerConnection(pc, s.stream, track, s.encodings);
                subscribeTrackToEndedEvent(room, track, pc);
            });
            //kickoff renegotiation
            room.updateState();
        });
        //join room
        room.join();
    });
}

Lets dive deeper into connect function and see what it does.

Hide modal as we don't need it anymore and mute controls before connect is established

Code Block
languagejs
themeRDark
//hide modal
$('#entranceModal').modal('hide');
//disable controls
cControls.muteInput();

Create PeerConnection and prepare the room config for the creation of session and room

Code Block
languagejs
themeRDark
//create peer connection
const pc = new RTCPeerConnection();
//get config object for room creation
const roomConfig = cControls.roomConfig();
roomConfig.pc = pc;

Create session (which will automatically connect to the server).

Code Block
languagejs
themeRDark
const session = sfu.createRoom(roomConfig);

Subscribe to session's "CONNECTED" event

Code Block
languagejs
themeRDark
session.on(constants.SFU_EVENT.CONNECTED, function(room) {

Once we are connected initialize room chat

Code Block
languagejs
themeRDark
//connected to server
const chatDiv = document.getElementById('messages');
const chatInput = document.getElementById('localMessage');
const chatButton = document.getElementById('sendMessage');
//create and bind chat to the new room
createChat(room, chatDiv, chatInput, chatButton);

Subscribe to room error events

Code Block
languagejs
themeRDark
room.on(constants.SFU_ROOM_EVENT.FAILED, function(e) {
    const errField = document.getElementById("errorMsg");
    errField.style.color = "red";
    errField.innerText = e;
}).on(constants.SFU_ROOM_EVENT.OPERATION_FAILED, function (e) {
    const errField = document.getElementById("errorMsg");
    errField.style.color = "red";
    errField.innerText = e.operation + " failed: " + e.error;
})

Initialize remote display

Code Block
languagejs
themeRDark
//setup remote display for showing remote audio/video tracks
const remoteDisplay = document.getElementById("display");
initRemoteDisplay(room, remoteDisplay, pc);

Get preconfigured local media from controls

Code Block
languagejs
themeRDark
//get configured local video streams
let streams = cControls.getVideoStreams();
//combine local video streams with audio streams
streams.push.apply(streams, cControls.getAudioStreams());

Add each stream to local display (so we can see it on page) and peer connection

Code Block
languagejs
themeRDark
//add our local streams to the room (to PeerConnection)
streams.forEach(function (s) {
    //add local stream to local display
    localDisplay.add(s.stream.id, "local", s.stream);
    //add each track to PeerConnection
    s.stream.getTracks().forEach((track) => {
        addTrackToPeerConnection(pc, s.stream, track, s.encodings);
        subscribeTrackToEndedEvent(room, track, pc);
    });
});

Add listener to controls so we know if user adds new local streams. Once we have a new stream we will need to add it to local display, add it to peer connection and kickoff renegotiation.

Code Block
languagejs
themeRDark
//add callback for the new local stream to the local controls
cControls.onTrack(function (s) {
    //add local stream to local display
    localDisplay.add(s.stream.id, "local", s.stream);
    //add each track to PeerConnection
    s.stream.getTracks().forEach((track) => {
        addTrackToPeerConnection(pc, s.stream, track, s.encodings);
        subscribeTrackToEndedEvent(room, track, pc);
    });
    //kickoff renegotiation
    room.updateState();
});

Finally join the room

Code Block
languagejs
themeRDark
//join room
room.join();
Code Block
languagejs
themeRDark
Code Block
languagejs
themeRDark
Code Block
languagejs
themeRDark
Code Block
languagejs
themeRDark
Code Block
languagejs
themeRDark
Code Block
languagejs
themeRDark