...
Для разбора кода возьмем версию файла conference.js с хешем 05436f890771d4, которая находится здесь и доступна для скачивания в соответствующей сборке 2.0.216218.
Скрипт конференции использует RoomApi, предназначенное для видеочатов, конференций, вебинаров и других приложений, которые предполагают нахождение пользователей в одной виртуальной "комнате". Для того, чтобы использовать RoomApi, необходимо подключить скрипт flashphoner-room-api.js
...
Code Block | ||||
---|---|---|---|---|
| ||||
}).on(ROOM_EVENT.JOINED, function(participant){ installParticipant(participant); addMessage(participant.name(), "joined"); ... |
1. Инициализация API.
Flashphoner.init() code
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.init(); |
2. Запрос доступа к камере и микрофону
Flashphoner.getMediaAccess() code
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.init(); |
...
| ||
Flashphoner.getMediaAccess(null, localDisplay).then(function() {
createConnection(url, username);
}).catch(function(error) {
console.error("User not allowed media access: "+error);
$("#failedInfo").text("User not allowed media access. Refresh the page");
onLeft();
}); |
3. Подключение к серверу.
RoomApi.connect() code
Code Block | ||||
---|---|---|---|---|
| ||||
function createConnection(url, username) { connection = RoomApi.connect({urlServer: url, username: username}).on(SESSION_STATUS.FAILED, function(session){ ... }); } |
34. Получение от сервера события, подтверждающего успешное соединение
ConnectionStatusEvent ESTABLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
connection = RoomApi.connect({urlServer: url, username: username}).on(SESSION_STATUS.FAILED, function(session){ ... }).on(SESSION_STATUS.DISCONNECTED, function(session) { ... }).on(SESSION_STATUS.ESTABLISHED, function(session) { setStatus('#status', session.status()); joinRoom(); }); |
45. Присоединение к конференции.
connection.join() code
При присоединении передается имя "комнаты" конференции (берется из параметра в URL страницы клиента, или генерируется случайное имя).
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName(), record: isRecord()}).on(ROOM_EVENT.STATE, function(room){ ... }); |
56. Получение от сервера события, описывающего статус комнаты
RoomStatusEvent STATE code
При получении данного события:
...
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName(), record: isRecord()}).on(ROOM_EVENT.STATE, function(room){ var participants = room.getParticipants(); console.log("Current number of participants in the room: " + participants.length); if (participants.length >= _participants) { console.warn("Current room is full"); $("#failedInfo").text("Current room is full."); room.leave().then(onLeft, onLeft); return false; } setInviteAddress(room.name()); if (participants.length > 0) { var chatState = "participants: "; for (var i = 0; i < participants.length; i++) { installParticipant(participants[i]); chatState += participants[i].name(); if (i != participants.length - 1) { chatState += ","; } } addMessage("chat", chatState); } else { addMessage("chat", " room is empty"); } publishLocalMedia(room); onJoined(room); }).on(ROOM_EVENT.JOINED, function(participant){ ... }).on(ROOM_EVENT.LEFT, function(participant){ ... }).on(ROOM_EVENT.PUBLISHED, function(participant){ ... }).on(ROOM_EVENT.FAILED, function(room, info){ ... }).on(ROOM_EVENT.MESSAGE, function(message){ ... }); |
67. Проверка режима Low Power Mode при публикации на мобильном устройстве
Flashphoner.playFirstVideo() code
Code Block | ||||
---|---|---|---|---|
| ||||
if (Browser.isSafariWebRTC()) { var display = document.getElementById("localDisplay"); Flashphoner.playFirstVideo(display, true, PRELOADER_URL).then(function() { publishLocalMedia(room); }).catch(function (error) { console.log("Can't atomatically publish local stream, use Publish button"); for (var i = 0; i < display.children.length; i++) { if (display.children[i]) { console.log("remove cached instance id " + display.children[i].id); display.removeChild(display.children[i]); } } onMediaStopped(room); }); } |
78. Публикация видеопотока.
room.publish() code
При публикации передаем div-элемент, в котором будет отображаться видео с камеры.
Code Block | ||||
---|---|---|---|---|
| ||||
room.publish({ display: display, constraints: constraints, record: false, receiveVideo: false, receiveAudio: false }).on(STREAM_STATUS.FAILED, function (stream) { console.warn("Local stream failed!"); setStatus("#localStatus", stream.status()); onMediaStopped(room); }).on(STREAM_STATUS.PUBLISHING, function (stream) { setStatus("#localStatus", stream.status()); onMediaPublished(stream); }).on(STREAM_STATUS.UNPUBLISHED, function(stream) { setStatus("#localStatus", stream.status()); onMediaStopped(room); }); |
89. Получение от сервера события, сигнализирующего о присоединении пользователя к чат-комнате
RoomStatusEvent JOINED code
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName(), record: isRecord()}).on(ROOM_EVENT.STATE, function(room){ ... }).on(ROOM_EVENT.JOINED, function(participant){ installParticipant(participant); addMessage(participant.name(), "joined"); }).on(ROOM_EVENT.LEFT, function(participant){ ... }).on(ROOM_EVENT.PUBLISHED, function(participant){ ... }).on(ROOM_EVENT.FAILED, function(room, info){ ... }).on(ROOM_EVENT.MESSAGE, function(message){ ... }); |
910. Получение от сервера события, сигнализирующего о публикации видеопотока другим участником
RoomStatusEvent PUBLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName(), record: isRecord()}).on(ROOM_EVENT.STATE, function(room){ ... }).on(ROOM_EVENT.JOINED, function(participant){ ... }).on(ROOM_EVENT.LEFT, function(participant){ ... }).on(ROOM_EVENT.PUBLISHED, function(participant){ playParticipantsStream(participant); }).on(ROOM_EVENT.FAILED, function(room, info){ ... }).on(ROOM_EVENT.MESSAGE, function(message){ ... }); |
1011. Проверка режима Low Power Mode при воспроизведении на мобильном устройстве
Flashphoner.playFirstVideo() code
Code Block | ||||
---|---|---|---|---|
| ||||
if (Browser.isSafariWebRTC()) { Flashphoner.playFirstVideo(pDisplay, false, PRELOADER_URL).then(function() { playStream(participant, pDisplay); }).catch(function (error) { // Low Power Mode detected, user action is needed to start playback in this mode #WCS-2639 console.log("Can't atomatically play participant" + participant.name() + " stream, use Play button"); for (var i = 0; i < pDisplay.children.length; i++) { if (pDisplay.children[i]) { console.log("remove cached instance id " + pDisplay.children[i].id); pDisplay.removeChild(pDisplay.children[i]); } } onParticipantStopped(participant); }); } |
1112. Воспроизведение видеопотока.
participant.play() code
В метод передаются следующие параметры:
...
Code Block | ||||
---|---|---|---|---|
| ||||
var options = { unmutePlayOnStart: true, constraints: { audio: { deviceId: 'default' } } }; // Leave participant stream muted in Android Edge browser #WCS-3445 if (Browser.isChromiumEdge() && Browser.isAndroid()) { options.unmutePlayOnStart = false; } participant.getStreams()[0].play(display, options).on(STREAM_STATUS.PLAYING, function (playingStream) { var video = document.getElementById(playingStream.id()) video.addEventListener('resize', function (event) { resizeVideo(event.target); }); // Set up participant Stop/Play button if (playBtn) { $(playBtn).text("Stop").off('click').click(function() { $(this).prop('disabled', true); playingStream.stop(); }).prop('disabled', false); } // Set up participant audio toggle button #WCS-3445 if (audioBtn) { $(audioBtn).text("Audio").off('click').click(function() { if (playingStream.isRemoteAudioMuted()) { playingStream.unmuteRemoteAudio(); } else { playingStream.muteRemoteAudio(); } }).prop('disabled', false); } // Start participant audio state checking timer #WCS-3445 participantState.startMutedCheck(playingStream); }).on(STREAM_STATUS.STOPPED, function () { onParticipantStopped(participant); }).on(STREAM_STATUS.FAILED, function () { onParticipantStopped(participant); }); |
1213. Остановка публикации видеопотока.
stream.stop() code
Code Block | ||||
---|---|---|---|---|
| ||||
function onMediaPublished(stream) { $("#localStopBtn").text("Stop").off('click').click(function(){ $(this).prop('disabled', true); stream.stop(); }).prop('disabled', false); ... } |
1314. Получение от сервера события, подтверждающего остановку публикации.
StreamStatusEvent UNPUBLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
room.publish({ display: display, constraints: constraints, record: false, receiveVideo: false, receiveAudio: false }).on(STREAM_STATUS.FAILED, function (stream) { ... }).on(STREAM_STATUS.PUBLISHING, function (stream) { ... }).on(STREAM_STATUS.UNPUBLISHED, function(stream) { setStatus("#localStatus", stream.status()); onMediaStopped(room); }); |
1415. Выход из комнаты конференции.
room.leave() code
Code Block | ||||
---|---|---|---|---|
| ||||
function onJoined(room) { $("#joinBtn").text("Leave").off('click').click(function(){ $(this).prop('disabled', true); room.leave().then(onLeft, onLeft); }).prop('disabled', false); ... } |
1516. Включение/выключение аудио и видео для публикуемого потока.
stream.isAudioMuted(), stream.isVideoMuted(), stream.muteAudio(), stream.unmuteAudio(), stream.muteVideo(), stream.unmuteVideo() code
Code Block | ||||
---|---|---|---|---|
| ||||
function onMediaPublished(stream) { ... $("#localAudioToggle").text("Mute A").off('click').click(function(){ if (stream.isAudioMuted()) { $(this).text("Mute A"); stream.unmuteAudio(); } else { $(this).text("Unmute A"); stream.muteAudio(); } }).prop('disabled', false); $("#localVideoToggle").text("Mute V").off('click').click(function() { if (stream.isVideoMuted()) { $(this).text("Mute V"); stream.unmuteVideo(); } else { $(this).text("Unmute V"); stream.muteVideo(); } }).prop('disabled',false); } |
1617. Отправка текстового сообщения.
participant.sendMessage() code
При нажатии на кнопку Send
...