WebRTC стриминг в виртуальной реальности и вокруг нее

jwqov9cav_juhuolm3cwf8xm-aw.jpeg

Виртуальная реальность нынче на пике моды. Оборудование, что во времена «Газонокосильщика» было уделом сумасшедших ученых гиков с большими деньгами от Минобороны, сейчас и простому человеку по карману, а те, у кого карман совсем пуст, могут собрать VR-гарнитуру из картона и смартфона по множеству рецептов.

И пользы VR может принести гораздо больше. чем 3–4–5–6–7-далее-по-вкусу-D кинотеатр. Допустим, Вы проживаете в Москве и хотите вложить честно заработанные ресурсы в самую твердую из валют — недвижимость где-нибудь на берегу Средиземного моря. Как известно, выбирать жилье лучше на месте и самостоятельно, но что, если Вы не можете уделить этому достаточно времени? Вот здесь и нужна виртуальная реальность. Представьте: агент устанавливает специальную камеру в комнате, и Вы, не сходя с любимого кресла, можете эту комнату осмотреть, покрутить головой и даже на потолок с плафоном 18 века «Греческие боги предаются разврату отдохновению» глянуть!

Затем, все так же не сходя с места, Вы интересуетесь, а чему же предаются Ваши чада в детском саду? И снова: камера в игровой комнате, и Вы с эффектом присутствия можете осмотреть все углы, куда Ваши чада расставлены прячутся.

Ну, а мы разберемся, как сделать, чтобы в подобных случаях все работало, и риэлтеры дети не успели разбежаться.


Нюансы VR-картинки

«Василий Иванович, объясните, что же такое нюанс?»
«Видите ли, Петр…»
Из диалога двух выдающихся джентльменов

Технически, VR-медиапоток не отличается от обыкновенного: дорожка видео плюс дорожка аудио. Но есть нюанс.

VR-поток предполагает стерео-картинку. Специальная камера смотрит в мир двумя широко, на 180 градусов, открытыми глазами объективами, примерно, как этот робот

yvwqgcgjjnblruhtjnhduw3_xwq.jpeg

картинки склеиваются в один кадр,

otmnli2-vsrodo4wcjplsdmuw50.png

поэтому на устройстве зрителя должен работать специальный плеер, который из двух картинок сделает одну. Как видно, соотношение сторон кадра составляет 2:1, по FullHD картинке на каждый глаз.


Нюансы VR-трансляции

Да-да-да, могу все мели
Счесть, как пальцы на руке
Песенка из классического кино

Итак, речь идет о трансляции 4K потоков с высоким битрейтом. Что у нас есть? А есть у нас RTMP и WebRTC.

RTMP — дешево, надежно и практично. Под капотом использует TCP, что полезно при не очень хороших каналах. Есть разнообразные программные решения для публикующего клиента, как платные, так и бесплатные. Но, при всех достоинствах, RTMP дает высокие задержки. В одной из предыдущих статей мы отмечали задержку в 2–3 секунды для потока 720p. В каких-то случаях задержки приемлемы, но виртуальность будет уже немного отставать от реальности, и дети уже успеют разбежаться.

WebRTC — стильно, модно, молодежно. При хороших каналах задержки измеряются миллисекундами, реальность останется реальностью. Но есть нюансы.

Во-первых, по умолчанию WebRTC бегает поверх UDP, что при малейших ухудшениях качества канала приводит к потерям. А для 4K потока любой чих на канале — уже ухудшение. С этим можно справиться, перейдя на TCP транспорт, но дальше нас подстерегает…

Во-вторых, WebRTC транслируется из браузера, а мы с вами знаем, какой браузер сейчас самый популярный на планете (спойлер — давно не IE6). И в этом популярном браузере, причем на уровне движка, зашит максимальный битрейт публикации 2500 кбит/с. Этого вполне достаточно по мнению Google для FullHD, но маловато для 4K, и если битрейт не разогнать до 5 — 10 Мбит/с, зрители увидят вместо виртуальной реальности движущиеся акварельные пятна. К счастью, есть специальные настройки для разгона битрейта, которые работают во всех большинстве браузеров на движке Chromium. Затем, преодолев это препятствие, мы упремся…

В третьих, мы упремся в пропускную способность каналов. Чтобы публиковать и играть VR-картинку, при упомянутом выше битрейте клиенту потребуются каналы от 20 Мбит, а лучше от 50, а еще лучше от 100 Мбит, причем в обе стороны — и на загрузку, и на выгрузку. Причем это должны быть не те параметры, о которых рассказывает провайдер в рекламных буклетах, а реальная пропускная способность от клиента до сервера. Кстати, здесь можно прочитать, как ее можно измерить без iperf и знания командной строки. На стороне сервера, таким образом, желательно иметь 10 Гбит, если рассчитывать на большое количество потоков.

