Table of Contents |
---|
Описание
Пример демонстрирует сценарий презентации: публикация потоков с веб-камеры и с экрана на одной странице с возможностью микширования этих двух потоков на сервере.
Параметры публикации экрана:
- FPS - частота кадров в секунду
- Width - ширина картинки
- Height - высота картинки
...
Overview
The example shows a presentation case: webcamera and screen sharing streams publishing from a single page with optional streams mixing at server side.
Screen sharing parameters:
- FPS - framerate per second
- Width - picture width
- Height - picture height
Server stream mixing parameters:
- Add to mixer - добавлять ли потоки автоматически в микшерadd streams automatically to mixer
- Mixer - имя микшера
...
- mixer name
Connection parameters:
- Websocket URL of WCS сервераsever
Код примера
...
The code of the example
The code of the example is on WCS server by the following path:
/usr/local/FlashphonerWebCallServer/client2/examples/demo/streaming/screen-camera-mixer
screen-camera-mixer.css - файл стилей styles file
screen-camera-mixer.html - example HTML страница примераpage
screen-camera-mixer.js - скрипт, обеспечивающий работу примераТестировать данный пример можно по следующему адресу main example script
The example may be tested by the following address:
https://host:8888/client2/examples/demo/streaming/screen-camera-mixer/screen-camera-mixer.html
Здесь where host - адрес WCS-сервера.
Работа с кодом примера
Для разбора кода возьмем версию файла is WCS server address.
Analyzing the code
To analyze the code let's take a screen-camera-mixer.js с хешем version with hash 32144d9, которая находится здесь и доступна для скачивания в соответствующей сборке which is available here and may be downloaded in build 2.0.243.
1. Инициализация API initialization.
Flashphoner.init() code
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.init(); |
2. Подключение к серверу Connecting to the server
Flashphoner.createSession() code
Code Block | ||||
---|---|---|---|---|
| ||||
const connect = function() { ... let url = field("url"); ... console.log("Create new session with url " + url); Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function(session){ ... }).on(SESSION_STATUS.DISCONNECTED, function(){ ... }).on(SESSION_STATUS.FAILED, function(){ ... }); } |
3. Получение от сервера события, подтверждающего успешное соединение Receiving the event confirming successful connection
STREAM_STATUS.ESTABLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
const connect = function() { ... let url = field("url"); ... console.log("Create new session with url " + url); Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function(session){ //session connected, start streaming setStatus("screen", SESSION_STATUS.ESTABLISHED); setStatus("camera", SESSION_STATUS.ESTABLISHED); onConnected(session); }).on(SESSION_STATUS.DISCONNECTED, function(){ ... }).on(SESSION_STATUS.FAILED, function(){ ... }); } |
4. Публикация видеопотока с экранаScreen sharing stream publishing
Session.createStream(), Stream.publish() code
Методу The following parameters are passed to createStream() передаются следующие параметрыmethod:
- streamName - имя публикуемого потокаstream name
- constraints.video.width - ширина картинкиpicture width
- constraints.video.height - высота картинкиpicture height
- constraints.video.frameRate - FPS публикацииpublishing framerate
- constraints.video.type: "screen" - тип потока: публикация экранаstream type: screen sharing
- constraints.video.withoutExtension: true - публикация экрана из браузера без использования расширенияscreen sharing from browser without a special extension
- constraints.video.mediaSource: "screen" - только для публикации из Firefoxfor screen sharing from Firefox browser only
- localVideoScreen - элемент для локального отображения потокаdiv tag to display a local video
- disableConstraintsNormalization = true - отключение нормализации параметров (только для disable constraints normalization (for MacOS Safari only)
Code Block | ||||
---|---|---|---|---|
| ||||
const startStreamingScreen = function(session) { let streamName = getStreamName("screen", field("url")); let constraints = { video: { width: parseInt($('#width').val()), height: parseInt($('#height').val()), frameRate: parseInt($('#fps').val()), type: "screen", withoutExtension: true } }; if (Browser.isFirefox()) { constraints.video.mediaSource = "screen"; } let options = { name: streamName, display: localVideoScreen, constraints: constraints } if (isSafariMacOS()) { options.disableConstraintsNormalization = true; } session.createStream(options).on(STREAM_STATUS.PUBLISHING, function(screenStream) { ... }).on(STREAM_STATUS.UNPUBLISHED, function() { ... }).on(STREAM_STATUS.FAILED, function(stream) { ... }).publish(); } |
5. Получение от сервера события, подтверждающего успешную публикацию экрана Receiving the event confirming successful screen publishing
STREAM_STATUS.PUBLISHING codeПо этому событию начинается публикация потока с камеры
Web camera stream publishing starts on this event
Code Block | ||||
---|---|---|---|---|
| ||||
const startStreamingScreen = function(session) { ... session.createStream(options).on(STREAM_STATUS.PUBLISHING, function(screenStream) { /* * User can stop sharing screen capture using Chrome "stop" button. * Catch onended video track event and stop publishing. */ document.getElementById(screenStream.id()).srcObject.getVideoTracks()[0].onended = function (e) { screenStream.stop(); }; document.getElementById(screenStream.id()).addEventListener('resize', function(event){ resizeVideo(event.target); }); setStatus("screen", STREAM_STATUS.PUBLISHING, screenStream); startStreamingCamera(session, screenStream); }).on(STREAM_STATUS.UNPUBLISHED, function() { ... }).on(STREAM_STATUS.FAILED, function(stream) { ... }).publish(); } |
6. Публикация видеопотока с камерыWeb camera stream publishing
Session.createStream(), Stream.publish() code
Методу The following parameters are passed to createStream() передаются следующие параметрыmethod:
- streamName - имя публикуемого потокаstream name
- localVideoCamera - элемент для локального отображения потокаdiv tag to display a local video
Code Block | ||||
---|---|---|---|---|
| ||||
const startStreamingCamera = function(session, screenStream) { let streamName = getStreamName("camera", field("url")); let options = { name: streamName, display: localVideoCamera } session.createStream(options).on(STREAM_STATUS.PUBLISHING, function(cameraStream) { ... }).on(STREAM_STATUS.UNPUBLISHED, function() { ... }).on(STREAM_STATUS.FAILED, function(stream) { ... }).publish(); } |
7. Получение от сервера события, подтверждающего успешную публикацию камеры Receiving the event confirming successful camera publishing
STREAM_STATUS.PUBLISHING code
Code Block | ||||
---|---|---|---|---|
| ||||
const startStreamingCamera = function(session, screenStream) { ... session.createStream(options).on(STREAM_STATUS.PUBLISHING, function(cameraStream) { document.getElementById(cameraStream.id()).addEventListener('resize', function(event){ resizeVideo(event.target); }); setStatus("camera", STREAM_STATUS.PUBLISHING, cameraStream); onStarted(cameraStream); }).on(STREAM_STATUS.UNPUBLISHED, function() { ... }).on(STREAM_STATUS.FAILED, function(stream) { ... }).publish(); } |
8. Остановка публикации камерыStop camera publishing
Stream.stop() code
Code Block | ||||
---|---|---|---|---|
| ||||
const setPublishButton = function(action, session, cameraStream) { $("#publishBtn").text(action).off('click').click(function(){ if (action == "Start") { ... } else if (action === "Stop") { $(this).prop('disabled', true); cameraStream.stop(); } }).prop('disabled', false); } |
9. Остановка публикации экранаStop screen publishing
Stream.stop() code
Code Block | ||||
---|---|---|---|---|
| ||||
const startStreamingCamera = function(session, screenStream) { ... session.createStream(options).on(STREAM_STATUS.PUBLISHING, function(cameraStream) { ... }).on(STREAM_STATUS.UNPUBLISHED, function() { setStatus("camera", STREAM_STATUS.UNPUBLISHED); screenStream.stop(); }).on(STREAM_STATUS.FAILED, function(stream) { ... }).publish(); } |