Не будем делать пространную вводную часть, сразу перейдём к сути.

Итак, есть стерео-камера, которая может отдавать видео H264 по разным протоколам. Есть очки Oculus Go. Как посмотреть стерео live stream с камеры в VR очках? Желательно, с минимальной задержкой и локально, так что Youtube и прочие RTMP видеосервисы отпадают.

Забегая вперёд, вот что получилось. В начале — воспроизведение заранее записанного видеофайла со стереопи, затем воспроизведение live stream со StereoPi (MPEG-TS через UDP).


Стереокамера, которую я использую — StereoPi, так что конкретные примеры буду приводить применительно к ней. По сути, это обычная малина, но с двумя камерами, так что описанные примеры можно и на обычной малине попробовать, если очень хочется. Правда, понадобится установить прошивку от StereoPi.
Первым делом, была попытка сделать обычное приложение под Android, которое воспроизводит поток с камеры на полный экран, и залить его в окулусы методом sideloading (через adb).

После некоторых ковырянием с манифестом очки согласились считать это приложение нативным. Оно появилось в «Неизвестных источниках» в библиотеке, запускалось, показывало всё что надо, но была проблемка — движения головы не учитывались, видео с камеры просто тупо отображалось на полный экран в очках. Стерео эффект был, да, но стоило чуть подвигать головой как моск начинал сходить с ума, что вызывало весьма и весьма дискомфортные ощущения.

Если что, вот .apk приложения: StereoPi for Oculus Go Заодно в архиве и adb лежит, так что сразу можно попробовать залить в очки. Просто командуем

adb install StereoPi.apk

После этого идём в Библиотека -> Неизвестные источники, там должно появиться приложение com.virt2real.stereopi



Запускаем и, если StereoPi находится в той же локальной сети что и очки, сразу видим стерео-картинку с камеры.

Но это фигня… Хочется нормальное нативное приложение для окулусов для просмотра видео. Чтоб был неподвижный экран и чтоб не штормило при движении головой. Осваивать Unity для окулусов я пока не готов, так что появилась идея попробовать использовать уже имеющиеся в магазине Oculus приложения-видеоплееры. 3D киношки я обычно в Skybox смотрю, так что именно его я и попробовал задействовать.

Помимо обычного просмотра медиафайлов с встроенной флешки и с сетевых устройств, в Skybox нашёлся интересный пункт «Airscreen». Оказалось, можно установить приложение Skybox на комп с виндой (ну, или на Мак), скормить ему видеофайлы и тогда появляется возможность смотреть в очках эти видеофайлы. Т.е. виндовое приложение является видеосервером, а очки — клиентом. Протокол общения я нигде не нашёл, так что пришлось расчехлять tcpdump.

После непродолжительных раскопок оказалось что Skybox использует широковещательные сообщения UDP для поиска сервера в локалке. Выглядит сообщение примерно так:

{"command":"search","project":"direwolf","deviceId":"66a86b57-b292-3957-9fc9-4041d5e1f841","deviceType":"vr","udpPort":"6881"}


Все сообщения в JSON, очень удобно.

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

{"udp":true,"project":"direwolf server","command":"searchResult","deviceId":"66a86b57-b292-3957-9fc9-4041d5e1f841","computerId":"53709de962eba2f9695c8a926562486c","computerName":"STEREO-PI","ip":"192.168.1.51","ips":["192.168.1.51"],"port":6888}

Тут мы указываем свой хост и порт, на котором у нас запущен сервер WebSockets. Всё дальнейшее общение пойдёт именно через вебсокеты.

Например, первое же сообщение через вебсокеты будет примерно таким:

{"command":"addDevice","deviceId":"66a86b57-b292-3957-9fc9-4041d5e1f841","deviceName":"Oculus Pacific","deviceType":"vr","showLoginCode":true}

Отвечаем на него:

{"command":"addDevice","deviceId":"66a86b57-b292-3957-9fc9-4041d5e1f841","deviceName":"Oculus Pacific","deviceType":"vr","showLoginCode":true}

И после этого в Skybox в очках увидим нашу StereoPi. Далее будет ещё куча запросов, на которые нужно слать ответы. Содержимое плейлиста, например.

