javascript

Транслируем видеопоток с веб-страницы по WebRTC на Facebook и YouTube одновременно

  • пятница, 5 мая 2017 г. в 03:14:22
https://habrahabr.ru/company/flashphoner/blog/327986/
  • Разработка систем связи
  • Разработка веб-сайтов
  • Программирование
  • JavaScript
  • Блог компании Flashphoner


Facebook и YouTube предоставляют сервисы трансляций, которые позволяют вещать Live-видеопотоки на широкую аудиторию зрителей. В этой статье мы расскажем, как захватить видеопоток с веб-страницы по технологии WebRTC и отправить этот видеопоток одновременно в Facebook и на YouTube для прямой трансляции — сразу в два сервиса.

Перед тем как начать трансляцию, выясним, какие RTMP endpoints предоставляют Facebook и Youtube для стриминга. Далее нам нужно будет послать по этим RTMP адресам видеопотоки.

Facebook


Начнем, пожалуй с Facebook. Первым делом нужно отыскать кнопку Начать прямой эфир. Эта кнопка может выглядеть так:


Или вот так:


Далее нужно еще раз нажать кнопку В эфир


И кликнуть по ссылке Click here для трансляции с внешних устройств, а не с самого Facebook.

Далее кликаем Создать стрим


В результате, Facebook дает данные RTMP потока:


Из скриншота видно, что адрес сервера: rtmp://rtmp-api.facebook.com:80/rtmp/

А имя RTMP потока — это длинная уникальная строка:
1489000000111961?ds=1&s_l=1&a=ATj9giGjaTTfgpNHBP

Именно эти два параметра нам потребуются для трансляции. Давайте их пока отложим и узнаем RTMP параметры для YouTube.

YouTube


Чтобы начать стримить с YouTube, нужно зайти на сайт https://youtube.com/live и нажать на кнопочку Upload


Далее выбираем Live Streaming и жмем Get Started.


Должна показаться панель стриминга, плеер и RTMP-настройки:


Из настроек видим, что RTMP адрес сервера rtmp://a.rtmp.youtube.com/live2, а имя потока скрыто и становится видимым по нажатию на кнопку Reveal.
Имя RTMP-потока для YouTube выглядит так: 8r0t-z4d-9xyj-2bcd

В итоге мы точно знаем куда слать RTMP-потоки:
  Facebook YouTube
RTMP-адрес rtmp://rtmp-api.facebook.com:80/rtmp/ rtmp://a.rtmp.youtube.com/live2
Имя потока 1489000000111961?ds=1&s_l=1&a=ATj9giGjaTTfgpNHBP 8r0t-z4d-9xyj-2bcd

Web Call Server


Сервер будет отвечать за прием видеопотока с вебкамеры по WebRTC и доставку на Facebook и YouTube по RTMP.


Делай раз

Сначала отправляем на сервер видеопоток с веб-камеры из браузера Google Chrome.

Для этой цели можно скачать пример HTML-страницы и скрипта для стриминга здесь и развернуть на своем веб-сервере три файла из этого архива:

  • streamer.html
  • streamer.js
  • flashphoner.js

flashphoner.js — это файл API. Его последнюю версию можно скачать в сборке Web SDK.

Код стандартного демо-примера для стриминга доступен здесь. Допустим мы открыли демо. Коннектимся к серверу и отправляем на сервер WebRTC видеопоток с именем 5dfd. Это работает так:


Видео захватывается с камеры браузера (в данном случае с виртуальной), и уходит на сервер WCS5 по технологии WebRTC, в кодеках VP8+Opus или H.264+Opus в зависимости от устройства и версии браузера.

Следующим шагом будет перенаправление этого видео на Facebook.

Делай два

Web Call Server имеет REST API, которое позволяет, зная имя потока, перенаправить WebRTC видеопоток на RTMP.

Для этого нужно отправить серверу REST / HTTP запрос следующего содержания:
URL
https://wcs5-eu.flashphoner.com:8888/rest-api/push/startup
Content-Type application/json
Method POST
Body
{
streamName: "5dfd",
rtmpUrl: "rtmp://rtmp-api.facebook.com:80/rtmp/1489000000111961?ds=1&s_l=1&a=ATj9giGjaTTfgpNHBP"

}

Такой запрос можно протестировать из тулы Advanced REST Console, которая выглядит так:


В результате WCS перенаправляет WebRTC видеопоток на Facebook по длинному адресу:

rtmp://rtmp-api.facebook.com:80/rtmp/1489000000111961?ds=1&s_l=1&a=ATj9giGjaTTfgpNHBP

В этом адресе совмещены RTMP URL и имя видеопотока.

Через несколько секунд в Facebook появится видео:


Делай три

Высылаем аналогичный запрос для YouTube
URL
https://wcs5-eu.flashphoner.com:8888/rest-api/push/startup
Content-Type application/json
Method POST
Body
{
streamName: "5dfd",
rtmpUrl: "rtmp://a.rtmp.youtube.com/live2/8r0t-z4d-9xyj-2bcd"
}

Или из REST-консоли:


Сервер вернет 200 OK и заберет поток на YouTube:


В итоге видим, что стрим транслируется и раздается на оба сервиса: и на Facebook и на YouTube.


Теперь можно запросить список всех транслируемых потоков из того же REST API:
URL
https://wcs5-eu.flashphoner.com:8888/rest-api/push/find_all
Content-Type application/json
Method POST
Body
{}

