Трансляція WebRTC-відеопотоку з браузера на YouTube Live 65 рядків JavaScript/HTML-коду

image

У даній статті ми розповімо як працюють трансляції Youtube Live і покажемо як людина з базовими знаннями JavaScript може закодить трансляцію на Youtube Live з HTML сторінки з використанням технології WebRTC.

Для роботи категорично потрібні такі знання та вміння:

1) Базові знання JavaScript / HTML
2) Вміння працювати в командному рядку Linux.
3) Прямі руки.

Трансляції на Youtube Live
Youtube дає можливість проводити трансляції в реальному часі. Тобто не просто залити відеоролик, а створити повноцінну живу трансляцію себе, свого кота мурзика або іншого відповідального заходу.

Телестудія Youtube розташовується на цій сторінці і в браузері Google Chrome виглядає так:

image

Для того щоб зробити мовлення доступними, потрібно натиснути кнопку Enable live streaming і пройти верифікацію з двох кроків. Далі кнопка перетворюється у Create live event і можна починати мовлення.

image

Натискаємо Go live now щоб перейти безпосередньо до мовлення.

Youtube відкриває Google Hangouts вікно, через який проводяться всі маніпуляції з відеопотоком.

image

Таким чином, ми створили живу трансляцію на Youtube Live, стартували мовлення, зупинили мовлення. Отримали ролик із записом на Youtube. Трансляція проходила засобами Google Hangouts.

Все здорово, але судячи з IT новин, Гугл закриває API Hangouts для розробки відео додатків з 25 квітня 2017 року. Для розробників це означає, що з допомогою API Hangouts вже не можна буде зробити своє кастомное додаток, яке стрім відео, в тому числі і на Youtube.

Трансляція з RTMP live encoder
Далі розглянемо альтернативний варіант створення трансляції, не прив'язаний до Google Hangouts і дозволяє транслювати відео зі спеціалізованого пристрою відеозахоплення (RTMP Live Encoder).

image

Якщо клікнути по кнопці Stream Now, потрапляємо в знайомий інтерфейс створення трансляції.

Найбільш важлива частина — це параметри кодувальника:

image

Як бачите, тут всього два поля:

1) Server URL
2) Stream name / key

Якщо натиснути кнопку Reveal, назва вашого потоку відобразиться і буде доступно для копіювання.

Цих даних достатньо для того, щоб надіслати відеопотік з RTMP Live Encoder на Youtube Live з будь-якого місця і будь-якого комп'ютера, без використання Google Hangouts. RTMP Live Encoder (кодер) — це пристрій або програмне забезпечення, яке захоплює потік з веб-камери або з професійної відеокамери, кодує відео в RTMP протокол і відправляє за вказаною адресою (Encoder setup).

Щоб отримати якісний аудіо і відео потрібно використовувати стандартні для Live Encoders кодеки, а саме H. 264 відеокодек і AAC аудіо кодек. Ця комбінація кодеків є найпоширенішою і надійної і є фактичним стандартом застосування в RTMP при використанні автономних кодувальників.

Наприклад плагін для браузера Adobe Flash Player теж є кодувальником і може стримить відео прямо з веб-сторінки браузера, але він не підтримує аудіо кодек AAC для стрімінг і тому з мовленням можуть виникнути проблеми, а саме не може бути звуку.

Тому ми відразу беремо тестування тільки ті коди, які явно підтримують кодеки H. 264 і AAC. На поточний момент нам відомі два кандидата на тестування, які використовують дані кодеки:

Adobe Flash Media Live Encoder на Mac OS — це безкоштовний програмний кодер від Adobe, який може кодувати RTMP потоки в H. 264 і AAC. Зверніть увагу, що AAC аудіо кодек підтримується тільки у версії FMLE для Mac OS. Якщо ви використовуєте той же софт на Windows, AAC кодек буде недоступний. Замість нього буде mp3.

