Живая трансляция стерео видео в очки VR (Oculus Go)

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

    Итак, есть стерео-камера, которая может отдавать видео 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 выглядело) — пишите в личку, обсудим детали.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 2

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

    Only users with full accounts can post comments. Log in, please.