Table of Contents |
---|
Пример видеочата с отображением экрана
Данный пример может использоваться для видеочата между двумя участниками на Web Call Server с отображением экрана одного из участников.
Участник видеочата может публиковать следующие типы потоков
...
WebRTC поток с веб-камеры и одновременно с этим WebRTC поток с экрана или из окна приложения
Пример окна клиента, публикующего свой экран в браузере Chrome:
...
Пример окна клиента, получающего поток с экрана в браузере Chrome
Настройка расширения для публикации экрана браузера Chrome описана в примере Screen Sharing.
Код примера
Код данного примера находится на WCS-сервере по следующему пути:
...
Здесь host - адрес WCS-сервера.
Работа с кодом примера
Для разбора кода возьмем версию файла video-chat-and-screen-sharing.js с хешем c306c1bbf49bfcbd8e24be927ae95f63b7dbaaba 90771d4, которая находится здесь и доступна для скачивания в соответствующей сборке 2.0.5.28.2747218.
1. Инициализация API.
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.init(try { Flashphoner.init(); flashMediaProviderSwfLocation: '../../../../media-provider.swf',} catch(e) { $("#notifyFlash").text("Your browser doesn't support screenSharingExtensionId:WebRTC extensionId technology needed for this example"); }); return; } |
2. Подключение к серверу.Запрос доступа к камере и микрофону
Flashphoner.roomApi.connectgetMediaAccess() код code
Code Block | ||||
---|---|---|---|---|
| ||||
connection = Flashphoner.roomApi.connect({urlServer: url, username: username}).on(SESSION_STATUS.FAILED, function(session)getMediaAccess(null, localDisplay).then(function() { setStatuscreateConnection('#status'url, session.status(username)); onLeft(); }).on(SESSION_STATUS.DISCONNECTED, catch(function(sessionerror) { setStatus('#status', session.status()console.error("User not allowed media access: "+error); onLeft$(); }).on(SESSION_STATUS.ESTABLISHED, function(session) { setStatus('#status', session.status()"#failedInfo").text("User not allowed media access. Refresh the page"); joinRoomonLeft(); }); |
3. Получение от сервера события, подтверждающего успешное соединениеConnectionStatusEvent ESTABLISHED код. Подключение к серверу.
RoomApi.connect() code
Code Block | ||||
---|---|---|---|---|
| ||||
function createConnection(url, username) { connection = Flashphoner.roomApiRoomApi.connect({urlServer: url, username: username}).on(SESSION_STATUS.FAILED, function(session){ ... }).on(SESSION_STATUS.DISCONNECTED, function(session) { ... ; } |
4. Получение от сервера события, подтверждающего успешное соединение
ConnectionStatusEvent ESTABLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
connection = RoomApi.connect({urlServer: url, username: username}).on(SESSION_STATUS.ESTABLISHEDFAILED, function(session) { ... setStatus('#status', session.status());}).on(SESSION_STATUS.DISCONNECTED, function(session) { joinRoom();... }); |
...
.on(SESSION_STATUS.ESTABLISHED, function(session) {
setStatus('#status', session.status());
joinRoom();
}); |
5. Присоединение к комнате.
При присоединении передается имя "комнаты" конференции (берется из параметра в URL страницы клиента, или генерируется случайное имя).
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName()}).on(ROOM_EVENT.STATE, function(room){ ... }); |
56. Получение от сервера события, описывающего статус комнаты
RoomStatusEvent STATE код code
При получении данного события:
...
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName()}).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; } room_ = room; 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. Публикация видеопотока с экрана.
При публикации передаются параметры:
...
Code Block | ||||
---|---|---|---|---|
| ||||
var constraints = { video: { width: parseInt($('#width').val()), height: parseInt($('#height').val()), frameRate: parseInt($('#fps').val()), withoutExtension: true }, audio: $("#useMic").prop('checked') }; constraints.video.type = "screen"; if (Browser.isFirefox()){ constraints.video.mediaSource = "screen"; } var options = room.publish({ displayname: document.getElementById("previewscreenShare"), constraintsdisplay: constraintsdocument.getElementById("preview"), nameconstraints: "screenShare"constraints, cacheLocalResources: false } ... if (isSafariMacOS()) { options.disableConstraintsNormalization = true; } room.publish(options).on(STREAM_STATUS.FAILED, function (stream) { ... }); |
78. Получение от сервера события, сигнализирующего о присоединении пользователя к чат-комнате
RoomStatusEvent JOINED код code
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName()}).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){ ... }); |
89. Получение от сервера события, сигнализирующего о публикации видеопотока другим участником
RoomStatusEvent PUBLISHED код code
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName()}).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){ ... }); |
910. Воспроизведение видеопотока от другого участника
Параметром передается div-элемент, в котором будет отображаться видео, в зависимости от источника - веб-камера или экран
Code Block | ||||
---|---|---|---|---|
| ||||
function playParticipantsStream(participant) { if (participant.getStreams().length > 0) { for (var i=0; i<participant.getStreams().length; i++) { $("[id$=Name]").each(function (index, value) { if ($(value).text() == participant.name()) { var p = value.id.replace('Name', ''); var pDisplay = p + 'Display'; // check if we already play this stream if (document.getElementById(participant.getStreams()[i].id()) == null) { // setup 1st stream to main div if (participant.getStreams()[i].streamName().indexOf("screenShare") == -1) { participant.getStreams()[i].play(document.getElementById(pDisplay)).on(STREAM_STATUS.PLAYING, function (playingStream) { document.getElementById(playingStream.id()).addEventListener('resize', function (event) { resizeVideo(event.target); }); }); } else { participant.getStreams()[i].play(document.getElementById("sharedDisplay")).on(STREAM_STATUS.PLAYING, function (playingStream) { document.getElementById(playingStream.id()).addEventListener('resize', function (event) { resizeVideo(event.target); }); }); } }); } } }); } } } |
11. Остановка публикации видеопотока с экрана
stream.stop() code
Code Block | ||||
---|---|---|---|---|
| ||||
room.publish(options).on(STREAM_STATUS.FAILED, function (stream) { ... } ).on(STREAM_STATUS.PUBLISHING, function (stream) { });/* } * User } } |
10. Остановка публикации видеопотока.
stream.stop() код
Code Block | ||||
---|---|---|---|---|
| ||||
function onMediaPublished(stream) { $("#localStopBtn").text("Stop").off('click').click(function(){ $(this).prop('disabled', true);can stop sharing screen capture using Chrome "stop" button. * Catch onended video track event and stop publishing. stream.stop(); */ }).prop('disabled', false); document.getElementById(stream.. } |
11. Получение от сервера события, подтверждающего остановку публикации.
StreamStatusEvent UNPUBLISHED код
Code Block | ||||
---|---|---|---|---|
| ||||
room.publish(id()).srcObject.getVideoTracks()[0].onended = function (e) { display: document.getElementById("preview"), constraints: constraints, stream.stop(); }; ... }).on(STREAM_STATUS.UNPUBLISHED, function(stream) { name: "screenShare",... }); |
12. Получение от сервера события, подтверждающего остановку публикации.
StreamStatusEvent UNPUBLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
cacheLocalResources: false }room.publish(options).on(STREAM_STATUS.FAILED, function (stream) { ... }).on(STREAM_STATUS.PUBLISHING, function (stream) { ... }).on(STREAM_STATUS.UNPUBLISHED, function(stream) { onStopSharing(); }); |
1213. Выход из комнаты чата.
Code Block | ||||
---|---|---|---|---|
| ||||
function onJoined(room) { $("#joinBtn").text("Leave").off('click').click(function(){ $(this).prop('disabled', true); room.leave().then(onLeft, onLeft); }).prop('disabled', false); ... } |