Сервер вернет список потоков, которые в данный момент ретранслируются на Facebook и YouTube:


Останавливаем ретрансляции двумя вызовами /push/terminate

Отключаемся от Facebook:
URL
https://wcs5-eu.flashphoner.com:8888/rest-api/push/terminate
Content-Type application/json
Method POST
Body
{
"mediaSessionId": "8omef99f40674tcfi4pm87npbb"
}

Отключаемся от YouTube:
URL
https://wcs5-eu.flashphoner.com:8888/rest-api/push/terminate
Content-Type application/json
Method POST
Body
{
"mediaSessionId": "e13p1gc10bgsk3me49cest9gv2"
}

Таким образом, мы организовали трансляцию с веб-страницы по технологии WebRTC на сервер Web Call Server 5, затем одним REST-запросом /push/startup ре-транслировали видеопоток на Facebook, а вторым запросом /push/startup ре-транслировали поток на YouTube Live. После этого проверили воспроизведение видеопотоков через стандартные плееры сервисов и вывели список ре-транслируемых потоков запросом /push/find_all. Закончили тестирование, завершив текущие трансляции двумя запросами /push/terminate.

Пишем JavaScript / HTML код


Работать с REST API, пожалуй, приходилось каждому или почти каждому разработчику. Поэтому мы не будем здесь описывать код, реализующий отправку REST/HTTP запросов.

Вместо этого расскажем как видеопоток с веб-страницы и вебкамеры доходит до сервера.

Как мы упоминали выше, для создания минимального клиента, захватывающего видео, необходимо три скрипта:

  • streamer.html
  • streamer.js
  • flashphoner.js

flashphoner.js — это файл, который находится в сборке Web SDK и описывать его смысла нет.

streamer.html

Эта страница содержит div-элемент localVideo, в котором будет отображаться захват с камеры, и кнопку Start для начала трансляции.

<html>
<head>
    <script language="javascript" src="flashphoner.js"></script>
    <script language="javascript" src="streamer.js"></script>
</head>
<body onLoad="init()">
<h1>The streamer</h1>
<div id="localVideo" style="width:320px;height:240px;border: 1px solid"></div>
<input type="button" value="start" onClick="start()"/>
<p id="status"></p>
</body>
</html>

streamer.js

Скрипт трансляции работает с четырьмя основными функциями API:

  • Flashphoner.init(); //отвечает за инициализацию API.
  • Flashphoner.createSession(); //отвечает за подключение к серверу
  • session.createStream(); //отвечает за создание видеопотока
  • session.createStream().publish(); //отвечает за отправку видеопотока

В результате устанавливается подключение к серверу по протоколу Websocket и захват видео с веб-камеры браузера с последующей отправкой на сервер по WebRTC.

var localVideo;

function init(){
    Flashphoner.init();
    localVideo = document.getElementById("localVideo");
}

function start() {
    Flashphoner.createSession({urlServer: "wss://wcs5-eu.flashphoner.com:8443"}).on(Flashphoner.constants.SESSION_STATUS.ESTABLISHED, function (session) {
        //session connected, start streaming
        startStreaming(session);
    }).on(Flashphoner.constants.SESSION_STATUS.DISCONNECTED, function () {
        setStatus("DISCONNECTED");
    }).on(Flashphoner.constants.SESSION_STATUS.FAILED, function () {
        setStatus("FAILED");
    });
}

function startStreaming(session) {
    session.createStream({
        name: "stream222",
        display: localVideo,
        cacheLocalResources: true,
        receiveVideo: false,
        receiveAudio: false
    }).on(Flashphoner.constants.STREAM_STATUS.PUBLISHING, function (publishStream) {
        setStatus(Flashphoner.constants.STREAM_STATUS.PUBLISHING);
    }).on(Flashphoner.constants.STREAM_STATUS.UNPUBLISHED, function () {
        setStatus(Flashphoner.constants.STREAM_STATUS.UNPUBLISHED);
    }).on(Flashphoner.constants.STREAM_STATUS.FAILED, function () {
        setStatus(Flashphoner.constants.STREAM_STATUS.FAILED);
    }).publish();
}

function setStatus(status) {
    document.getElementById("status").innerHTML = status;
}

Скачать архив с скриптами streamer.html и streamer.js можно здесь.

Чтобы трансляция заработала из Google Chrome, нужно выложить скрипты трансляции на веб-хостинг, который работает по https.

Web Call Server может быть установлен на отдельном Linux-хосте. Скачать сервер для тестов можно здесь. После того, как сервер установлен и запущен, он будет принимать входящие вебсокет-соединения по адресам: ws://host:8080 и wss://host:8443

Таким образом, мы показали как захватить видео с вебкамеры и доставить видеопоток до сервера с помощью трех скриптов. Если все было сделано правильно, скрипт должен вывести статус PUBLISHING. Это означает, что WebRTC поток успешно доставляется на сервер и может быть ре-транслирован на YouTube или Facebook с помощью REST API.



Ссылки


Web Call Server — WebRTC сервер с возможностью ретрансляции на YouTube и Facebook
Web SDK — JavaScript API для внедрения кода трансляции в веб-страницу.
REST API — управление ретрансляциями WebRTC видеопотоков
Source — исходный код примера трансляции потока с веб-страницы на сервер.
YouTube Live — сервис живых трансляций от YouTube
Facebook Live — сервис живых трансляций от Facebook