«Звонки» в iPhone-приложении Одноклассников

    В пятницу мы запустили новую версию нашего iPhone-приложения. В этом посте мы хотели бы поделиться с вами опытом разработки подобных сервисов.

    Сервис «Звонки» — видеочат на сайте Одноклассники реализован средствами Flash. Но далеко не все наши пользователи заходят на Одноклассники с компьютера/ноутбука. Чтобы расширить аудиторию видеочата, мы решили поддержать его также в смартфонах.

    В этой статье пойдет речь об опыте реализации видеозвонков в приложении для iOS.

    Схема работы приложения:



    Аудио/видео кодеры и декодеры


    Так как под iPhone можно компилировать код на C/C++, проблем с выбором кодеков не было — можно брать любой open source-кодек, при условии, что лицензия позволяет использование в коммерческих приложениях. Для звука взяли Speex, а для видео H.263 из кода ОС Android (пришлось его немного доработать для совместимости с флешом).

    Модуль захвата видео


    Начиная с версии 4.0 в iOS есть API для захвата «сырого» видео (AVCaptureSession). Но у этого API есть свои ограничения — в частности нельзя задать произвольное разрешение (поддерживаются несколько фиксированных пресетов). Также невозможно изменить ориентацию видео при повороте устройства. Для того чтобы обойти эти ограничения мы захватываем видео кадры большего размера, чем нам необходимо, а потом вырезаем и поворачиваем видео в соответствии с ориентацией устройства. Это отнимает довольно много ресурсов процессора и имеет нежелательный эффект приближения («зума»), но тут остается только сказать спасибо компании Apple за такую реализацию API.

    Видео захватывается в родном для кодеков формате YUV. В связи с этим встает проблема «отрисовки» фреймов для отображения «своей» картинки на экране. Ее мы тоже решили, но об этом позже, в разделе «Вывод видео на экран».

    Еще стоит упомянуть алгоритм выбора камеры: если у устройства есть фронтальная камера — приложение выбирает ее. Если фронтальной камеры нет, видео захватывается с камеры на задней крышке. Если же камеры нет вообще (например iPad) — кнопка «Включить видео» не отображается.

    Вывод видео на экран


    Видео декодер, равно как и модуль захвата видео с камеры, выдают кадры в формате YUV. Для того чтобы отобразить кадр на экране устройства, необходимо перевести его в формат RGB и привести к нужному размеру. Так как основной процессор занят в это время другими задачами, мы перевели эти операции на графический процессор используя OpenGL ES 2.0. Кадр в формате YUV загружается в OpenGL текстуру, после чего фрагментный шейдер пересчитывает цветовые компоненты для каждой точки. Для поддержки более старых устройств на которых не поддерживается OpenGL ES 2.0 (младше чем 3GS), в приложении есть ветвь кода, которая производит все вычисления, не используя шейдеры. На таких устройствах приходится компенсировать недостаток вычислительной мощности понижением фреймрейта видео.

    Захват и проигрывание звука


    Для захвата звука с микрофона и проигрывания через динамик используется API AudioSession — это самое низкоуровневое API, к которому возможно получить доступ из iOS приложения. Звук, который приходит от сервера, декодируется и попадает в буфер, который сглаживает «дрожание» сети. Глубина буфера меняется в зависимости от качества соединения — чем хуже сеть, тем глубже буфер. Для пользователя это проявляется тем, что на плохой сети увеличивается задержка звука.

    В iPhone есть несколько маршрутов проигрывания звука — он может проигрываться через телефонный динамик, через громкую связь (динамик на нижнем торце устройства) либо через подключенную гарнитуру. Если не подключена гарнитура — по умолчанию выбирается маршрут громкой связи. Телефонный динамик подключается при срабатывании датчика расстояния (proximity sensor).

    Многозадачность


    Начиная с 4-ой версии в iOS была добавлена поддержка многозадачности. Звонок по видеочату можно продолжать даже когда наше приложение работает в фоновом режиме. Для того чтобы максимально высвободить ресурсы при переходе в фоновый режим приложение прекращает прием и отсылку видео, а также не обновляет графический интерфейс до тех пор, пока приложение не станет опять активно. При этом продолжается захват и воспроизведение звука, а на экране сверху отображается красная «полоса» с надписью «odnoklassniki» — индикация того, что приложение «слушает» микрофон. При нажатии на эту панель приложение возвращается в активное состояние.

    Использование датчика приближения


    Датчик приближения (proximity sensor) — это датчик, установленный сверху на лицевой панели телефона, который определяет близость какого-либо предмета к устройству. Идея в том, чтобы определять, когда пользователь подносит телефон к уху. Во время видеозвонка приложение мониторит состояние этого сенсора. В случае срабатывания датчика приложение гасит экран, выключает прием и отсылку видео, и переключает звук в телефонный динамик. Это удобно для тех пользователей, которые хотят просто «по старинке» поговорить по телефону.

    Адаптирование к качеству соединения

    Видеозвонки в приложении могут использоваться как на WIFI так и на 3G/EDGE сетях. Во время звонка постоянно мониторится состояние сетевого соединения и в случае ухудшения качества связи уменьшается фреймрейт и качество видео.

    Что хотелось бы улучшить

    • Сделать возможность пользоваться остальными функциями приложения «одноклассники» во время разговора
    • Автоматическое восстановление соединения в случае обрыва (например, при переключении между сетями Wi-Fi/3G)
    • Более широко использовать оптимизации кода для процессора ARM, чтобы уменьшить загрузку процессора и разрядку батареи во время разговора.


    Будем рады услышать ваши замечания и рекомендации по улучшению сервиса.
    Команда разработчиков сервиса «Звонки».
    Одноклассники 79,45
    Делимся экспертизой
    Поделиться публикацией
    Комментарии 18
    • +13
      Мама будет довольна.
      • +2
        Ваша мама пользуется айфоном? Тогда да, надеемся она останется довольна.
        • +2
          Да, я не ради шутки это написал.Буквально неделю назад поставил ей Ваш апп.Сегодня вечером обновлю и в Вашу сторону направятся наверняка лучи признательности)
      • +6
        Круто! Мало, наверное, кто ожидал такого от одноклассников.
        • –1
          Одноклассники, как всегда, запустили классный сервис!
          • 0
            А статистика есть какая? Много народа пользуется звонками?
            • 0
              Привет, было бы интересно услышать о технических деталях реализации. Пожалуйста, напишите статью об этом.
              • +2
                Более подробную статью с техническими деталями мы писать скорее всего не соберемся, так как это большой объем работы и для большинства читателей будет неинтересно. А вот если есть более конкретные вопросы — с удовольствием ответим.
                • +1
                  Исходники выложите, это быстро.
              • 0
                Вот только юзабилити вашего приложения малость сомнительно. Все выглядит так, что во фрейме открыта обычная html-версия сайта (статус-бар от браузера подтверждает это). Я уж молчу про соблюдение гайдлайнов от эппла. Неужели нельзя было сделать что-то более нативное с использованием вашего API как пресловутый ВКонтакте?
                • +2
                  Скоро будет. Ждать осталось немного.
                • 0
                  А шрифта для заголовка побольше нет? Плохо видно.
                  • 0
                    Очень интересно, как огранизована сетевая часть — какой сервер используется для передачи видеопотоков, какие протоколы. Хотя бы в общих чертах.
                    • 0
                      Используется тот же сервер что и для звонков с веба, поэтому протокол используется совместимый с флеш сервером — RTMP.
                    • 0
                      А какая реализация RTMP используется на сервере? FCS/FMS или что-то самописное? Или сторонняя реализация?

                      Аналогичный вопрос по клиенту. Как из нативного iOS приложения работать с RTMP?
                      • 0
                        И сервер и клиент самописные.
                      • 0
                        Клиент — на ObjC? А не планируете в опенсорс выложить?
                        • 0
                          Клиент на С, код пока открывать не планируем.

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

                        Самое читаемое