VOD — это про video on demand, т.е. проигрывание обычных роликов, как это делается на YouTube или другом стриминговом сервисе. WebRTC — это видео реалтайм с низкой задержкой. Вы спросите — как эти две вещи могут быть связаны? Заходите под кат за подробностями.

Сапорт и багфикс


Все началось, как обычно, с сапорта. К нам обратилась девушка-программист, предположительно из аутсорсинговой компании в Индии, которая участвовала в разработке мобильного приложения для телемедицины. Одной из хотелок клиента была запись WebRTC видеочата с iOS приложения, с последующим воспроизведением в этом же iOS приложении. Такая запись работала, но при воспроизведении стандартными средствами iOS SDK, обнаружились зеленые артефакты. Точнее даже не артефакты, а вполне четкие прямоугольные области зеленого цвета, занимающие ? экрана. Конечно же это никуда не годилось, и мы приступили к изучению проблемы.


Воспроизведение записанного WebRTC видео через AVPlayerViewController

В мобильном приложении для воспроизведения видео, мы использовали стандартные компоненты MPMoviePlayer или AVPlayerViewController, которые могут играть mp4 ролик если указать его http URL, например http://host/sample.mp4. Эти компоненты отыгрывали MP4 видео нормально, но в случае с трансляциями, записанными с iOS приложения, зеленая область никуда не исчезала и все портила.

WebRTC динамически меняет разрешение потока


Оказалось, что зеленые артефакты в записи были связаны с тем, что для WebRTC нормально менять разрешение видео на лету. При этом, в файле записи mp4 мы имеем чудесные фреймы разного размера, точнее сначала последовательность одного размера 640x480, потом другого 320x240, и т.д. Такие фокусы замечательно отыгрывает например VLC, без каких либо артефактов, а встроенные компоненты воспроизведения видео в iOS по HTTP дают зеленые артефакты при изменении разрешения видео в битстриме.

Давайте запустим трансляцию с iOS-приложения и убедимся, что это действительно так. Для тестирования можно воспользоваться нашим мобильным приложением для iOS — Two Way Streaming на базе iOS SDK и демо-сервером WCS5-EU.

Так выглядит приложение, которое стримит поток на сервер:


А так выглядит изменение разрешения видео, отправляемого с мобильного приложения, во времени:


Из графика мониторинга видеопотока видно, что разрешение картинки динамически меняется в зависимости от возможностей мобильного устройства по сжатию видео, работы с сетью, и т.д. WebRTC меняет разрешение чтобы таргетировать низкую задержку.

WebRTC VOD, как решение


Выходом из сложившейся ситуации стал бы рескейлинг с транскодингом, т.е. декодирование фреймов, приведение к одному разрешению, например 640x480 и запись в этом разрешении. Но если делать так с каждым публикуемым на сервер стримом, ресурсы CPU быстро иссякнут на 10-20 видеопотоках. Поэтому нам требовалось какое-то решение, не задействующее транскодинг.

Мы подумали — если WebRTC стримит видео с такими изменениями в разрешениях, то оно должно уметь и отыгрывать видео, записанное таким образом. Получается, если мы зачитаем mp4 файл и скормим его по WebRTC браузеру или мобильному приложению, то все должно быть в порядке и зеленые прямоугольники на экране iOS приложения должны уйти.

Осталось реализовать зачитку записанного mp4 и проброс в движок Web Call Server для дальнейшей конвертации в WebRTC. Первые же тесты показали хорошие результаты — зеленые прямоугольники исчезли.

Так мы получили VOD с воспроизведением не только по WebRTC, но и по всем поддерживаемым протоколам и технологиям: RTMP, RTMFP, RTSP, HTML5 Canvas, Media Source, HLS, WebRTC.

WebRTC VOD — Live трансляция


Дальше возник вопрос — “А вдруг пользователи захотят транслировать ролик как поток, всем сразу и одновременно?”.

В результате, пришлось сделать два типа VOD.

Первый — персональный VOD. Для каждого юзера, желающего проиграть ролик, создается отдельный канал, по которому с самого начала ролика отыгрывается видео.

Второй — живой VOD. Если юзер начал играть ролик, а второй юзер подключился позже, то они будут смотреть ролик как живую трансляцию в реальном времени, т.е. сервер будет стримить из ролика ровно один поток, к которому оба юзера будут подключены и смогут одновременно смотреть, например футбольный матч и комментировать действия игроков.

В нашем плеере и в API, чтобы играть поток, нужно знать его имя.

Для VOD мы ввели следующие схемы:

Если нужно проиграть ролик персонально, передаем имя потока так:

vod://sample.mp4

Если же требуется устроить из ролика полноценную онлайн-трансляцию, то имя потока будет таким:

vod-live://sample.mp4

Сам файл sample.mp4 должен лежать в папке сервера WCS_HOME/media и иметь формат MP4 / H.264 + AAC.

Что же стало с iOS приложением? — спросите вы.

Все хорошо. iOS приложение играет VOD ролик по WebRTC без зеленых прямоугольников.

WebRTC VOD в Web плеере