Wirecast — це платний кодувальник, який має безкоштовну тріальну версію в якій поверх транслюється відео вставляється логотип і накладається звук кожні 30 секунд. Wirecast має Windows-дистрибутив.

Почнемо з Adobe FMLE. Встановлюємо FMLE на Mac і подцепляем до комп'ютера (у тестах використовувався Mac Mini) веб-камеру. З віртуальними камерами FMLE, схоже не працює, тому потрібна чесна USB веб-камера або вбудована (якщо у вас макбук).

В якості відеокодека виставляємо H. 264 з роздільною здатністю 640x480. У якості аудіокодека залишаємо те, що задано за замовчуванням AAC 22050 Hz mono. Інші конфігурації та налаштування H. 264 і AAC також повинні працювати без проблем.

У полі FMS URL проставляємо RTMP-адреса трансляції, який був отриманий на Youtube.
У полі Stream проставляємо назва стріму, що знову ж таки було отримано на Youtube.

* Поле має таку дивну назву FMS URL тому що FMLE думає що в світі існує тільки один сервер, здатний приймати RTMP відео — Flash Media Server від Adobe (нині Adobe Media Server), але як ми бачимо це не так, і з цим завданням чудово справляється, наприклад Youtube і ще сотня інша серверів і сервісів.

image

Після того, як всі налаштування виставили, натисніть зелену кнопку Start щоб почати трансляцію і відео відправляється на Youtube. На картинці трохи мутно, але мій Mac перевантажений і скріншоти я знімаю через Teamviewer, тому на особливу якість розраховувати не доводиться. Щоб отримати якісний стрім, подбайте про якісної веб-камері з високим дозволом і про потужний CPU, наприклад процесор Core i7, і SSD диск були б корисні для безперешкодного та якісного кодування RTMP відеопотоку.

image

Так як ми досягли деякого успіху при використанні FMLE, то тестувати Wirecast особливого сенсу немає. Якщо у вас виникли проблеми з FMLE чи немає під рукою Mac OS, спробуйте зробити теж саме з Wirecast. Наприклад у цій статті можна знайти кілька скріншотів з описом як транслювати відео в Wirecast. Кодувальник Wirecast цікавий тим, що його можна використовувати навіть без веб-камери. Віщати і кодувати в RTMP можна звичайний відеоролик.

Конвертація з WebRTC в RTMP
Вище ми провели тест, який показує, як створити мовлення на сервісі Youtube Live і як відправити RTMP відео, закодований в H. 264 + AAC на Youtube.

Наступне завдання — зробити теж саме з допомогою WebRTC. WebRTC — це технологія, вбудована в браузер, яка дозволяє браузеру захоплювати відео з камери і аудіо з мікрофону і відправляти в мережу. Таким чином, браузер, що підтримує WebRTC може працювати в точності як Live Encoder — робити захоплення і відправляти. WebRTC підтримується в наступних браузерах:

  • Chrome
  • Firefox
  • Opera
  • Chrome for Android
  • Firefox for Android
Тобто WebRTC відеопотоки можна відправляти з десктопних браузерів Chrome, FF і тих же браузерів під управлінням Android.

В результаті, наша задача — зробити трансляцію на Youtube з браузера Google Chrome звичайної HTML сторінки, без використання Google Hangouts або RTMP Live Encoder.

Проблеми три:

  • WebRTC не підтримує RTMP протокол, який вимагає Youtube.
  • WebRTC не підтримує AAC аудіо кодек, який вимагає Youtube.
  • WebRTC в Chrome не підтримує кодек H. 264 на мобільних пристроях, там використовується кодек VP8.
По цим трьом причин, WebRTC не може прямо відправити аудіо+відео на Youtube Live.

Якщо ж говорити про Adobe Flash Player, у нього інша проблема

  • Не кодує аудіо в AAC
Тому незалежно від того, використовується браузер з підтримкою WebRTC (Chrome) або браузер з підтримкою Flash Player (IE або Safari), не можна відправити RTMP-відеопотік H. 264 + AAC прямо з браузера.

