Cкринкастинг (демонстрация экрана, скриншаринг) уже работает в браузере Google Chrome и позволяет захватывать как окно самого браузера, так и окно любого другого приложения. Например можно захватить Firefox, запущенный в соседнем окне.
Все бы замечательно, но есть проблема с безопасностью. В браузере Chrome скринкастинг выключен.
Для его включения необходимо воспользоваться Chrome Desktop Capture API и мы покажем в этой статье как это сделать.
Расширение для скринкастинга
Чтобы скринкастинг заработал, юзер должен установить ваше расширение (Chrome Extension), которое создано специально для вашего сайта (домена).
Самый первый запуск скринкастинга потребует от пользователя нескольких действий:
Юзер заходит на сайт и нажимает кнопку Начать демонстрацию экрана.
Юзеру предлагается добавить расширение для этого действия.
Добавление расширения происходит в аккуратном блоке, который выводится самим Chrome — браузером и предлагает добавить расширение в 1 клик. В блоке обозначено, что расширение сможет захватывать экран.
Собственное расширение
Следующим шагом будет создание расширения для своего домена. Например ваш тестовый домен — mysupercat.com. В этом случае, при создании расширения, вам нужно будет прописать ваш домен в коде расширения.
Кроме этого, ваш домен (сайт на этом домене) обязательно должен работать по HTTPS. Соответственно ваша страница скринкастинга должна открываться как-то так: mysupercat.com/screen-sharing.php
Домен и HTTPS — это пожалуй все, что потребуется для создания собственного расширения для скринкастинга. При этом покупать SSL-сертификаты не обязательно. Self-signed сертификаты также подойдут. Главное чтобы ваша страница открывалась по HTTPS, пусть даже с красной строчкой:
Хотя, потребуется еще кое-что — пять американских долларов. Ровно столько придется заплатить за членство в клубе разработчиков под Chrome.
Подведем итоги. Чтобы приступить к созданию и тестированию собственного расширения, нам потребуется:
Переходим в Chrome Developer Dashboard и оплачиваем заготовленные 5 баксов.
Готовим ZIP-архив с файлами расширения.
Для этого скачиваем 2 файла здесь.
Меняем файл manifest.json и проставляем свои:
name
author
description
homepage_url
Например
"Name" : "My cool screen sharing extension",
"Author" : "I am",
"Description" : "The extensions shares screens from my website",
"Homepage_url" : "https://mysupercat.com",
6) Добавляем div — элемент remoteVideo, который будет плеером, отображающим то, что пришло с сервера, т.е. будет воспроизводить видеопоток, который был захвачен в localVideo и отправлен на сервер.
7) Кнопка, по которой будем начинать скринкастинг и отображение статуса потока
<button id="publishBtn" type="button" onclick="connectAndShareScreen()">Connect and share screen</button>
<p id="status"></p>
В «дизайне» наша страница выглядит так.
2. Создаем JavaScript код для скринкастинга screen-sharing.js
Весь код доступен для скачивания здесь. Код занимает пару страниц и содержит 5 основных функций.
var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS;
var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS;
var localVideo;
var remoteVideo;
var extensionId = "nlbaajplpmleofphigmgaifhoikjmbkg";
function init_page() {
//init api
try {
Flashphoner.init({screenSharingExtensionId: extensionId});
} catch (e) {
//can't init
return;
}
var interval = setInterval(function () {
chrome.runtime.sendMessage(extensionId, {type: "isInstalled"}, function (response) {
if (response) {
document.getElementById("installExtensionButton").disabled = true;
clearInterval(interval);
localVideo = document.getElementById("localVideo");
remoteVideo = document.getElementById("remoteVideo");
} else {
document.getElementById("installExtensionButton").disabled = false;
}
});
}, 500);
}
function connectAndShareScreen() {
var url = "wss://wcs5-eu.flashphoner.com:8443";
console.log("Create new session with url " + url);
Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) {
//session connected, start streaming
startStreaming(session);
}).on(SESSION_STATUS.DISCONNECTED, function () {
setStatus(SESSION_STATUS.DISCONNECTED);
}).on(SESSION_STATUS.FAILED, function () {
setStatus(SESSION_STATUS.FAILED);
});
}
function startStreaming(session) {
var streamName = "test123";
var constraints = {
video: {
width: 320,
height: 240,
frameRate: 10,
type: "screen"
}
};
session.createStream({
name: streamName,
display: localVideo,
constraints: constraints
}).on(STREAM_STATUS.PUBLISHING, function (publishStream) {
setStatus(STREAM_STATUS.PUBLISHING);
//play preview
session.createStream({
name: streamName,
display: remoteVideo
}).on(STREAM_STATUS.PLAYING, function (previewStream) {
//enable stop button
}).on(STREAM_STATUS.STOPPED, function () {
publishStream.stop();
}).on(STREAM_STATUS.FAILED, function () {
//preview failed, stop publishStream
if (publishStream.status() == STREAM_STATUS.PUBLISHING) {
setStatus(STREAM_STATUS.FAILED);
publishStream.stop();
}
}).play();
}).on(STREAM_STATUS.UNPUBLISHED, function () {
setStatus(STREAM_STATUS.UNPUBLISHED);
//enable start button
}).on(STREAM_STATUS.FAILED, function () {
setStatus(STREAM_STATUS.FAILED);
}).publish();
}
//show connection or local stream status
function setStatus(status) {
var statusField = document.getElementById("status");
statusField.innerHTML = status;
}
//install extension
function installExtension() {
chrome.webstore.install();
}
Разберем этот код детально.
1) В начале объявляется несколько переменных: статусы, элементы localVideo и remoteVideo, и extensionId, содержащий уникальный идентификатор расширения для скринкастинга.
var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS;
var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS;
var localVideo;
var remoteVideo;
var extensionId = "nlbaajplpmleofphigmgaifhoikjmbkg";
2) Далее в Flashphoner API передается extensionId и в результате API знает какое расширение будет использовано для скринкастинга.
3) Периодически обращаемся к Chrome и проверяем, установлено ли расширение. Если расширение установлено, нам больше не требуется кнопка Install extension и ее можно скрыть.
chrome.runtime.sendMessage(extensionId, {type: "isInstalled"}, function (response) {...}
4) Функция connectAndShareScreen устанавливает соединение с сервером и как только соединение установлено (ESTABLISHED), начинает захват и отправку видеопотока, передавая управление функции startStreaming.
function connectAndShareScreen() {
var url = "wss://wcs5-eu.flashphoner.com:8443";
console.log("Create new session with url " + url);
Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) {
//session connected, start streaming
startStreaming(session);
}).on(SESSION_STATUS.DISCONNECTED, function () {
setStatus(SESSION_STATUS.DISCONNECTED);
}).on(SESSION_STATUS.FAILED, function () {
setStatus(SESSION_STATUS.FAILED);
});
}
5) Перед началом скринкастинга устанавливаются такие параметры потока, как разрешение видео и FPS.
Страница и скрипт готовы и можно начинать тестирование.
Подготовка к тестированию
В результате у нас есть следующие файлы:
screen-sharing.html
screen-sharing.js
flashphoner.js
flashphoner.js находится в составе сборки Web SDK. Последнюю сборку можно скачать с этой страницы.
Кроме html и js-файлов, потребуется сервер-ретранслятор, который будет принимать видеопоток и ретранслировать его другим (в данном случае обратно на эту же страницу).
Мы используем для тестирования Web Call Server 5. Поэтому есть несколько вариантов:
С таким же успехом можно раздать скринкастинг-поток на множество подключившихся пользователей
Тестируем скринкастинг в Chrome
Открываем страницу screen-sharing.html по HTTPS в браузере Google Chrome
Нажимаем кнопку Install Now чтобы добавить расширение методом инлайн инсталляции
Нажимаем Add extension и можно сразу стартовать скринкастинг по кнопке Connect and share screen. Chrome попросит выбрать что именно мы будем захватывать. Это может быть вкладка либо окно Chrome или другое приложение.
Нажимаем кнопку Share и приходим к окончательному результату. Экран захватывается, отправляется на сервер по WebRTC и проходит обратно, отображаясь в блоке Preview.
Подведем итоги
Таким образом мы успешно протестировали скринкастинг с простой тестовой страницей screen-sharing.html в браузере Google Chrome. Тестовая страница содержит расширение для скринкастинга, которое мы опубликовали в Chrome Store и которое устанавливается в один клик без перехода на Store.
При тестировании страница работала по HTTPS и отправляла / получала видео через Web Call Server — WebRTC медиасервер для трансляций потокового видео.
Для интеграции скринкастинга в HTML-страницу использовался скрипт flashphoner.js, который является частью сборки Web SDK для сервера WCS.