Описание
Пример демонстрирует публикацию потока с веб-камеры и с экрана на одной странице с возможностью микширования этих двух потоков, случай презентации.
Параметры публикации экрана:
- FPS - частота кадров в секунду
- Width - ширина картинки
- Height - высота картинки
Параметры микширования:
- Add to mixer - добавлять ли потоки автоматически в микшер
- Mixer - имя микшера
Параметры соединения:
- Websocket URL WCS сервера
Код примера
Код данного примера находится на WCS-сервере по следующему пути:
/usr/local/FlashphonerWebCallServer/client2/examples/demo/streaming/screen-camera-mixer
screen-camera-mixer.css - файл стилей
screen-camera-mixer.html - HTML страница примера
screen-camera-mixer.js - скрипт, обеспечивающий работу примера
Тестировать данный пример можно по следующему адресу:
https://host:8888/client2/examples/demo/streaming/screen-camera-mixer/screen-camera-mixer.html
Здесь host - адрес WCS-сервера.
Работа с кодом примера
Для разбора кода возьмем версию файла screen-camera-mixer.js с хешем 32144d9, которая находится здесь и доступна для скачивания в соответствующей сборке 2.0.243.
1. Инициализация API.
Flashphoner.init() code
Flashphoner.init();
2. Подключение к серверу
Flashphoner.createSession() code
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. Получение от сервера события, подтверждающего успешное соединение
STREAM_STATUS.ESTABLISHED code
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. Публикация видеопотока с экрана
Session.createStream(), Stream.publish() code
Методу createStream() передаются следующие параметры:
- streamName - имя публикуемого потока
- constraints.video.width - ширина картинки
- constraints.video.height - высота картинки
- constraints.video.frameRate - FPS публикации
- constraints.video.type: "screen" - тип потока: публикация экрана
- constraints.video.withoutExtension: true - публикация экрана из браузера без использования расширения
- constraints.video.mediaSource: "screen" - только для публикации из Firefox
- localVideoScreen - элемент для локального отображения потока
- disableConstraintsNormalization = true - отключение нормализации параметров (только для MacOS Safari)
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. Получение от сервера события, подтверждающего успешную публикацию экрана
STREAM_STATUS.PUBLISHING code
По этому событию начинается публикация потока с камеры
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. Публикация видеопотока с камеры
Session.createStream(), Stream.publish() code
Методу createStream() передаются следующие параметры:
- streamName - имя публикуемого потока
- localVideoCamera - элемент для локального отображения потока
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. Получение от сервера события, подтверждающего успешную публикацию камеры
STREAM_STATUS.PUBLISHING code
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. Остановка публикации камеры
Stream.stop() code
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. Остановка публикации экрана
Stream.stop() code
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(); }