Рішенням є конвертація відеопотоку на стороні сервера, яка показана на схемі нижче.

image

Таким чином, в трансляції з'являється сервер-посередник, який приймає WebRTC відеопотік і конвертує його у формат, який приймає Youtube.

Для тестування будемо використовувати Web Call Server 5. Це медіасервер з підтримкою WebRTC технології та протоколу RTMP, має тріальну версію.

Наше завдання — встановити Web Call Server 5 на Linux-сервер і відправити на нього WebRTC відеопотік, який буде перенаправлено на Youtube. Для цього потрібно локальний залізний сервер на 64-бітної системі Linux або VPS сервер у хостера. Мінімальні вимоги: 1 ядро процесора і 1 гігабайт RAM, Linux x86_64.

В локальній мережі виявили старенький двоядерний Athlon 64 біт, 1.8 GHz з встановленою на нього CentOS 6 і 2 гігабайтами ОПЕРАТИВНОЇ пам'яті. Для експериментів вирішили використати його.

Процес установки описаний на сайті розробника.

1. Завантажуємо архів

wget https://flashphoner.com/download-wcs5-server.tar.gz

При скачуванні wget лається на сертифікати. Доводиться додавати прапор:

wget --no-check-certificate https://flashphoner.com/download-wcs5-server.tar.gz

2. Розпаковуємо

tar -xzf download-wcs5-server.tar.gz

3. Запускаємо інсталятор

./install.sh

При інсталяції видає помилку і вказує на відсутність Java.

4. Встановлюємо java c допомогою менеджера пакетів, після чого запускаємо інсталятор знову.

yum install java
./install.sh

Під час інсталяції, інсталятор запитує, не в локальній мережі знаходиться сервер. Відповідаємо ствердно 'yes', після чого інсталятор прописує в налаштування локальний IP адреса сервера 192.168.1.59.

5. Далі запускаємо сервер.

service webcallserver start

Запуск сервера займає близько хвилини.

6. Відкриваємо dashboard за адресою 192.168.1.59:8888 в Chrome

image

Браузер очікувано скаржиться на відсутність нормальних SSL-сертифікатів. Пізніше їх можна буде імпортувати, наприклад взяти безкоштовні letsencrypt.

Зараз же просто тиснемо Advanced / Proceed і підтверджуємо виняток безпеки.

7. девелоперської документації потрібно зробити ще одну річ, що відноситься до сертифікатів. Потрібно зробити теж саме на сторінку: 192.168.1.59:8443

Це для того щоб сигнальні websocket з'єднання також проходили. Без них не буде працювати WebRTC, тому що Для його роботи потрібно обмін SDP через окреме з'єднання.

image

Після цих двох маніпуляцій з сертифікатами, має відкритися сторінка Dashboard з демо-прикладів. Потрібний нам демо-приклад називається WebRTC as RTMP re-publishing і виглядає так:

image

Давайте його протестуємо в браузері Google Chrome. Завдання цього прикладу — відправити WebRTC аудіо+відео потік з Веб Call Server 5, конвертувати в RTMP і перенаправити у заданому напрямку.

image

Для початку тестування досить натиснути кнопку Start і дозволити використання камери і мікрофона за запитом браузера.

На скріншоті зверху відбувається наступне:

1. Встановлюється з'єднання браузера Google Chrome і Web Call Server 5 по протоколу websocket через захищене з'єднання: wss://192.168.1.59:8443

2. WebRTC аудіо+відео потік відправляється на сервер і відображається статус PUBLISHING, який говорить про успішну відправку відеопотоку на сервер.

3. Web Call Server перенаправляє отриманий WebRTC аудіо+відео потік на вказаний RTMP адреса:

  • rtmp://localhost:1935/live
  • stream1
Таким чином RTMP відео перенаправляється на localhost, тобто На той же самий сервер 192.168.1.59 в нашому випадку. Тобто Можна сказати, що Web Call Server прийняв WebRTC потік і завернув його на самого себе як RTMP.