Ну и в четвертых, что следует из требований к каналам. Транскодирование 4K потока займет слишком много ресурсов процессора на сервере. Поэтому нужно либо выбирать царь-сервер, что накладно по бюджету, либо использовать кодирование на видеокартах, что также весьма затратно, либо избегать транскодирования. То есть ни в коем случае не менять разрешение, частоту кадров и битрейт потоков при трансляции.

Итак, все мели сочтены, теперь


Давайте попробуем

Что тут думать, трясти надо!
Персонаж из детского мультика

Возьмем:

Устанавливаем камеру на столе или штативе

q-botwt5-af0pl19umr-zphiez0.jpeg

Подключаем к ПК по USB 3.0 с питанием 1A, как для внешних дисков

kh4pbpwvvpvceliez14mgn0ocjc.jpeg

Надо сказать, камера весьма чувствительна к оборудованию, и если на ноутбуке 2 порта USB 3.0, с одним из них она вполне может отказаться работать. Кабель для подключения также должен быть не совсем китайским, все пины, предусмотренные стандартом, должны быть на месте. И даже при идеальном подключении, камера может выдавать помеху, как старый пузатый телевизор в грозу. Зато для Windows 10 драйверов не требуется, честный Plug-n-Play.

На стороне сервера установим необходимые границы битрейта

webrtc_cc_min_bitrate=5000000
webrtc_cc_max_bitrate=10000000

Откроем в браузере Chrome страницу примера, позволяющего выставить нужные параметры для захвата потока с камеры, и установим


  • разрешение 3072×1536
  • FPS 24 (при трансляции из браузера камера поддерживает только такой FPS)
  • транспорт TCP

и настроим параметры SDP для того, чтобы браузер не резал нам осетра битрейт, на стороне клиента

x-google-max-bitrate=10000;x-google-min-bitrate=5000

или на стороне сервера (в этом случае настройки будут действовать для всех публикующих клиентов)

webrtc_sdp_min_bitrate_bps=5000000
webrtc_sdp_max_bitrate_bps=10000000

ae6zr7vxhkeeh65bp144sjklxfg.png

Опубликуем поток с камеры

hq-rhunttdvkc4cff_o9uurcbec.png

Теперь попробуем проиграть поток обычным WebRTC плеером

otmnli2-vsrodo4wcjplsdmuw50.png

Все хорошо… Почти. Виртуальность какая-то не совсем виртуальная. Что ж, теперь играем этот же поток в специальном плеере, внедренном на страницу

ijkim-0dccwdgyeccgirdcusgec.png

Так гораздо лучше (и котики есть). Если играть поток на мобильном устройстве или в VR-очках, можно покрутить головой, а мы в браузере на ПК покрутим мышкой. Где-то в этой комнате спрятался ребенок. Посмотрим налево

gcdmdflghc1jm1wxnleffttk-he.png

Теперь направо

ctiyglkgyc2wb987mj6pzpgqdji.png

И вверх

ndj83milhj9weql0x1ifufccuou.png

А где же малыш? Да вот он, за шторкой прячется. Но котик все видит!


Кода, нужно больше кода!

На стороне клиента кода немного.

Публикуем поток со страницы браузера

session.createStream({
    name: streamName,
    display: localVideo,
    cacheLocalResources: true,
    transport: "TCP",
    sdpHook: rewriteSdp,
    constraints: {
        audio:true,
        video: {
            width: 3072,
            height: 1536,
            frameRate: 24
        }
    }
}).publish();

Функция замены параметров SDP браузера

function rewriteSdp(sdp) {
    var sdpStringFind = "a=fmtp:(.*) (.*)";
    var sdpStringReplace = "a=fmtp:$1 $2;x-google-max-bitrate=10000;x-google-min-bitrate=5000";
    var newSDP = sdp.sdpString.toString();
    newSDP = newSDP.replace(new RegExp(sdpStringFind,"g"), sdpStringReplace);
    return newSDP;
}

Пример страницы с VR-плеером



    
        WebRTC Delight
        
        
           
           
           
           
        
    
           
        
\

Обычно при создании стрима для плеера (вызов session.createStream()) мы передаем div-элемент, в который будет вмонтирован video-элемент для воспроизведения стрима по WebRTC. Но VR-плеер использует свой video-элемент, и нам нужно каким-то образом пробросить его в код используемого API. Для этого мы напрямую передаем video-элемент стороннего плеера в функцию session.createStream () параметром remoteVideo

В качестве серверной части используется demo.flashphoner.com, примеры веб-приложений доступны в подвале по ссылкам.

Удачи в осмотре на месте, не сходя с места!


Ссылки


  1. Индикатор качества канала серверного WebRTC через TCP — Контроль качества каналов от клиента до сервера
  2. Видеотрансляции с веб-камеры браузера или мобильного устройства — WebRTC стриминг из браузера
  3. Документация по использованию WCS совместно с VR-плеером
  4. WCS — сервер для передачи VR 360 видео по WebRTC

© Habrahabr.ru