Пример плейлиста для Skybox
[ { id: 'livestream-rtsp',
name: 'Live Stream RTSP',
duration: 0,
size: 0,
url: 'rtsp://192.168.1.51:554/h264',
thumbnail: 'http://192.168.1.51/thumbnail/livestream.png',
thumbnailWidth: 186,
thumbnailHeight: 120,
lastModified: 1,
defaultVRSetting: 1,
userVRSetting: 2,
width: 1280,
height: 720,
orientDegree: '0',
subtitles: [],
ratioTypeFor2DScreen: 'default',
rotationFor2DScreen: 0,
exists: true,
isBadMedia: false,
addedTime: 1 },
{ id: 'livestream-mpegts',
name: 'Live Stream MPEG-TS',
duration: 0,
size: 0,
url: 'udp://@:3001',
thumbnail: 'http://192.168.1.51/thumbnail/livestream.png',
thumbnailWidth: 186,
thumbnailHeight: 120,
lastModified: 1,
defaultVRSetting: 1,
userVRSetting: 2,
width: 1280,
height: 720,
orientDegree: '0',
subtitles: [],
ratioTypeFor2DScreen: 'default',
rotationFor2DScreen: 0,
exists: true,
isBadMedia: false,
addedTime: 1 } ]

Это особенно интересно, т.к. в плейлисте, который формирует виндовое приложение, обнаружилась заветная аббревиатура RTSP. Оказалось, приложение-сервер стримит видеофайлы через RTSP, что уже подходит для живого стриминга видео, который нам, собссно, нужен. Точнее, оказалось что «RTSP» в плейлисте есть, но ссылки на видеофайлы обычные http. Т.е. приложение-сервер всё-таки отдаёт файлы по HTTP, а это нам не подходит. На этом моменте я уже было расстроился, но подумал, почему бы не попробовать дать в плейлисте ссылку в формате в которым обычно VLC понимает, т.е. rtsp://192.168.1.51:554/h264 И ура, Skybox стал воспроизводить видеопоток с RTSP сервера на стереопишке. Задержка очень большая, секунд 20, так что ковыряем дальше. Пробуем скормить UDP поток в MPEG-TS. Опять же, VLC это кушает обычно по ссылке udp://@:3001, для Skybox я попробовал аналогично указать. Затем осталось лишь направить MPEG-TS поток на хост очков и указанный UDP порт. Для этого задействован GStreamer:

raspivid -3d sbs -w 1280 -h 720 -o - | gst-launch-1.0 -q fdsrc ! h264parse ! mpegtsmux alignment=7 name=muxer ! rndbuffersize max=1316 min=1316 ! multiudpsink clients="192.168.1.60:3001" sync=false

Кликаем в скайбоксе на элемент плейлиста «Live Stream MPEG-TS» и вуаля, видим живой поток MPEG-TS на большом экране в виртуальном кинотеатре. Задержка намного меньше чем при RTSP, 2-3 секунды, но всё равно намного больше чем в моём простеньком приложении, которое сырой H264 поток по UDP принимает (там задержка обычно 100-150 мс при 720p разрешении).

Тут я упёрся в тупик, снизить задержку пока никак не удаётся. Возможно, нужно отключать буферизацию в самом Skybox, попробую разработчикам написать, может сделают опцию «Disable buffering» :-)

В заключение


В общем, если вдруг вам зачем-то вдруг понадобилось смотреть живой видеопоток в окулусах или других очках VR (Skybox доступен на многих платформах вроде) — можете попробовать описанный мною метод. Я не знаю, прокатит ли это с другими стерео-камерами, но со StereoPi проверено, пашет.

Ссылки


Исходники сервера для скайбокса
Ветка на форуме с обсуждением

Всем спасибо, все свободны.

Ах да, чуть не забыл. Если вдруг кто может помочь с нативным приложением под окулусы (чтоб примерно как Skybox выглядело) — пишите в личку, обсудим детали.

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


  1. Nick_Maverick
    16.05.2019 14:30

    есть под Google Cardboard такое


    1. Gol Автор
      17.05.2019 08:44

      Cardboard на обычной мобиле, для этого у меня уже есть приложение play.google.com/store/apps/details?id=com.virt2real.stereopi
      А хотелось именно в окулусах сделать показ живого стерео-видео.