Зверніть увагу, як це корелює з Youtube Live. Там ми вказували Server URL Stream name / key

image

4. Далі залишається програти відео у вбудованому плеєрі. Там автоматично формується адресу та проставляється ім'я потоку.

image

Вбудований в сторінку RTMP плеєр дуже простий і дозволяє переконатися, що стрім на місці і відтворюється коректно.

Повна адреса стріму виглядає так: rtmp://192.168.1.59:1935/live/rtmp_stream1

Тут потрібно звернути увагу на важливу деталь — Web Call Server 5 підставляє назва стріму префікс rtmp_. Тобто приймає потік з назвою stream1, а перенаправляє його як rtmp_stream1. Це важливо для тестування на localhost, щоб імена стримов були різними.

Локальне тестування пройшло успішно і прийшла пора відправити стрім на Youtube Live.
Згадаймо, що для тестування Youtube Live c RTMP live video encoder ми використовували

Server URL: rtmp://a.rtmp.youtube.com/live2
Stream name / key: myfm-c9td-etew-eqdf
Тобто Youtube очікує від нас імені відеопотоку саме такого і ніякого інакше: myfm-c9td-etew-eqdf. І якщо Web Call Server проставить префікс rtmp_, то результуюче ім'я буде rtmp_myfm-c9td-etew-eqdf і Youtube не прийме потік.

Для того щоб це обійти, редагуємо конфіг /usr/local/FlashphonerWebCallServer/conf/flashphoner.properties на стороні сервера.
Коментуємо або прибираємо рядок конфига:

#rtmp_transponder_stream_name_prefix =rtmp_

Тим самим, говоримо сервера не проставляти префікс і перенаправляти отриманий стрім з тим же ім'ям.

image

Зміна даної настройки вимагає перезавантаження. Виконуємо команду перезавантаження сервера і чекаємо на 1 хвилину.

service webcallserver restart

Після перезавантаження переходимо до заключного етапу тестування. Знову відкриваємо dashboard і WebRTC as RTMP re-publishing демо-приклад, але на цей раз вводимо RTMP адресу в точності як для Live Encoder.

image

І нарешті, відкриваємо Youtube Live і дивимося результат:

image

На цей раз нам вдалося прокинути WebRTC відео на Youtube як RTMP і отримати картинку.

У браузері Google Chrome у вкладці chrome://webrtc-internals можна побачити графіки, які описують доставку WebRTC відеопотоку на сервер:

image

На стороні Youtube, вхідний трафік виглядає так:

image

Дуже схоже на HTTP Live streaming (HLS) з подгрузкой відео-сегментів по протоколу HTTP (HTTPS).

Відмінно, у нас вийшло протестувати і переконатися, що це дійсно працює. Картинка є, звук є, відеопотік йде прямо з браузера і потрапляє на Youtube.

Тепер можна переходити до програмування. А саме, ми хотіли б мати можливість зробити теж саме з простий HTML-сторінки і в перспективі зі свого веб-сайту або веб-додатки.

Програмування HTML-сторінки, що відправляє WebRTC на Youtube
Простіше всього було б розібратися в прикладі, завантаживши три файлу з вихідними кодами: HTML, JavaScript, CSS. Але ми не шукаємо легких шляхів і хочемо створити мінімальну сторінку з нуля (так сказати from scratch).

Починаємо з створення болванки test-webrtc-youtube.html

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
</html>

Тепер потрібно завантажити скрипт flashphoner.js, який робить всю роботу, пов'язану з WebRTC і передачею відеопотоку на сервер. Цей скрипт входить в Web SDK доступний для скачування цим посиланням.

Завантажуємо і розпаковуємо Web SDK на окремий сервер, де встановлений Apache (у кого-то Nginx).

wget https://flashphoner.com/downloads/builds/flashphoner_client/wcs_api-2.0/flashphoner-api-0.5.14.1977-48448b99eddb0da1248519290dba2d4d00d4a505.tar.gz

