Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Reverted from v. 2

...

Объявление конфигурации комнаты и публикации потоков по умолчанию, на случай, если нет файла конфигурации config.json

code

Клиент настраивается на соединение с сервером по WSS по адресу localhost для входа в комнату "ROOM1" с пин-кодом "1234" под именем "Alice". Секция media задает публикацию аудио и видео дорожек. Видео публикуется двумя дорожками с качествами high (h) и medium (m)

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: "mh", active: true, maxBitrate: 300000, scaleResolutionDownBy:900000 2},
                        { rid: "hm", active: true, maxBitrate: 900000 300000, scaleResolutionDownBy: 2 }
                    ]
                       }
            ]
        }
    }
};

Отметим, что, начиная со сборки 2.0.248, качества должны быть перечислены по возрастанию

3. Инициализация

init() code

Функция init() вызывается после того, как страница загрузится. Функция загружает config.json или конфигурацию по умолчанию, создает элемент для отображения локального видео и открывает модальное окно входа

Code Block
languagejs
themeRDark
/**
 * Loadload track configurationconfig 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() code

Функция вызывается по щелчку пользователя по кнопке Enter  в модальном окне входа

Code Block
languagejs
themeRDark
/**
 * Connectconnect to server and publish preconfigured streams
 */
async 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();
    //kick off connect roomConfig.pc = pc;
    //kick off connect to server and local room creation
    try {
        const session = await sfu.createRoom(roomConfig);
    session.on(constants.SFU_EVENT.CONNECTED, function(room) {
     // Now we //connected to the server
 (if no exception was thrown)
   const chatDiv =   sessiondocument.on(constants.SFU_EVENT.FAILED, function (e) {getElementById('messages');
        const chatInput   if (e.status && e.statusText) {
= document.getElementById('localMessage');
        const chatButton = document.getElementById('sendMessage');
        displayError("CONNECTION FAILED: " + e.status + " " + e.statusText);//create and bind chat to the new room
        createChat(room, chatDiv,   } else if (e.type && e.info) {chatInput, chatButton);

           room.on(constants.SFU_ROOM_EVENT.FAILED, function(e) {
           displayError("CONNECTION FAILED: " + e.info const errField = document.getElementById("errorMsg");
            } else {
errField.style.color = "red";
            errField.innerText = e;
    displayError("CONNECTION FAILED: " + e);
            }
        }).on(constants.SFU_ROOM_EVENT.DISCONNECTEDOPERATION_FAILED, function (e) {
            displayError("DISCONNECTED. Refresh the page to enter the room againconst errField = document.getElementById("errorMsg");
        });
    errField.style.color = "red";
  const room = session.room();
        room.on(constants.SFU_ROOM_EVENT.FAILED, function (e) {
    errField.innerText = e.operation + " failed: " + e.error;
        displayError(e});
        }).on(constants.SFU_ROOM_EVENT.OPERATION_FAILED, function (e) {
   //setup remote display for showing remote audio/video tracks
        const displayError(e.operation + " failed: " + e.errorremoteDisplay = document.getElementById("display");
        })initRemoteDisplay(room, remoteDisplay, pc);

        //get createconfigured local display to show local video streams
        let localDisplaystreams = initLocalDisplay(documentcControls.getElementByIdgetVideoStreams("localDisplay"));
        //combine displaylocal audiovideo andstreams videowith controlaudio tablesstreams
        awaitstreams.push.apply(streams, cControls.displayTablesgetAudioStreams());
        cControls.onTrack(async function (s) {
     //add our local streams to the room (to PeerConnection)
       await publishNewTrack(room, pc, s);
 streams.forEach(function (s) {
       });
        //createadd andlocal bind chatstream to thelocal newdisplay
 room
        const chatDiv = documentlocalDisplay.getElementById('messages'add(s.stream.id, "local", s.stream);
          const chatInput = document.getElementById('localMessage');  //add each track to PeerConnection
        const  chatButton = document.getElementById('sendMessage');
 s.stream.getTracks().forEach((track) => {
          createChat(room, chatDiv, chatInput, chatButton);

      addTrackToPeerConnection(pc, s.stream, track, s.encodings);
           //setup remote display for showing remote audio/video tracks
subscribeTrackToEndedEvent(room, track, pc);
         const remoteDisplay = document.getElementById("display" });
        initDefaultRemoteDisplay(room, remoteDisplay, {quality: true},{thresholds: [
});
        //add callback for the new local stream to the local controls
  {parameter: "nackCount", maxLeap: 10},
   cControls.onTrack(function (s) {
           {parameter: "freezeCount", maxLeap: 10},
    //add local stream to local display
             {parameter: "packetsLost", maxLeap: 10}
localDisplay.add(s.stream.id, "local", s.stream);
            //add each ],track abrKeepOnGoodQuality: ABR_KEEP_ON_QUALITY, abrTryForUpperQuality: ABR_TRY_UPPER_QUALITY, interval: ABR_QUALITY_CHECK_PERIOD});

        //get configured local video streams
to PeerConnection
            s.stream.getTracks().forEach((track) => {
                let streams = cControls.getVideoStreams(addTrackToPeerConnection(pc, s.stream, track, s.encodings);
        //combine local video streams with audio streams
        streams.push.apply(streams, cControls.getAudioStreams()subscribeTrackToEndedEvent(room, track, pc);

         // Publish preconfigured streams});
        publishPreconfiguredStreams(room, pc, streams);
  //kickoff renegotiation
 } catch (e) {
        consoleroom.errorupdateState(e);
        displayError(e});
        //join room
        room.join();
    });
}

5. Подробнее о функции connect()

Скрытие модального окна входа и отключение полей ввода до установки соединения с сервером

code

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

Создание объекта PeerConnection и подготовка объекта конфигурации комнаты

code

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

Создание сессии и установка соединения с сервером

code

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

Подписка на события событие сессии "CONNECTED"

code

Code Block
languagejs
themeRDark
        session.on(constants.SFU_EVENT.FAILEDCONNECTED, function (eroom) {
            if (e.status && e.statusText) {

Инициализация чата после установки соединения

code

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

Подписка на сообщения об ошибках комнаты

code

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

Инициализация объекта для отображения потоков от других участников

code

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

Получение настроек публикации локального медиа

code

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

Добавление каждого потока в объект localDisplay для отображения и в объект PeerConnection для публикации

code

Code Block
languagejs
themeRDark
        //add our local streams to the    room displayError("CONNECTION FAILED: " + e.status + " " + e.statusText);
         to PeerConnection)
   } else if (e.type && e.infostreams.forEach(function (s) {
            //add local stream to displayError("CONNECTION FAILED: " + e.info);local display
            } else {
    localDisplay.add(s.stream.id, "local", s.stream);
            displayError("CONNECTION FAILED: " + e);//add each track to PeerConnection
            }
  s.stream.getTracks().forEach((track) => {
      }).on(constants.SFU_EVENT.DISCONNECTED, function (e) {
       if     displayError("DISCONNECTED. Refresh the page to enter the room again");
(s.source === "screen") {
               });

Создание объекта комнаты и подписка на его события

code

Code Block
languagejs
themeRDark
     config[track.id] = s.source;
 const room = session.room();
          room.on(constants.SFU_ROOM_EVENT.FAILED, function (e) {}
                displayError(eaddTrackToPeerConnection(pc, s.stream, track, s.encodings);
         }).on(constants.SFU_ROOM_EVENT.OPERATION_FAILED, function (e) {
    subscribeTrackToEndedEvent(room, track, pc);
      displayError(e.operation + " failed: " + e.error});
        })

...

;

Добавление слушателя, чтобы определить, когда клиент добавляет новые потоки для публикации. Получив новый поток, необходимо добавить его в localDisplay для отображения, добавить в PeerConnection для публикации и обновить состояние комнаты

code

Code Block
languagejs
themeRDark
        localDisplay = initLocalDisplay(document.getElementById("localDisplay"));
        //add displaycallback audiofor andthe videonew controllocal tables
stream to the      await cControls.displayTables();local controls
        cControls.onTrack(async function (s) {
            await publishNewTrack(room, pc, s);
let config = {};
         });

Создание чата

code

Code Block
languagejs
themeRDark
   //add local stream to local constdisplay
 chatDiv = document.getElementById('messages');
        const chatInput = document.getElementById('localMessage' localDisplay.add(s.stream.id, "local", s.stream);
         const chatButton = document.getElementById('sendMessage');
   //add each track to PeerConnection
         createChat(room, chatDiv, chatInput, chatButton);

Инициализация объекта для отображения потоков от других участников

code

Code Block
languagejs
themeRDark
   s.stream.getTracks().forEach((track) => {
      const remoteDisplay = document.getElementById("display");
       if initDefaultRemoteDisplay(room, remoteDisplay, {quality: true},{thresholds: [s.source === "screen") {
                {parameter: "nackCount", maxLeap: 10},
    config[track.id] = s.source;
             {parameter: "freezeCount", maxLeap: 10},
                {parameter: "packetsLost", maxLeap: 10}addTrackToPeerConnection(pc, s.stream, track, s.encodings);
            ], abrKeepOnGoodQuality: ABR_KEEP_ON_QUALITY, abrTryForUpperQuality: ABR_TRY_UPPER_QUALITY, interval: ABR_QUALITY_CHECK_PERIOD});

Получение настроек публикации локального медиа и публикация треков согласно настройкам

code

Code Block
languagejs
themeRDark
 subscribeTrackToEndedEvent(room, track, pc);
         let streams = cControls.getVideoStreams(});
            //combine local video streams with audio streams
kickoff renegotiation
           streams.push.apply(streams, cControls.getAudioStreams());

 room.updateState(config);
        });

Настройка WebRTC соединения в комнате

code

Code Block
languagejs
themeRDark
//join Publish preconfigured streams
        publishPreconfiguredStreams(room, pc, streams);room
room.join(pc, null, config); 

6. Завершение публикации потока

...