Алиса — опытный фулл-стек разработчик и способна за неделю написать каркас SAAS проекта на своем любимом фреймворке с использованием php. На фронтенде предпочитает Vue.js.
В телеграмм стучится заказчик, которому во что бы то ни стало надо разработать веб-сайт, который будет местом встречи работодателя и сотрудника для проведения очного интервью. Очного — означает глаза в глаза, прямого видео контакта в реальном времени с видео и голосом.
«Почему не скайп?» — спросите вы. Так уж повелось, что серьезные проекты, а каждый стартап, несомненно, себя таковым считает, стараются предложить внутренний сервис коммуникаций по самым разным причинам, среди которых:
1) Не отдавать своих пользователей сторонним коммуникаторам (скайп,
hangouts, и т.д.). Оставлять их в сервисе.
2) Контролировать коммуникации: историю звонков, результаты интервью.
3) Записывать звонки (разумеется, с уведомлением обеих сторон о записи).
4) Не зависеть от политик и обновлений сторонних сервисов. Всем известна такая история: Скайп обновился, и началось ...
Задача выглядит простой. По теме гуглится WebRTC и вроде как можно организовать peer-to-peer связь между двумя браузерами, но остаются вопросы:
1) Где брать STUN / TURN серверы
2) Можно ли обойтись без них
3) Как записать peer-to-peer WebRTC звонок
4) Что будет если потребуется добавить в звонок третьего участника, например HR-менеджера или другого специалиста со стороны работодателя.
Выходит, что просто WebRTC и peer-to-peer недостаточно и не понятно что со всем этим делать чтобы запустить требуемые видео-функции сервиса.
Содержание статьи
- Сервер и API
- Входящие стримы
- Исходящие стримы
- Входящие и исходящие
- Манипуляции с входящими стримами
- Запись входящего стрима
- Снятие снапшота
- Добавление потока в микшер
- Транскодирование потока
- Добавление водяного знака
- Добавление FPS фильтра
- Поворот картинки на 90, 180, 270 градусов
- Где происходит управление входящими стримами
- Ретрансляции потоков
- Объединение серверов в сеть обработки контента CDN
- Подведем итоги
- Ссылки
Сервер и API
Для того чтобы закрыть все эти белые пятна, используются серверные решения и архитектура peer-server-peer. Web Call Server 5.2 далее WCS является одним из серверных решений — платформой для разработки, которая позволяет добавить такие видео-функции в проект и не заботиться о STUN/TURN и стабильности peer-to-peer соединений.
На самом высоком уровне WCS представляет собой JavaScript API + серверная часть. API используется для разработки на обычном JavaScript на стороне браузера, а сервер обрабатывает видеотрафик, выступая в роли Stateful Proxy для медиатрафика.
Кроме JavaScript API есть еще Android SDK и iOS SDK, которые нужны для разработки нативных мобильных приложений под iOS и Android соответственно.
Например, публикация потока на сервер (стриминг потока с веб-камеры по направлению к серверу), выглядит следующим образом:
Web SDK
session.createStream({name:”stream123”}).publish();
Android SDK
publishStream = session.createStream(streamOptions)
publishStream.publish();
iOS SDK
FPWCSApi2Stream *stream = [session createStream:options error:&error];
if(![stream publish:&error]) {
//published without errors
}
В итоге, можно реализовать не только веб-приложение, но и полноценные аппы для Google Play и App Store с поддержкой видео стриминга. Добавим мобильные SDK на верхнеуровневую картинку. Получится так:
Входящие стримы
Потоковый сервер, коим является WCS, начинается с входящих стримов. Чтобы что-то раздавать, нужно это иметь. Для раздачи видеопотоков зрителям, необходимо чтобы эти потоки зашли на сервер, прошли через его оперативную память и вышли через сетевую карту. Поэтому первый вопрос, который полезно было бы задать при ознакомлении с медиасервером — по каким протоколам и форматам последний принимает стримы. В случае WCS, это следующие технологии: WebRTC, RTMP, RTSP, VOD, SIP/RTP.
Каждый из протоколов может использоваться разноплановыми клиентами. Например по WebRTC может войти не только поток с браузера, но и с другого сервера. Отобразим возможные источники входящего трафика в таблице.
WebRTC | RTMP | RTSP | VOD | SIP/RTP |
|
|
|
|
|
Если пройти по источникам входящего трафика, можно добавить следующее:
Входящий WebRTC
Web SDK позволяет захватывать не только камеру и микрофон, но и использовать возможности браузерного API для доступа к экрану — screen sharing. Кроме этого, можно захватить произвольный элемент Canvas и все что на нем отрисовывается для последующей трансляции — canvas streaming.
Android SDK и iOS SDK из-за мобильной специфики имеют функции переключения между фронтальной и задней камерой устройства на лету. Это позволяет переключать источник во время стриминга без остановки потока.
Входящий WebRTC-поток можно получить также с другого WCS-сервера методами: push, pull и CDN, о которых речь пойдет немного позже.
Входящий RTMP
RTMP протокол широко используется в любимом стримерами OBS, и в других энкодерах: Wirecast, Adobe Media Ensourcer, ffmpeg, и т.д. Взяв один из этих энкодеров, можно захватить стрим и отправить на сервер.
Можно также забрать RTMP поток с другого медиасервера или WCS-сервера с
использованием методов push и pull. В случае push, инициатором является удаленный сервер. В случае pull — обращаемся к локальному чтобы утянуть поток с удаленного.
Входящий RTSP
Источниками RTSP трафика как правило являются IP камеры или сторонние медиасерверы с поддержкой RTSP-протокола. Несмотря на то, что при установлении RTSP-соединения инициатором является WCS, аудио и видео трафик по направлению от IP камеры двигается в сторону WCS-сервера. Поэтому поток с камеры считаем входящим.
Входящий VOD
На первый взгляд может показаться, что функция VOD (Video On Demand) связана исключительно с исходящими потоками и с воспроизведением файла браузерами. В нашем случае это немного не так. WCS честно транслирует mp4 файл из файловой системы на localhost, в результате создается входящий стрим, как если бы он зашел из стороннего источника. Далее если ограничить одним зрителем одного mp4 файла — получаем классический VOD, где зритель забирает поток и проигрывает его с самого начала. Если не ограничивать, получаем VOD LIVE — вариацию VOD, при которой зрители могут играть один и тот же файл как поток, подключаясь к той точке воспроизведения в которой в данный момент находятся все остальные (режим телевидения-трансляции предзаписанного эфира).
Входящий SIP/RTP
Для получения входящего RTP трафика внутри SIP-сессии, требуется установка звонка со сторонним SIP шлюзом. При успешно установленном соединении, со стороны SIP-шлюза пойдет аудио и/или видео трафик, который будет обернут во входящий стрим на стороне WCS.
Исходящие стримы
После получения стрима на сервер можно тиражировать полученный стрим одному или многим зрителям по запросу. Зритель запрашивает стрим из плеера или другого устройства. Такие стримы называются исходящими или “стримами зрителей”, т. к. сессии таких стримов всегда инициируются на стороне зрителя / плеера. Набор технологий воспроизведения включает следующие протоколы / форматы: WebRTC, RTMP, RTSP, MSE, HLS
WebRTC | RTMP | RTSP | MSE | HLS |
---|---|---|---|---|
|
|
|
|
|
Исходящий WebRTC
В этом случае Web SDK, Android SDK и iOS SDK выступают в качестве API для плеера. Пример воспроизведения WebRTC потока выглядит так:
Web SDK
session.createStream({name:”stream123”}).play();
Android SDK
playStream = session.createStream(streamOptions);
playStream.play();
iOS SDK
FPWCSApi2Stream *stream = [session createStream:options error:nil];
if(![stream play:&error])
{
//published without errors
}
Это очень похоже на API для публикации, с той лишь разницей, что вместо
stream.publish(), для воспроизведения вызывается stream.play().
В качестве плеера может также выступить сторонний WCS-сервер, которому дадут команду забрать поток по WebRTC с другого сервера методом pull или забрать поток внутри CDN.
Исходящий RTMP
Здесь будут главным образом RTMP плееры — как всем известный Flash Player, так и десктопные и мобильные приложения, которые работают по протоколу RTMP, принимают и играют RTMP-поток. Дело в том, что несмотря на то, что Flash ушел из браузера, от него остался RTMP протокол, который широко применяется для видеотрансляций и отсутствие его нативной поддержки в браузерах никак не препятствует использованию этого вполне удачного протокола в других клиентских приложениях. Известно о широком применении RTMP в VR-плеерах для мобильных приложений под Android и iOS.
Исходящий RTSP
WCS-сервер может выступать в роли RTSP-сервера и раздавать полученный поток по RTSP как обычная IP камера. В этом случае, плеер должен установить RTSP соединение с сервером и забрать поток на воспроизведение, как если бы это была IP-камера.
Исходящий MSE
В данном случае, плеер запрашивает у сервера поток по протоколу Websocket. Сервер отдает аудио и видео данные по вебсокетам. Данные доходят до браузера и преобразуются в куски, которые браузер умеет воспроизводить благодаря нативному расширению MSE, поддерживаемому из коробки. Плеер в конечном итоге работает на основе HTML5 video-элемента.
Исходящий HLS
Здесь WCS играет роль HLS сервера или Web-сервера, который поддерживает HLS (HTTP Live Streaming). После того, как на сервере появился входящий стрим, формируется плей-лист HLS в формате .m3u8, который отдается плееру в ответ на HTTP-запрос. Плей-лист описывает какие сегменты видео должен скачать и показать у себя плеер. Плеер скачивает видео-сегменты и воспроизводит на странице браузера, в мобильном устройстве, на десктопе, в приставке Apple TV, и везде, где заявлена поддержка HLS.
Входящие и исходящие
Итого имеем 5 входящих и столько же исходящих типов стримов. Перечислим
их в таблице:
Входящие | Исходящие |
---|---|
WebRTC | WebRTC |
RTMP | RTMP |
RTSP | RTSP |
VOD | MSE |
SIP/RTP | HLS |
Т.е. можем загнать стримы на сервер и можем к ним подключаться и играть подходящими под это дело плеерами. Чтобы проиграть WebRTC стрим, используем Web SDK. Чтобы проиграть WebRTC стрим как HLS, используем HLS плеер, и т.д. Один стрим могут играть много зрителей. Трансляции один ко многим работают.
Теперь расскажем какие действия можно производить со стримами.
Манипуляции с входящими стримами
Исходящими стримами, на которых сидят зрители особо не поманипулируешь. Действительно, если зритель установил сессию с сервером и уже забирает какой-то стрим, нет возможности внести в него какие-либо изменения, не разорвав сессию. По этой причине все манипуляции и изменения проходят на входящих стримах, в точке, где еще не произошло его тиражирование. Стрим, который подвергся изменениям далее тиражируется всем подключенным зрителям.
К операциям над стримами можно отнести:
- запись
- снятие снапшота
- добавление потока в микшер
- транскодирование потока
- добавление водяного знака
- добавление FPS-фильтра
- поворот картинки на 90, 180, 270 градусов
Запись входящего стрима
Пожалуй, самая понятная и часто-встречающаяся из функций. Действительно, потоки требуют записи во многих кейсах: вебинар, урок английского языка, консультация, и т.д.
Запись может быть инициирована как с Web SDK, так и с REST API специальным запросом:
/stream/startRecording {}
Результат сохраняется в файловой системе в виде mp4-файла.
Снятие снапшота
Не менее частая задача — снятие картинок действующего потока для отображения иконок на сайте. Например, у вас 50 потоков в системе видеонаблюдения, каждый из которых имеет источником одну IP камеру. Все 50 потоков выводить на одной странице не только проблематично по ресурсам браузера, но и бессмысленно, т.к. В случае 30 FPS, суммарный FPS изменяющейся картинки будет 1500 кадров в секунду и человеческий глаз такую частоту показа просто не воспримет. В качестве решения, можно настроить автоматическую нарезку или съем снапшотов по требованию, в этом случае можно выводить картинки на сайт с произвольной частотой, например 1 кадр в 10 секунд. Снапшоты можно снимать из SDK, через REST API или нарезать автоматически.
WCS-сервер поддерживает следующий REST-метод для снятия снапшота:
/stream/snapshot
Добавление потока в микшер
Изображение с двух и более источников можно объединить в одно для отображения конечным зрителям. Такая процедура называется микшированием. Основные примеры: 1) Видеонаблюдение с нескольких камер на экран в одну картинку. 2) Видеоконференция, где каждому пользователю для экономии ресурсов приходит один поток, в котором смикшированы остальные. Микшер управляется через REST API и имеет режим работы MCU для создания видеоконференций.
REST команда добавления потока в микшер:
/mixer/startup
Транскодирование потока
Потоки иногда требуется пережать чтобы адаптировать для отдельных групп клиентских устройств по разрешению и битрейту. Для этого используется транскодинг. Транскодинг может включаться на стороне Web SDK, через REST API, или автоматически через специальный Транскодинг-узел в CDN. Например, при заходе видео 1280x720, оно может быть транскодировано в 640x360 для отдачи клиентам из географического региона с традиционно низкой пропускной полосой. Где же твои спутники, Илон Маск?
Используемый REST-метод:
/transcoder/startup
Добавление водяного знака
Известно, что любой контент может быть украден и превращен в WebRip, какой бы защитой ни был наделен плеер. Если ваш контент действительно настолько ценный, можете вживить в него водяной знак или логотип, который cильно осложнит его дальнейшее использование и публичную демонстрацию. Для добавления водяного знака достаточно загрузить PNG-картинку, и она будет вставлена в видеопоток путем транскодирования. Поэтому придется заготовить пару ядер CPU на стороне сервера на случай, если вы все же решитесь
добавить водяной знак в поток. Чтобы не крутить водяной знак на сервере путем транскодинга, лучше добавить его прямо на энкодере/стримере, которые
зачастую предоставляют такую возможность.
Добавление FPS фильтра
В некоторых случаях требуется чтобы стрим был с ровным FPS (количество кадров в секунду). Это может пригодиться если мы ретранслируем стрим на сторонний ресурс вроде Youtube или Facebook или же играем его чувствительным HLS-плеером. Фильтрация опять же требует транскодинга, поэтому рассчитывайте силы вашего сервера и готовьте к конфигурации плюс 2 ядра на стрим если планируется такая операция.
Поворот картинки на 90, 180, 270 градусов
Мобильные устройства имеют свойство менять разрешение публикуемого потока в зависимости от угла поворота. Например, начали стримить, держа айфон горизонтально, а потом повернули на бок. По спецификации WebRTC, браузер-стример мобильного устройства, а в данном случае iOS Safari должен сигнализировать о повороте на сервер. Сервер, в свою очередь, должен разослать это событие всем подписчикам. В противном случае получилось бы
так, что стример положил телефон на бок, но видит свою камеру по-прежнему вертикально, в то время как у зрителей изображение завалено на бок. Для работы с поворотами на стороне SDK включается соответствующее расширение cvoExtension.
Где происходит управление входящими стримами
Automatic — конфигурация как правило, задается на стороне сервера в
настройках.
Действие с потоком | Web, iOS, Android SDK | REST API | Automatic | CDN |
---|---|---|---|---|
Запись | + | + | ||
Снятие снапшота | + | + | + | |
Добавление в микшер | + | + | ||
Транскодирование потока | + | + | + | |
Добавление водяного знака |
+ | |||
Добавление FPS-фильтра | + | |||
Поворот картинки на 90, 180, 270 градусов |
+ |
Ретрансляции потоков
Ретрансляция также является вариантом манипуляции над входящими на сервер стримами и заключается в принудительной передаче стрима на сторонний сервер. Синонимом ретрансляции являются такие слова как: републикация, пуш, инжект.
Ретрансляция может осуществляться по одному из следующих протоколов: WebRTC, RTMP, SIP/RTP. В таблице показано направление, по которому может быть ретранслирован поток.
WebRTC | RTMP | SIP/RTP |
---|---|---|
WCS | RTMP server WCS | SIP server |
Ретрансляция WebRTC
Поток может быть ретранслирован на другой WCS-сервер если по каким-то причинам требуется сделать поток доступным на другом сервере. Ретрансляция производится через REST API методом /push. При поступлении такого REST-запроса, WCS подключается к указанному серверу и публикует на него поток сервер-сервер. После этого поток становится доступен для воспроизведения на другой машине.
/pull/push
— используемый REST-метод.
Ретрансляция RTMP
Как и в случае с ретрансляцией по WebRTC, возможна ретрансляция и по RTMP а другой сервер. Разница будет лишь в протоколе ретрансляции. RTMP-ретрансляция также выполняется через /push и позволяет передать поток как на сторонние RTMP серверы, так и на сервисы, поддерживающие RTMP Ingest: Youtube, Facebook streaming, и т.д. Таким образом, WebRTC стрим может быть ретранслирован в RTMP. С тем же успехом в RTMP можно ретранслировать любой другой стрим входящий на сервер, например RTSP или VOD.
Ретрансляция видеопотока на другой RTMP-сервер производится при помощи REST-вызовов
/push/startup
— используемый REST-вызов.
Ретрансляция SIP/RTP
Достаточно редко используемая функция. Чаще всего в энтерпрайзе. Например, когда требуется установить SIP-звонок с внешним сервером SIP-конференций и перенаправить в этот звонок аудио или видеопоток чтобы зрители конференции увидели какой-то видеоконтент: “Посмотрите пожалуйста этот ролик” или “Коллеги, а сейчас давайте посмотрим на стрим с IP-камеры со стройки объекта”. Надо понимать, что сама конференция существует и управляется в данном случае на внешнем ВКС-сервере с поддержкой SIP (Недавно тестировали решение от Polycom DMA), мы же просто подключаемся и ретранслируем на этот сервер существующий поток. Функция REST API называется /inject и служит как раз для этого случая.
REST API команда:
/call/inject_stream/startup
Объединение серверов в сеть обработки контента CDN
Один сервер имеет как правило ограниченное количество ресурсов. Поэтому для крупных онлайн-трансляций, где счет зрителей идет на тысячи и десятки тысяч, необходимо масштабирование. Несколько серверов WCS могут быть объединены в одну сеть доставки контента CDN. Внутри CDN будет работать через WebRTC для сохранения низкой задержки при стриминге.
Сервер может быть сконфигурирован в одной из следующих ролей: Origin, Edge, Transcoder. Серверы типа Origin — принимают трафик и раздают его на краевые узлы Edge-серверы, отвечающие за доставку потока зрителям. При необходимости подготовить поток в нескольких разрешениях, в схему включаются Transcoder-узлы, которые берут на себя ресурсозатратную миссию по транскодированию потоков.
Подведем итоги
WCS 5.2 — это сервер для разработки приложений с поддержкой реалтайм аудио и видео для браузеров и мобильных устройств. Для разработки предоставляется четыре API: Web SDK, iOS SDK, Android SDK, REST API. На сервер можно публиковать (скармливать) видеопотоки по пяти протоколам: WebRTC, RTMP, RTSP, VOD, SIP/RTP. С сервера можно играть потоки плеерами также по пяти протоколам: WebRTC, RTMP, RTSP, MSE, HLS. Потоками можно управлять и производить над ними такие операции как: запись, нарезку снапшотов, микширование, транскодирование, добавление водяного знака, фильтрация FPS, трансляция поворотов видео в мобильных устройствах. Потоки можно ретранслировать на другие серверы по WebRTC и RTMP протоколам, а также перенаправлять в SIP-конференции. Серверы можно объединить в сеть доставки контента и масштабировать для обработки произвольного количества видеопотоков.
Что должна знать разработчик Алиса для работы с сервером
Разработчику необходимо уметь пользоваться Linux. Команды такого рода в
командной строке не должны вызывать замешательства:
tar -xvzf wcs5.2.tar.gz
cd wcs5.2
./install.sh
tail -f flashphoner.log
ps aux | grep WebCallServer
top
Ванильный JavaScript тоже надо уметь, если речь идет о разработке под
Web.
//публикуем поток
session.createStream({name:’mystream’}).publish();
//играем поток
session.createStream({name:’mystream’}).play();
Пригодится также умение работать с бэкендом.
WCS может не только получать управляющие команды через REST API, но и отправлять хуки — нотификации о событиях, которые на нем происходят.
Например, при попытке установить соединение из браузера или мобильного приложения, WCS вызовет хук /connect, а при попытке проиграть стрим, вызовет хук playStream. Поэтому разработчику придется побыть немного в шкуре бэка, который в состоянии написать как простого REST-клиента, так и небольшой REST-сервер для обработки хуков.
Пример REST API
/rest-api/stream/find_all
— пример REST API вывода списка стримов на сервере
Пример REST хука
https://myback-end.com/hook/connect
— обработка REST-хука /connect на стороне бэкенда.
Linux, JavaScript, REST Client / Server — три элемента, которых
достаточно для разработки продакшен сервиса на платформе WCS, работающего
с видео стримами.
Для разработки мобильных приложений потребуется знание Java и Objective C
для Android и iOS соответственно.
Установка и запуск
Быстрый запуск WCS на сегодняшний день можно провести тремя способами:
1) Установить на свой Centos7 или Ubuntu 16.x LTS или Ubuntu 18.x LTS, и
т.д. руководствуясь статьей из документации.
или
2) Взять готовый образ на Amazon EC2.
или же
3) Взять готовый образ сервера на DigitalOcean.
И начать увлекательную разработку проекта с функциями потокового видео.
Обзорная статья получилась достаточно объемной. Спасибо что хватило
терпения прочесть.
Хорошего стриминга!
Ссылки
WCS 5.2 — WebRTC сервер
Установка и запуск
Запуск готового образа на Amazon AWS
Запуск готового образа на DigitalOcean
SDK
Кейсы
Документация
Документация Web Call Server 5.2
Автор: Stas