Versions Compared

Key

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

Table of Contents

1. Local variables 

Declare local variables for constants, SFU SDK, local display and controls

...

Code Block
languagejs
themeRDark
const constants = SFU.constants;
const sfu = SFU;
let localDisplay;
let cControls;

2. Default configuration

Declare default room and publishing configuration which will be used if there was no config.json file available

...

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 }
                    ]
                }
            ]
        }
    }
};

3. Initialization

init() code

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 window.

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');
}

4. Connect to the server and create or enter to the room

connect() code

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

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();
    });
}

5. connect() function details

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

...

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

6. Finalizing remote track

subscribeTrackToEndedEvent() code

...

Code Block
languagejs
themeRDark
const subscribeTrackToEndedEvent = function(room, track, pc) {
    track.addEventListener("ended", function() {
        //track ended, see if we need to cleanup
        let negotiate = false;
        for (const sender of pc.getSenders()) {
            if (sender.track === track) {
                pc.removeTrack(sender);
                //track found, set renegotiation flag
                negotiate = true;
                break;
            }
        }
        if (negotiate) {
            //kickoff renegotiation
            room.updateState();
        }
    });
};

7. Add new local track to peer connection

addTrackToPeerConnection() code

...