Створюємо папку /var/www/html/test-webrtc-youtube в якій буде перебувати html-сторінка і копіюємо в папку html та php файли:

— test-webrtc-youtube.html
— flashphoner.js

Виходить така структура:

test-webrtc-youtube
-- flashphoner.js
-- test-webrtc-youtube.html

1. Додаємо на сторінку наступні елементи:

<body onload="init_page()">
<div id="localVideo" style="width:320px;height:320px;border: 1px solid"></div>
Server URL <input type="text" id="urlServer" value="wss://192.168.1.59:8443"/><br/>
Stream URL: < input type="text" id="rtmpUrl" value="rtmp://a.rtmp.youtube.com/live2"/><br/>
Stream name / key: <input type="text" id="streamName" value="myfm-c9td-etew-xxxx"/><br/>
<input type="button" onclick="publishToYoutube()" value="Start"/>
<p id="status"></p>
</body>

1) localVideo — це просто div-блок, який буде розміщено відео з веб-камери
2) urlServer, rtmpUrl, streamName — вже знайомі з попереднього тестування поля
3) status — у цьому полі відображається статус з'єднання або потоку

2. Додаємо три змінних:

var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS;
var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS;
var localVideo;

Перші дві є просто скороченням. Змінна localVideo буде зберігати посилання на div-елемент.

3. Ініціалізуємо API

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

4. Підключення до WCS сервера і початок стрімінг.

function publishToYoutube(){
var urlServer = document.getElementById("urlServer").value;
Flashphoner.createSession({urlServer: urlServer}).on(SESSION_STATUS.ESTABLISHED, function(session){
//session connected, start streaming
startStreaming(session);
}).on(SESSION_STATUS.DISCONNECTED, function(){
setStatus("Connection DISCONNECTED");
}).on(SESSION_STATUS.FAILED, function(){
setStatus("Connection FAILED");
});
}

При успішному підключенні по події ESTABLISHED, починається стрімінг викликом функції startStreaming

5. Надсилання відео.

function startStreaming(session) {
var streamName = document.getElementById("streamName").value;
var rtmpUrl = document.getElementById("rtmpUrl").value;
session.createStream({
name: streamName,
display: localVideo,
cacheLocalResources: true,
receiveVideo: false,
receiveAudio: false,
rtmpUrl: rtmpUrl
}).on(STREAM_STATUS.PUBLISHING, function(publishStream){
setStatus(STREAM_STATUS.PUBLISHING);
}).on(STREAM_STATUS.UNPUBLISHED, function(){
setStatus(STREAM_STATUS.UNPUBLISHED);
}).on(STREAM_STATUS.FAILED, function(){
setStatus(STREAM_STATUS.FAILED);
}).publish();
}

Тут ми створили стрім і викликали для нього функцію publish.

6. Всі статуси відображаємо окремою функцією.

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

У кінцевому рахунку отримали приблизно теж саме, що і при використанні демо з коробки.

Результат виглядає так:

image

Зверніть увагу, що знову використовується протокол https. Ваш веб-сервер повинен бути налаштований для роботи через https. Зазвичай це робиться досить просто, установкою mod_ssl:

yum install mod_ssl

Код HTML — сторінки зайняв рівно 65 рядків і виглядає так:

image

А завантажити вихідні коди можна тут

У результаті ми створили HTML-сторінку розміром 65 рядків, включаючи скрипти, яка з використанням файлу API flashphoner.js відправляє WebRTC відео на Web Call Server, який в свою чергу перенаправляє цей відеопотік на сервіс Youtube Live.

На цьому все. Для бажаючих повторити наводжу використані в статті посилання і матеріали.

Посилання:

1) Youtube Live
2) Adobe Flash Media Live Encoder
3) Wirecast
4) Web Call Server (використовувана версія 2047)
5) WebRTC
6) Вихідні коди HTML+Javascript
7) Google закриває Hangouts API
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.