В данной статье мы расскажем как работают трансляции Youtube Live и покажем как человек с базовыми знаниями JavaScript может закодить трансляцию на Youtube Live с HTML страницы с использованием технологии WebRTC.
Для работы категорически потребуются следующие знания и умения:
1) Базовые знания JavaScript / HTML
2) Умение работать в командной строке Linux.
3) Прямые руки.
Трансляции в Youtube Live
Youtube дает возможность проводить трансляции в реальном времени. Т.е. не просто залить видеоролик, а создать полноценную живую трансляцию себя, своего кота мурзика или иного ответственного мероприятия.
Телестудия Youtube располагается на этой странице и в браузере Google Chrome выглядит так:
Для того чтобы сделать вещания доступными, нужно нажать кнопку Enable live streaming и пройти верификацию из двух шагов. Далее кнопка превращается в Create live event и можно начинать вещание.
Нажимаем Go live now чтобы перейти непосредственно к вещанию.
Youtube открывает Google Hangouts окно, через которое проводятся все манипуляции с видеопотоком.
Таким образом, мы создали живую трансляцию на Youtube Live, стартовали вещание, остановили вещание. Получили ролик с записью на Youtube. Трансляция проходила средствами Google Hangouts.
Все здорово, но судя по IT новостям, Гугл закрывает API Hangouts для разработки видео приложений с 25 апреля 2017 года. Для разработчиков это означает, что с помощью API Hangouts уже нельзя будет сделать свое кастомное приложение, которое стримит видео, в том числе и на Youtube.
Трансляция с RTMP live encoder
Далее рассмотрим альтернативный вариант создания трансляции, не привязанный к Google Hangouts и позволяющий транслировать видеопоток со специализированного устройства видеозахвата (RTMP Live Encoder).
Если кликнуть по кнопке Stream Now, попадаем в знакомый интерфейс создания трансляции.
Наиболее важная часть — это настройки кодировщика:
Как видите, здесь всего два поля:
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 и еще сотня другая серверов и сервисов.
После того как все настройки выставили, нажимаем зеленую кнопку Start чтобы начать трансляцию и видео отправляется на Youtube. На картинке немного мутно, но мой Mac перегружен и скриншоты я снимаю через Teamviewer, поэтому на особое качество рассчитывать не приходится. Чтобы получить качественный стрим, позаботьтесь о качественной веб-камере с высоким разрешением и о мощном CPU, например процессор Core i7 и SSD диск были бы полезны для беспрепятственного и качественного кодирования RTMP видеопотока.
Так как мы достигли некоторого успеха при использовании 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 напрямую из браузера.
Решением является конвертация видеопотока на стороне сервера, которая показана на схеме ниже.
Таким образом, в трансляции появляется сервер-посредник, который принимает WebRTC видеопоток и конвертирует его в формат, который принимает Youtube.
Для тестирования будем использовать Web Call Server 5. Это медиасервер с поддержкой WebRTC технологии и RTMP протокола, имеющий триальную версию.
Наша задача — установить Web Call Server 5 на Linux-сервер и отправить на него WebRTC видеопоток, который будет перенаправлен на Youtube. Для этого потребуется локальный железный сервер на 64-битной Linux системе или
В локальной сети обнаружили старенький двухъядерный Athlon 64 бит, 1.8 GHz с установленной на него CentOS 6 и 2 гигабайтами RAM. Для экспериментов решили использовать его.
Процесс установки описан на сайте разработчика.
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
Браузер ожидаемо жалуется на отсутствие нормальных SSL-сертификатов. Позже их можно будет импортировать, например взять бесплатные на letsencrypt.
Сейчас же просто жмем Advanced / Proceed и подтверждаем исключение безопасности.
7. По девелоперской документации нужно сделать еще одну вещь, относящуюся к сертификатам. Нужно сделать тоже самое на странице: 192.168.1.59:8443
Это для того чтобы сигнальные websocket соединения также проходили. Без них не будет работать WebRTC, т.к. Для его работы требуется обмен SDP через отдельное соединение.
После этих двух манипуляций с сертификатами, должна открыться страница Dashboard с демо-примерам. Нужный нам демо-пример называется WebRTC as RTMP re-publishing и выглядит так:
Давайте его протестируем в браузере Google Chrome. Задача этого примера — отправить WebRTC аудио+видео поток на Web Call Server 5, конвертировать в RTMP и перенаправить по заданному направлению.
Для начала тестирования достаточно нажать кнопку 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
4. Далее остается проиграть видеопоток во встроенном плеере. Там автоматически формируется адрес и проставляется имя потока.
Встроенный в страницу 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_
Тем самым, говорим серверу не проставлять префикс и перенаправлять полученный стрим с тем же именем.
Изменение данной настройки требует перезагрузки. Выполняем команду перезагрузки сервера и ждем 1 минуту.
service webcallserver restart
После перезагрузки переходим к заключительному этапу тестирования. Снова открываем dashboard и WebRTC as RTMP re-publishing демо-пример, но на этот раз вводим RTMP адрес в точности как для Live Encoder.
И наконец, открываем Youtube Live и смотрим результат:
На этот раз нам удалось пробросить WebRTC видеопоток на Youtube как RTMP и получить картинку.
В браузере Google Chrome во вкладке chrome://webrtc-internals можно увидеть графики, описывающие доставку WebRTC видеопотока на сервер:
На стороне Youtube, входящий трафик выглядит так:
Очень похоже на 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 и js файлы:
— 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;
}
В конечном счете получили примерно тоже самое, что и при использовании демо из коробки.
Результат выглядит так:
Обратите внимание, что снова используется протокол https. Ваш веб-сервер должен быть настроен для работы через https. Обычно это делается достаточно просто, установкой mod_ssl:
yum install mod_ssl
Код HTML — страницы занял ровно 65 строк и выглядит так:
А скачать исходники можно здесь
В результате мы создали 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
Автор: amayabay