Cкринкастинг на сайте по WebRTC из браузера Chrome

в 9:11, , рубрики: chrome, Chrome Store, Google Chrome, javascript, screencast, screencasting, screensharing, WebRTC, демонстрация экрана, Программирование, Разработка веб-сайтов, расширение, Расширения для браузеров, скринкаст, скринкастинг, скриншаринг, стриминг, трансляция экрана, метки: , ,
Cкринкастинг на сайте по WebRTC из браузера Chrome - 1

Cкринкастинг в Chrome

Cкринкастинг (демонстрация экрана, скриншаринг) уже работает в браузере Google Chrome и позволяет захватывать как окно самого браузера, так и окно любого другого приложения. Например можно захватить Firefox, запущенный в соседнем окне.

Все бы замечательно, но есть проблема с безопасностью. В браузере Chrome скринкастинг выключен.

Для его включения необходимо воспользоваться Chrome Desktop Capture API и мы покажем в этой статье как это сделать.

Расширение для скринкастинга

Чтобы скринкастинг заработал, юзер должен установить ваше расширение (Chrome Extension), которое создано специально для вашего сайта (домена).

Самый первый запуск скринкастинга потребует от пользователя нескольких действий:

  1. Юзер заходит на сайт и нажимает кнопку Начать демонстрацию экрана.
    Cкринкастинг на сайте по WebRTC из браузера Chrome - 2
  2. Юзеру предлагается добавить расширение для этого действия.
    Cкринкастинг на сайте по WebRTC из браузера Chrome - 3

Добавление расширения происходит в аккуратном блоке, который выводится самим Chrome — браузером и предлагает добавить расширение в 1 клик. В блоке обозначено, что расширение сможет захватывать экран.

Собственное расширение

Следующим шагом будет создание расширения для своего домена. Например ваш тестовый домен — mysupercat.com. В этом случае, при создании расширения, вам нужно будет прописать ваш домен в коде расширения.

Кроме этого, ваш домен (сайт на этом домене) обязательно должен работать по HTTPS. Соответственно ваша страница скринкастинга должна открываться как-то так: mysupercat.com/screen-sharing.php

Домен и HTTPS — это пожалуй все, что потребуется для создания собственного расширения для скринкастинга. При этом покупать SSL-сертификаты не обязательно. Self-signed сертификаты также подойдут. Главное чтобы ваша страница открывалась по HTTPS, пусть даже с красной строчкой:

Cкринкастинг на сайте по WebRTC из браузера Chrome - 4

Хотя, потребуется еще кое-что — пять американских долларов. Ровно столько придется заплатить за членство в клубе разработчиков под Chrome.

Подведем итоги. Чтобы приступить к созданию и тестированию собственного расширения, нам потребуется:

  • доменное имя
  • хостинг с HTTPS
  • 5 долларов на карте

Cкринкастинг на сайте по WebRTC из браузера Chrome - 5

