«Боль» девелопера — воплощать идею без единого референса на старте. Когда под рукой нет примера технического решения, миссия кажется невыполнимой. С похожей ситуацией столкнулась команда NIX.
Работа над проектом Vuze Camera Remote Control App помогла девелоперам прокачать скиллы, проявить новаторство в нескольких решениях и послужила материалом сразу двух докладов на NIXMultiConf. Ссылками с подробностями делимся ниже. А пока — подробнее о челленджах команды.
Требовалось создать приложение под девайс с двумя камерами — Vuze Camera. Клиент — компания-лидер в области 3D, computer vision и обработки изображений с более чем 70 патентами. Забегая наперед, с задачей ребята справились. Vuze Camera Remote Control App позволяет снимать, стримить и редактировать 3D/VR-видео. Практически во всех задачах команда стала первопроходцем. Среди основных:
- создать мобильный 3D видеоредактор для 4к и 5.7к контента, снятого в формате 360°;
- запустить многочисленные опции для пользователя: фильтры, стабилизацию, трекинг объекта в видео 360° или в стандартном 2D, анимацию, эффекты, вроде Little Planet и другие;
- внедрить режимы Cardboard и VR;
- дать пользователю удаленный доступ и возможность редактировать видео «на лету» с высоким разрешением.
Вдобавок — обновить прошивку девайса и обеспечить надежное соединение нового приложения с камерой. По идее, пользователь контролировал бы устройство даже в самых экстремальных условиях. Например, при съемке на горнолыжном спуске, под водой или в воздухе. У камеры есть кейс для таких съемок.
Технологии: Swift, Objective-C, OpenGL, CoreML, Vision, AVFoundation, ProtoBuf, PromiseKit, C++, JNI, FFmpeg, EGL, OpenCv, boost, NDK, Kotlin, Java, GVR, FreeType, glm, libyuv, XMP, Crashlytics.
Команда: Project Manager, Business Analyst, трое C++ Developers, пятеро iOS Developers, четверо Android Developers, трое QA Engineer.
Настроили съемку видео 360°
На момент запуска проекта было мало качественных камер, снимающих видео 360°. Соответственно, не хватало плееров с поддержкой такого формата. Примером послужила SDK от Google, ориентированная на продукт Google Cardboard — VR-шлем, поддерживающий соответствующую функцию. Для пилотного проекта NIX взяли эту SDK и показали, что с видео можно поиграть как в 3D, так и полным кадром с применением эквиректангулярной проекции.
Далее команде предстояла разработка множества новых фич по обработке фото и видео. Вот тогда и начались первые сложности.
Подключили мощный редактор с функцией Little Planet
Стандартный в таких ситуациях GPUImage отбросили из-за недостаточной гибкости. Библиотека фиксировала порядок применения эффектов — все должно было происходить до даунскейла и вывода на экран. Когда речь идет о видео 4к, а в будущем предполагается и 5к — это кажется не очень удачной затеей. К тому же, были опасения, что зафиксированный конвейер GPUImage может стать причиной проблем при проигрывании стрима с камеры в разных режимах. Помните, у нас же еще и две камеры. Требовалось не только воспроизводить видео, но и выполнить ститчинг и по необходимости стабилизировать картинку.
Стало понятно, что для обработки контента придется использовать OpenGL самостоятельно. Девелоперы уже имели дело с 3D и OpenGL, но этот опыт был довольно простым: показать картинку/модельку, применить фильтр/шейдер. Для нынешней задачи этого оказалось недостаточно, и вот почему.
Особенность всех редакторов — потоковость — последовательное применение эффектов и других трансформаций с возможностью менять очередность, включать/выключать определенные звенья. Разработчики же знали только, как рендерить кадр с каким-либо эффектом прямиком на экран и только туда. Победить это ограничение помог FBO — расширение OpenGL для внеэкранной отрисовки. Ок, узнать об этом, конечно, круто, но еще нужно понять и правильно применить этот механизм. Это оказалось настоящим вызовом, учитывая то, как нелегко его дебажить. Вроде бы знаешь, что все должно заработать, но этого не происходит.
Одной из важных фич был режим Little Planet — популярный фото/видео эффект, когда линия горизонта сворачивается в круг и получается маленькая планета. Для реализации такой функции используется пиксельный шейдер. Но впереди 5к и множество фильтров. Такой подход будет лишь расходовать ресурсы iPhone на каждом пикселе для геометрической трансформации. В итоге использовали трансформацию матрицы вида и получили такой же эффект. Решение стало максимально производительным и довольно уникальным. В интернете на тот момент ничего подобного не было.
Экспорт видео и «потрясающие» метаданные
Вы можете настроить редактирование видео в рантайме, использовать FBO, легко запилить Little Planet и радоваться жизни… Пока не придет время сохранить результат. Оказалось, это еще ничего не значит. То, что происходит на экране, остается на экране. Нам повезло, что был фреймворк AVFoundation, при котором отпала необходимость в энкодинге видео. AVFoundaiton сам это делал, используя видеокарту (где-то заплакал Android-разработчик). Разобравшись с экспортом видео с помощью OpenGL композитора, команда выяснила, что текущая архитектура не совсем подходит. Появилось еще одно рендер флоу уже для экспорта. Но после рефакторинга удалось объединить в один поток все, что касается рендеринга.
Главным препятствием в экспорте стали метаданные. Если запустить «правильное» видео 360° в Youtube, оно откроется в специальном плеере. Там его можно крутить во все стороны и использовать Google Cardboard. В этом случае видео отображалось во весь кадр с equirectangular искажениями. Ни AVFoundation, ни UIKit/CoreImage ничего об этом не знали. Вернее, они готовы записать определенную метадату, но что именно и куда — решать юзеру. Более того, AVFoundation мог записывать только iTunes-подобную метадату. Пришлось разбираться, что же это за 3D метадата. Инсайты стали основой доклада экспертов NIX на мультиконференции.
Загрузка файлов — почему так медленно и что делать?
Известно, что платформа iOS предоставляет более законченные и удобные решения, нежели Android, Причем, и для пользователей, и для разработчиков. И как же было сложно команде принять тот факт, что скачивание видеофайла с камеры на Android девайс гораздо быстрее, чем на iPhone.
Вначале казалось, что это просто режим по умолчанию, более безопасный, а будет «пара» свободных часов — команда и скорость подтянет, и приоритеты установит. Реальность оказалось жестокой — никакими настройками URLSession не удавалось поднять скорость. Выход нашли в распараллеливании доступа к частям ресурса. Решение позволило достигнуть такой же скорости скачивания, как на Android.
Трекинг объекта в 3D
Новым программным решениям нужны соответствующие технологии. Для 3D-видео одно из таких средств — слежение за объектом или областью (object tracking). В данном случае кадр целиком охватывает среду, поэтому следить за объектом логично, используя весь кадр. Для этого применили фреймворк Vision. Пользователь находится в режиме 3D — видит часть кадра и «поворачивается» вслед за объектом. Думали, все сработало, но не тут-то было.
Объект переходил из одного края кадра в другой подобно сфере. Для трекера это было потерей — за движением надо было следить. Он плохо отрабатывал верхние и нижние позиции кадра, где усиливались проекционные искажения. Также на вход трекера поступал кадр с разрешением в 4к, что уже казалось избыточным. Поэтому в следующей версии команда перешла к «вьюпорт» трекеру. Теперь трекер получал картинку, которую видит пользователь. Таким образом объект трекинга всегда был в центре кадра с минимально возможными искажениями. Размер кадра оказался гораздо меньше (а точнее — равным разрешению экрана). В целом получилось существенно улучшить трекинг.
Карта глубины и очередная борьба с метадатой
Одно из преимуществ режима 180° — создание карты глубины на основе различий кадров из двух камер. То, что известно в смартфонах как режим «Портрет» — «из коробки» — команда решила реализовать самостоятельно. Пришлось углубиться в алгоритмы компьютерного зрения OpenCV. Как и в случае с OpenGL, в интернете готовых решений практически не было, а то, что попадалось — работало не так.
Команда переключилась на использование карты глубины. Распространенный эффект — Facebook 3D фото. Но как ему передать нашу карту? Оказалось, совсем непросто. Facebook хотел видеть только «Портреты», снятые в соответствующем режиме на iPhone. Выяснили, что дело в метадате, но как ее сделать? iOS SDK позволяет менять метадату с картой глубины, которая уже есть в фото. Как создать ее с нуля — никаких идей. Вновь погрузились в метадату портретных фото и разбирались, что же такого волшебного в ней есть, что iOS не дает сделать ее заново. Подробностями исследования команда поделилась на еще одной NIX конференции.
В результате NIX разработали приложение с популярными функциями — созданием 2D-видео из 3D-кадров и материала в формате 360°. Просматривать файлы можно в режимах Cardboard или Little Planet. И даже выходить в прямой эфир на YouTube или Facebook. Художественные фильтры, корректировка цвета и добавление звука — далеко не единственные фичи мощного видеоредактора.
Также пользователи могут:
- выбирать разрешение для фото — 18MP, для видео — 4K/30fps, 4K/60fps или 5.7K/30fps;
- стабилизировать видео и снимать в формате, совместимом с Google VR 180;
- просматривать файлы или лайв-превью с помощью VR очков;
- стримить видео с динамическим изменением качества и использовать смартфон как промежуточную ссылку.
Как видите, даже отсутствие реальных примеров — не помеха в воплощении сложных идей. Пусть этот пошаговый разбор вдохновит остальных на успешные разработки в 3D/VR технологиях.