Камера историй ВКонтакте

15 августа на VK Tech Talks | Android разработчик Олег Смирнов рассказал о видеоисториях, а именно о создании видеозаписи с эффектом Ping Pong — двухсекундным видео без звука, которое проигрывается вперёд-обратно несколько раз подряд.

Запись видео

1. Записываем простое видео

Чтобы разобрать что-то сложное, нужно начать с чего-то простого. Как же реализовать запись видео?

В Android есть три класса, позволяющие работать с видео: Camera, SurfaceView и MediaRecorder.

Камера историй ВКонтакте, image #1

При помощи SurfaceView создаём основной блок, затем создаем камеру и сообщаем ей, чтобы она рисовала в SurfaceView. Теперь мы видим изображение.

Камера историй ВКонтакте, image #2

Далее создаём MediaRecorder, показываем ему камеру и задаем настройки: запись звука будет идти прямо с микрофона, а видео — с камеры. Далее указываем, в какой файл будет вестись непосредственно запись.

Камера историй ВКонтакте, image #3

Осталось настроить качество видео. Из настроек Android возьмём 720p и начнём запись.

Готово! Видео сделано, и его можно вставлять куда душе угодно. Но что делать с функциональностью такого рода?

Камера историй ВКонтакте, image #4

В этой ситуации при помощи нейросети на лицо накладывается виртуальная маска. В разобранном примере мы обращались непосредственно к системе, а тут нужно найти лицо, что-то обработать. Одним словом — сложно.

Наша задача — создать Ping Pong видео.

Реализация Ping Pong

2. Создаём видеоэффект Ping Pong

Вначале получим видеокадры.

Камера историй ВКонтакте, image #5

Задаём размер выходных данных, вычисляемый как 1280 × 720 × 12 / 8.

Если с 1280 × 720 всё понятно — задаётся качество 720p, то что же означает 12 × 8? Олег подробно объяснил.

Камера историй ВКонтакте, image #6

Существует такой формат хранения пикселей в памяти — NV21, один из подформатов YUV. Почему же используется YUV, а не привычный всем RGB?

Камера историй ВКонтакте, image #7

Как известно, пиксель на экране состоит из трёх цветов: красного, зелёного и синего. При смешивании они создают любой другой цвет.

Глаз работает так, что яркостную составляющую он воспринимает намного лучше, чем цветовую. При помощи формул RGB разбили на яркостную и два цветоразностных компонента.

В формате RGB каждый цвет занимает 1 байт, то есть чтобы сохранить пиксель, нам потребуется 3 байта. А в формате YUV пиксели группируются по 4, и храним две общие цветоразностные составляющие, отдельно от каждого из них их яркостную составляющую. Все форматы видео работают с форматом YUV и это никак не влияет на качество.

Камера историй ВКонтакте, image #8

Проведём подсчёты: один пиксель в RGB формате займёт 24 бита, а один пиксель формата YUV — 12 бит. Только основываясь на том, что яркость человеческий глаз воспринимает лучше, чем цвет, мы экономим половину памяти.

Камера историй ВКонтакте, image #9

После всего этого мы выделяем callback камере, куда будут присылаться фреймы.

Камера историй ВКонтакте, image #10

Камере выставляется превью callback, куда в массив ByteArray попадает сырой кадр.

На этом этапе этапе с полученной информацией можно уже что-то сделать: распознать QR-код, наложить маску, проделать множество других действий, однако нас интересует только сохранение кадров.

Хранение кадров

Рабочие данные
Рабочие данные

Чтобы создать эффект пинг-понга, мы воспользуемся классом MemoryFile. Благодаря ему все данные по возможности сохраняются в памяти, а если её не хватает он скидывает их на диск. Работает он в памяти системы.

Камера историй ВКонтакте, image #12

3. Запись кадров в файл

Файлы нужно сжать при помощи кодека. Для справки: 12 секунд несжатого видео будут занимать 400 Мб памяти, а сжатого — 4 Мб.

Для работы с кодеком операционная система предоставляет нам два класса — MediaCodec и MediaMuxer.

MediaCodec — интерфейс для всех кодеков, которые есть в операционной системе. С его помощью можно создать любой кодек для сжатия видео или аудио.

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

Напишем энкодер. Работать будем с кодеком H.264.

Камера историй ВКонтакте, image #13

Далее настроим качество видео, битрейт и фреймрейт, настроим цифровой формат: YUV — это важно, тут мы работаем в том же цифровом формате, что и с камерой.

Камера историй ВКонтакте, image #14

Затем создаём кодек с перечисленными настройками.

Камера историй ВКонтакте, image #15

Следующим шагом создаём MediaMuxer.

Также нужно добавить один трек, так как пинг-понг — видео без звука. Если бы мы работали со звуком, мы бы добавили второй трек.

Формат выходного контейнера — MP4.

Камера историй ВКонтакте, image #16

Теперь мы подошли к основному циклу.

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

Камера историй ВКонтакте, image #17

Разберём более детально сам цикл. Он повторяется три раза. Ровно столько повторений у пинг-понга.

Создаём условие: в какую сторону мы идём? Если в прямом направлении — то индексы увеличиваются, а если в обратную — индексы уменьшаются, и в любом случае берём из массива один кадр.

Камера историй ВКонтакте, image #18

Дальше подключаем функцию dequeInputBuffer, которая синхронно возвращает буфер, но она может вернуть отрицательный индекс в том случае, когда энкодер чем-то занят.

Получаем индекс и буфер.

Камера историй ВКонтакте, image #19

Далее копируем все кадры из YUV, вычисляем время.

Камера историй ВКонтакте, image #20

Одной из главных функций является сжатие кадра. Этим займётся энкодер.

Камера историй ВКонтакте, image #21

Затем нужно дождаться когда энкодер вернёт сжатый кадр. В этом поможет функция dequeOutputBuffer.

Камера историй ВКонтакте, image #22

Далее сообщаем муксеру, чтобы тот записал сжатые данные в файл и освобождаем энкодер. Выполняем цикл трижды. Готово!

Камера историй ВКонтакте, image #23

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

Камера историй ВКонтакте, image #24

Спасибо за прочтение! Запись выступления можно посмотреть ниже.

Камера историй ВКонтакте, image #25

The Brown Room — независимое интернет-издание про социальные сети и современные технологии

Автор: Илья Филиппов
Корректор: Арсений Метелев
Слайды и данные: VK Tech / Олег Смирнов

992 views·3 shares