Публикация расширения

  1. Переходим в Chrome Developer Dashboard и оплачиваем заготовленные 5 баксов.
    Cкринкастинг на сайте по WebRTC из браузера Chrome - 6

  2. Готовим 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",

    {
      "name" : "Flashphoner Screen Sharing",
      "author": "Flashphoner",
      "version" : "1.4",
      "manifest_version" : 2,
      "minimum_chrome_version": "34",
      "description" : "This Chrome extension is developed for http://flashphoner.com WCS Api to enable screen capture.",
      "homepage_url": "http://flashphoner.com",
      "background": {
        "scripts": ["background-script.js"],
        "persistent": false
      },
      "externally_connectable": {
        "matches": [
          "https://flashphoner.com/*",
          "https://*.flashphoner.com/*",
          "*://localhost/*",
          "*://127.0.0.1/*"
        ]
      },
      "icons": {
        "16": "logo16.png",
        "48": "logo48.png",
        "128": "logo128.png"
      },
      "permissions": [
        "desktopCapture"
      ],
      "web_accessible_resources": [
        "logo48.png"
      ]
    }

    Кроме этого меняем иконки и подставляем свой домен в коде externally_connectable

    "externally_connectable": {
        "matches": [
          "https://mysupercat.com/*",
          "https://*.mysupercat.com/*",
          "*://localhost/*",
          "*://127.0.0.1/*"
        ]
      }

    В итоге получается такой manifest.json:

    {
      "name" : "My cool screen sharing extension",
      "author": "I am",
      "version" : "1.0",
      "manifest_version" : 2,
      "minimum_chrome_version": "34",
      "description" : "The extensions shares screens from my website",
      "homepage_url": "https://mysupercat.com",
      "background": {
        "scripts": ["background-script.js"],
        "persistent": false
      },
      "externally_connectable": {
        "matches": [
          "https://mysupercat.com/*",
          "https://*.mysupercat.com/*",
          "*://localhost/*",
          "*://127.0.0.1/*"
        ]
      },
      "icons": {
        "16": "logo16.png",
        "48": "logo48.png",
        "128": "logo128.png"
      },
      "permissions": [
        "desktopCapture"
      ],
      "web_accessible_resources": [
        "logo48.png"
      ]
    }
    

    Упаковываем эти файлы в ZIP-архив со всеми иконками и другими картинками. Про иконки можно прочесть здесь. А про дополнительные картинки здесь.

    Далее жмем Add new item.

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 7

    Далее, после ознакомления с соглашением, заливаем наш ZIP-архив

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 8

    После загрузки архива, нужно еще раз все внимательно проверить и сохранить

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 9

    Осталось опубликовать расширение из Dashboard, нажав кнопку Publish.

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 10

    Опубликованное расширение в Dashboard выглядит так:

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 11

    Готово. Расширение упаковано, опубликовано и доступно для установки в браузер.

    Инлайн инсталляция

    Без инлайн инсталляции вашим пользователям пришлось бы переходить на сайт Chrome Store и устанавливать расширения там. Это конечно не смертельно, но:

    • Для пользователя это не очень удобно.
    • Пользователь может запутаться на странице установки расширения и не вернуться.

    Инлайн инсталляцией расширения называется как раз вот это аккуратное окошко, которое не заставляет пользователя переходить на Chrome Store:

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 12

    Чтобы настроить инлайн инсталляцию, вам нужно иметь контроль над доменом и хостингом, который вы описали в манифесте (файл manifest.json).

    Например, если ваш домен mysupercat.com, то нужно будет пройти стандартную процедуру верификации и подтвердить владение этим доменом.

    Чтобы включить инлайн инсталляцию, установите флаг This item uses inline install на странице редактирования расширения.

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 13

    Далее добавляете свой веб-сайт.

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 14

    В новом окне открывается Search Console, где можно пройти процедуру верификации.

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 15

    Следующим шагом нужно залить файл-идентификатор на ваш хостинг чтобы подтвердить владение доменом / сайтом

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 16

    Процедура верификации пройдена успешно.

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 17

    Верифицированный сайт становится доступен в списке для данного расширения и на нем теперь можно использовать инлайн инсталляцию

    Cкринкастинг на сайте по WebRTC из браузера Chrome - 18

Интеграция скринкастинга в веб-страницу

Расширение готово и настроено для инлайн инсталляции. Остается внедрить код вызова расширения в HTML-страницу и протестировать.

Cкринкастинг в браузере Google Chrome использует WebRTC API. Поэтому чтобы завершить этот тест, нам потребуется WebRTC — платформа.

В качестве серверной WebRTC — платформы мы будем использовать Web Call Server и Web SDK — набор скриптов API для этого сервера.

1. Создаем HTML-страницу для скринкастинга screen-sharing.html

Страница состоит из 20 строк кода и выглядит так:

<!DOCTYPE html>
<html lang="en">
<head>
   <title>Screen Sharing</title>
   <script type="text/javascript" src="../../../../flashphoner.js"></script>
   <script type="text/javascript" src="screen-sharing.js"></script>
   <link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/nlbaajplpmleofphigmgaifhoikjmbkg">
</head>
<body onload="init_page()">
<h1>Screen Sharing</h1>
<button type="button" id="installExtensionButton" onclick="installExtension()">Install Now
</button>
<h2>Capture</h2>
<div id="localVideo" style="width:320px;height:240px; border: 1px solid"></div>
<h2>Preview</h2>
<div id="remoteVideo" style="width:320px;height:240px; border: 1px solid"></div>
<button id="publishBtn" type="button" onclick="connectAndShareScreen()">Connect and share screen</button>
<p id="status"></p>
</body>
</html>

Давайте ее разберем.

1) Подгружаем файл API flashphoner.js

<script type="text/javascript" src="../../../../flashphoner.js"></script>

2) Подгружаем скрипт screen-sharing.js — его мы разберем немного позже.

<script type="text/javascript" src="screen-sharing.js"></script>

3) Указываем где искать расширение для скринкастинга.

<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/nlbaajplpmleofphigmgaifhoikjmbkg">

4) Добавляем кнопку, по нажатию на которую будет происходить установка расширения.

