Скриншаринг на сайте по WebRTC из браузера Mozilla Firefox
Недавно мы писали статью о том, как сделать расширение скриншаринга для браузера Google Chrome. В результате мы создали собственное расширение для скриншаринга, опубликовали его в Chrome Store и протестировали трансляцию экрана через Web Call Server в режиме один-ко-многим.
В этой статье мы проделаем тоже самое с браузером Firefox. Подход остается прежним и снова потребуется упаковка и публикация расширения, на этот раз в Mozilla Add-ons. В результате мы сможем делать скринкасты видеопотоков из FF без установки внешнего дополнительного ПО.
Подготовка кода расширения для FF
На текущий момент есть два способа подготовить расширение для Firefox
- WebExtension
- JPM XPI
Первый способ позволяет подготовить расширение для браузеров Firefox, начиная с 45 версии. Второй заключается в сборке xpi — файла и подходит для браузеров Firefox, начиная с 38 версии.
Mozilla грозится объявить способ создания на JPM устаревшим. Тем не менее мы опишем этот способ, т.к. мы имели возможность его протестировать и он работает. Вы можете также обратиться к документации WebExtension чтобы собрать ваше расширение более новым способом. Скорее всего процесс упаковки и публикации будет очень похож на тот, что описан в этой статье.
Создаем аккаунт (если нет) на сайте Firefox Accounts и переходим в Mozilla Add-ons
Скачиваем исходный код расширения, который представляет собой несколько файлов конфигов и иконок.
Исходный код расширения FF
Далее открываем конфиг package.json и редактируем его для использования с собственным доменом.
Исходный конфиг выглядит так:
{
"title": "Flashphoner Screen Sharing",
"name": "flashphoner-screen-sharing-extension",
"id": "@flashphoner-screen-sharing-extension",
"version": "0.0.4",
"description": "Enable screen sharing for flashphoner.com",
"main": "index.js",
"author": "Flashphoner",
"engines": {
"firefox": ">=38.0a1",
"fennec": ">=38.0a1"
},
"homepage": "http://flashphoner.com",
"license": "MIT"
}
Вам нужно вписать сюда собственные данные, например так:
{
"title": "My Screen Sharing Extension",
"name": "my-screen-sharing",
"id": "@my-screen-sharing",
"version": "0.0.1",
"description": "Enable screen sharing for mymegacat.com",
"main": "index.js",
"author": "Me",
"engines": {
"firefox": ">=38.0a1",
"fennec": ">=38.0a1"
},
"homepage": "https://mymegacat.com",
"license": "MIT"
}
Обратите внимание, что в качестве примера мы вписали сайт mymegacat.com — это предполагаемый домен вашего сайта, со страниц которого будут идти трансляции экрана (скринкасты).
Упаковка расширения для скриншаринга
Далее нужно упаковать код расширения в .xpi — файл. В этом нам поможет JPM. Упаковку будем делать на Windows.
- Скачиваем и устанавливаем Node.js + npm с сайта https://nodejs.org. Установка Node.js может потребовать перезагрузки системы.
- Убеждаемся что NPM был установлен корректно.
npm -v
- Устанавливаем JPM
npm install jpm –global
- Проверяем что JPM установлен
jpm
- Создаем XPI-файл с помощью JPM. Для этого переходим в ранее скачанную папку firefox-extension и выполняем команду
jpm xpi
Готово.
В результате мы получили XPI-файл расширения, готовый для публикации в Mozilla Add-ons.
Публикация расширения в Mozilla Add-ons
- Начинаем с того, что логинимся в Mozilla Add-ons и переходим в меню Tools / Submit a New Add-on
- Загружаем наш XPI-файл.
- После загрузки ваше расширение пройдет валидацию и можно нажимать Continue.
- Управлять вашими расширениями вы можете из меню Tools / Manage My Submissions
Более подробно о распространении и подписи ваших расширений можно почитать здесь.
Делаем HTML-страницу для скринкастинга из Firefox
Скринкастинг в Firefox работает по технологии WebRTC, также как и в Google Chrome. В качестве WebRTC — платформы, транслирующей видеопотоки, захваченные с экрана, мы будем использовать Web Call Server 5 и скрипт flashphoner.js, который представляет API для работы с сервером и входит в сборку Web SDK.
Код скринкастинга будет содержать:
- screen-sharing-ff.html
- screen-sharing-ff.js
- flashphoner.js
- flashphoner_screen_sharing-0.0.9-an+fx.xpi
Вам нужно использовать ваш XPI файл расширения, который был ранее создан с помощью JPM.
Код HTML страницы достаточно простой из 20 строк:
Screen Sharing
Screen Sharing
Capture
Preview
Страница использует два скрипта: screen-sharing-ff.js и flashphoner.js
На загрузку страницы вызывается функция инициализации init_page ()
Кнопка installExtensionButton служит для быстрой установки расширения.
Div — блок localVideo используется для отображения видео, захваченного с экрана локально.
Div — блок remoteVideo используется для отображения видео трансляции, которое пришло с сервера. Например, если мы хотим оставить только плеер на отдельной странице, мы можем использовать только один Div — блок remoteVideo. В данном же примере мы располагаем плеер и стример на одной странице для ускорения тестирования.
И наконец, кнопка publishBtn начинает трансляцию.
Ниже показано как выглядит HTML-страница скринкастинга в действии в браузере Mozilla Firefox 51.0.1
Теперь обратимся к скрипту screen-sharing-ff.js и поймем что происходит там
var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS;
var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS;
var localVideo;
var remoteVideo;
function init_page() {
//init api
try {
Flashphoner.init();
} catch (e) {
//can't init
return;
}
var interval = setInterval(function() {
if (Flashphoner.firefoxScreenSharingExtensionInstalled) {
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() {
var params = {
"Flashphoner Screen Sharing": { URL: "../../dependencies/screen-sharing/firefox-extension/flashphoner_screen_sharing-0.0.9-an+fx.xpi",
IconURL: "../../dependencies/screen-sharing/firefox-extension/icon.png",
Hash: "sha1:96699c6536de455cdc5c7705f5b24fae28931605",
toString: function () { return this.URL; }
}
};
InstallTrigger.install(params);
}
Работа этого скрипта подробно описана в предыдущей статье про скринкастинг из браузера Google Chrome.
В связи с этим, сфокусируемся на отличиях, специфичных именно для Firefox, а их всего три:
- При инициализации мы ничего не передаем, в то время как для Chrome передавали ID расширения. Для FF он будет передан в другом месте.
Flashphoner.init();
- Проверка установленного расширения тоже осуществляется немного иначе чем в Chrome. Проверяется флаг Flashphoner.firefoxScreenSharingExtensionInstalled.
var interval = setInterval(function() if (Flashphoner.firefoxScreenSharingExtensionInstalled) { document.getElementById("installExtensionButton").disabled = true; clearInterval(interval); localVideo = document.getElementById("localVideo"); remoteVideo = document.getElementById("remoteVideo"); }else{ document.getElementById("installExtensionButton").disabled = false; } }, 500);
- Код установки расширения по кнопке installExtensionButton отличается от кода установки расширения в Chrome и использует файл расширения XPI напрямую, в то время как в Chrome мы ставили ссылку на Chrome Store. Обратите внимание, что в качестве названия вместо Flashphoner Screen Sharing должно быть указано название вашего расширения, указанное ранее в package.json на этапе упаковки расширения.
function installExtension() { var params = { "Flashphoner Screen Sharing": { URL: "../../dependencies/screen-sharing/firefox-extension/flashphoner_screen_sharing-0.0.9-an+fx.xpi", IconURL: "../../dependencies/screen-sharing/firefox-extension/icon.png", Hash: "sha1:96699c6536de455cdc5c7705f5b24fae28931605", toString: function () { return this.URL; } } }; InstallTrigger.install(params); }
В результате, с учетом этих трех различий, мы получили рабочий скрипт screen-sharing-ff.js, который готов к установке расширения и скринкастингу в Firefox.
Подготовка к тестированию WebRTC скриншаринга в FF
Для того чтобы начать тестирование, вам потребуется залить все скрипты на ваш веб-хостинг:
- screen-sharing-ff.html
- screen-sharing-ff.js
- flashphoner.js
- flashphoner_screen_sharing-0.0.9-an+fx.xpi
В самих скриптах должен использоваться ваш XPI-файл
Везде — на хостинге и в скриптах должен использоваться ваш домен (помните, мы указывали mymegacat.com при упаковке расширения).
Сервер Web Call Server 5, который мы используем в качестве WebRTC-платформы для трансляции экрана, принимает соединения по протоколу Websockets и может быть установлен как на отдельном VPS / VDS, так и на одном сервере с вебсайтом.
Для коннекта к серверу вам потребуется Websocket-адрес в следующем виде:
wss://wcs5-eu.flashphoner.com:8443
В скрипте screen-sharing-ff.js этот адрес захардкожен. Это демо-сервер.
Вы можете установить свой сервер или запустить готовый образ на Amazon EC2.
Тестируем скринкастинг из FF и раздаем поток через сервер
- Открываем страницу screen-sharing-ff.html в браузере Firefox и нажимаем кнопку Install Now, которая активна пока не установлено расширение.
- Далее подтверждаем установку расширения и получаем сообщение об успешной установке. После этого кнопка Install Now уходит в disabled, т.к. наш скрипт screen-sharing-ff.js видит, что расширение уже установлено и в кнопке больше нет необходимости.
- Нажимаем кнопку Connect and share screen чтобы начать тестирование.
Firefox спросит нас какое именно окно мы намерены скринкастить, после чего отправит видеопоток на Web Call Server и отобразит захваченный поток в блоке localVideo HTML-страницы.
Под кнопкой отобразится статус PUBLISHING — видео захватывается с экрана и видеотрафик идет на сервер.
Через пару секунд видео, полученное с сервера начнет воспроизводиться в плеере — блоке remoteVideo. Это видео, которое прошло через сервер и вернулось на воспроизведение. Похожим образом можно проигрывать Live-видео на других страницах, тем самым получая one-to-many трансляцию или скринкастинг.
Ссылки
Скриншаринг на сайте из браузера Google Chrome по WebRTC
Разработка и упаковка WebExtension для Firefox
Упаковка расширения для Firefox с помощью JPM
Firefox Accounts — получить аккаунт
Mozilla Add-ons — опубликовать свое расширение
Исходный код расширения для упаковки в JPM
Node.js — быстрая установка NPM и JPM
Информация о распространении и подписи расширений на сайте Mozilla
Web Call Server 5 — платформа для ретрансляции видеопотоков по WebRTC
Web SDK — набор скриптов API, содержащий flashphoner.js для работы с сервером
Установка WCS5 на свой сервер
Статья про запуск образа Web Call Server в облаке Amazon EC2
Скачать исходный код тестовой страницы screen-sharing-ff.html и screen-sharing-ff.js