А теперь посмотрим, как WebRTC VOD выглядит в вебе. Для этого, на стороне сервера скопируем mp4-файл в папку /usr/local/FlashphonerWebCallServer/media. Пусть это будет всем известный Big Buck Bunny, sample.mp4.

Открываем страницу с тестовым плеером, указываем название потока vod://sample.mp4 и нажимаем Test Now.


Плеер начинает играть поток через WebRTC. В chrome://webrtc-internals можно видеть графики воспроизведения:


В итоге история закончилась хорошо. Мы пофиксили баг с зеленым экраном при воспроизведении mp4-записи трансляции в iOS приложении и сделали WebRTC-VOD-функцию для веб-браузеров и мобильных устройств под управлением iOS и Android.

Ссылки


  1. Тестовое iOS приложение Two Way Streaming для трансляций
  2. Web плеер — пример плеера для воспроизведения VOD — WebRTC потоков
  3. Сервер Web Call Server 5, раздающий mp4 ролики по WebRTC
  4. WebRTC SDK для iOS — библиотека для разработки стриминг-приложений для iOS

Комментарии (4)


  1. bustEXZ
    11.09.2017 08:32

    Видимо из-за хабраэффекта на страницу я так и не попаду (503) :) Спасибо за интересный опыт!


  1. Barabashkad
    11.09.2017 18:20
    +2

    это называеться «Scalable Video». К WebRTC обычно еще преполагаеться SDP — Session Description protocol, в котором и можно указать какие потоки клиент готов принимать…
    если клиент сообщяет что готов к 2м потокам, как в вашем случае, подрозумеваеться
    что клиент будет скейлить на весь экран сам, если сервер решит переслать меньшую резолюцию. Или же клиент сообщает что готов принимать только одну, в вашем случае 640х480, то сервер пришлет только ее!

    Scalable Video родилось что бы сэкономить транскодинг на сервере


    1. flashphoner Автор
      13.09.2017 12:24

      это называеться «Scalable Video»

      Нет, в статье речь не идет про scalable video, если вы про SVC. Насколько нам известно, WebRTC в данный момент не поддерживает SVC, по крайней мере для кодека H.264.
      Ну и SVC имеет слабое отношение к записи стримов и воспроизведению VOD в данном контексте.

      WebRTC обычно еще преполагаеться SDP — Session Description protocol, в котором и можно указать какие потоки клиент готов принимать

      Да, в SDP, разумеется указываются потоки. В нашем случае указывается 1 видео поток.

      если клиент сообщяет что готов к 2м потокам, как в вашем случае

      Нет. В нашем случае клиент принимает 1 видеопоток. На графике разрешений показаны высота и ширина этого одного потока во время записи.

      подрозумеваеться
      что клиент будет скейлить на весь экран сам, если сервер решит переслать меньшую резолюцию

      Да, клиент будет скейлить, то, что ему прислали.

      Или же клиент сообщает что готов принимать только одну, в вашем случае 640х480, то сервер пришлет только ее!

      А вот не факт. В WebRTC, Sender динамически меняет разрешение потока, основываясь на RTCP фидбеках. См. график. Сначала разрешение, при стриминге с iOS приложения, было 640x480, потом упало до 320x240.

      Scalable Video родилось что бы сэкономить транскодинг на сервере

      Это так, но не актуально для данного конкретного случая.


      1. Barabashkad
        13.09.2017 13:35

        При этом, в файле записи mp4 мы имеем чудесные фреймы разного размера, точнее сначала последовательность одного размера 640x480, потом другого 320x240, и т.д. Такие фокусы замечательно отыгрывает например VLC

        из этого вашего описания я сделал вывод, что один и тот же записаный файл проигрывает-ся offilne с помощью VLC без зеленых областей, а тот же файл переданный по сети да с зелеными…
        из этого следует что в файле несколько потоков.
        это может быть в 2х вариантах:
        1) 2 независимых паралельных H.264 потока, можно посмотреть в МП4 и дампить оба по отдельности в 2 МП4 файла
        2) 1 поток no SVC

        Насколько нам известно, WebRTC в данный момент не поддерживает SVC, по крайней мере для кодека H.264.


        зависит от конкретной имплиментации WebRTC сервера
        да, point2point между Chrome броузером нет подежки
        но если сервер, то все прекрасно поддерживаеться

        Ну и SVC имеет слабое отношение к записи стримов и воспроизведению VOD в данном контексте.


        в данном контексте, конечно…
        но SVC не ограничен использованием в видео конференциях, это всего лишь набор инструментов кодирования, а как их использовать дело часное

        А вот не факт. В WebRTC, Sender динамически меняет разрешение потока, основываясь на RTCP фидбеках. См. график. Сначала разрешение, при стриминге с iOS приложения, было 640x480, потом упало до 320x240.


        конечно RTCP играет тут контрольную роль… НО если клиент по SDP не разрешил опускать разрешение то сервер не должен.
        правильно составить SDP еще та проблема.
        по умолчанию предполагаеться что если клиент готов принять определенный формат, то это максимальный, а значит все что меньше разрешено.
        надо отдельно указать что только и только его…

        в конечно итоге дело ваше как вы расходуете ресурсы… хотите транскодировать, кстати что ухудшает качество… и вам кажеться так проше, ваше право