<button type="button" id="installExtensionButton" onclick="installExtension()">Install Now
</button>

5) Добавляем div — элемент localVideo, в котором будет отображаться захваченный экран локально

<div id="localVideo" style="width:320px;height:240px; border: 1px solid"></div>

6) Добавляем div — элемент remoteVideo, который будет плеером, отображающим то, что пришло с сервера, т.е. будет воспроизводить видеопоток, который был захвачен в localVideo и отправлен на сервер.

<div id="remoteVideo" style="width:320px;height:240px; border: 1px solid"></div>

7) Кнопка, по которой будем начинать скринкастинг и отображение статуса потока

<button id="publishBtn" type="button" onclick="connectAndShareScreen()">Connect and share screen</button>
<p id="status"></p>

В «дизайне» наша страница выглядит так.

Cкринкастинг на сайте по WebRTC из браузера Chrome - 19

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 знает какое расширение будет использовано для скринкастинга.

Flashphoner.init({screenSharingExtensionId: extensionId});

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.

var constraints = {
       video: {
           width: 320,
           height: 240,
           frameRate: 10,
           type: "screen"
       }
   };

6) Далее создается сам поток и вызывается метод publish(). Обратите внимание, что потоку задается имя test123

session.createStream({
       name: streamName,
       display: localVideo,
       constraints: constraints
   }).publish();

7) После успешной отправки потока test123 на сервер, код попадает в обработчик события PUBLISHING.

on(STREAM_STATUS.PUBLISHING, function (publishStream) {...}

8) Осталось только проиграть поток в соседнем div-блоке remoteVideo. Для этого вызываем функцию play().

session.createStream({
           name: streamName,
           display: remoteVideo
       }).play();

Страница и скрипт готовы и можно начинать тестирование.

Подготовка к тестированию

В результате у нас есть следующие файлы:

  • screen-sharing.html
  • screen-sharing.js
  • flashphoner.js

flashphoner.js находится в составе сборки Web SDK. Последнюю сборку можно скачать с этой страницы.

Кроме html и js-файлов, потребуется сервер-ретранслятор, который будет принимать видеопоток и ретранслировать его другим (в данном случае обратно на эту же страницу).

Мы используем для тестирования Web Call Server 5. Поэтому есть несколько вариантов:

Схема тестирования скринкастинга будет такой:

Cкринкастинг на сайте по WebRTC из браузера Chrome - 20

С таким же успехом можно раздать скринкастинг-поток на множество подключившихся пользователей

Cкринкастинг на сайте по WebRTC из браузера Chrome - 21

Тестируем скринкастинг в Chrome

  1. Открываем страницу screen-sharing.html по HTTPS в браузере Google Chrome
    Cкринкастинг на сайте по WebRTC из браузера Chrome - 22

  2. Нажимаем кнопку Install Now чтобы добавить расширение методом инлайн инсталляции
    Cкринкастинг на сайте по WebRTC из браузера Chrome - 23

  3. Нажимаем Add extension и можно сразу стартовать скринкастинг по кнопке Connect and share screen. Chrome попросит выбрать что именно мы будем захватывать. Это может быть вкладка либо окно Chrome или другое приложение.
    Cкринкастинг на сайте по WebRTC из браузера Chrome - 24

  4. Нажимаем кнопку Share и приходим к окончательному результату. Экран захватывается, отправляется на сервер по WebRTC и проходит обратно, отображаясь в блоке Preview.
    Cкринкастинг на сайте по WebRTC из браузера Chrome - 25

Подведем итоги

Таким образом мы успешно протестировали скринкастинг с простой тестовой страницей screen-sharing.html в браузере Google Chrome. Тестовая страница содержит расширение для скринкастинга, которое мы опубликовали в Chrome Store и которое устанавливается в один клик без перехода на Store.

При тестировании страница работала по HTTPS и отправляла / получала видео через Web Call ServerWebRTC медиасервер для трансляций потокового видео.

Для интеграции скринкастинга в HTML-страницу использовался скрипт flashphoner.js, который является частью сборки Web SDK для сервера WCS.

Ссылки

API Chrome для захвата видео с десктопа
Dashboard для разработчиков под Chrome
Минимальный код для расширения скринкастинга
Упаковка иконок в расширении
Упаковка дополнительных картинок в расширении
Скачать код примера скринкастинга
Установка Web Call Server на свой хост
Запуск Web Call Server на Amazon EC2
Демо-сервер Web Call Server 5
Web Call Server
Web SDK

Автор: e2-cat

Источник


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js