Live Streaming on iOS

В нашей работе нередко возникает необходимость реализовать отправку видеопотока с iOS-устройства в реальном – или близком к реальному – времени. Самый частый пример — использование iOS-устройства в качестве камеры слежения или создание стриминговых приложений наподобие Periscope. Как правило, при возникновении подобной задачи ставятся дополнительные условия — например, возможность проигрывания потока на другом устройстве (или в другом приложении) без возникновения лишних проблем в браузере или VLC-плеере, малые задержки (видеопоток должен транслироваться практически в режиме реального времени), низкая нагрузка на устройство (возможность длительной работы от батареи), отсутствие необходимости в специализированном медиасервере для обслуживания передачи потока, и т.п.

Подобная задача сама по себе не нова, но до сих пор не имеет однозначного решения. Точнее, она имеет целый спектр возможных решений:

  • HTTP Live Streaming (HLS)
  • HTTP Dynamic Streaming (HDS)
  • MPEG-DASH
  • fragmented MP4 (fMP4)
  • RTSP
  • WebRTC
  • и т.д.

Каждый подход обладает со своими плюсами и минусами. Например, в одной из наших прошлых, но не потерявшей актуальность, статье Реализация лайв-стриминга снимаемого видео в приложении для iOS, мы рассмотрели возможность генерации на устройстве готового HLS-потока. Это позволяет в принципе избавиться от необходимости в медиасервере, и сразу загружать контент в CDN (например, Amazon S3 + CloudFront). Однако такой, основанный на HLS, подход изначально имеет недостатки (о которых мы расскажем ниже), поэтому в этот раз мы предлагаем вам два новых варианта – генерацию на устройстве готового FMP4-потока и генерацию RTP-стрима с поддержкой локального RTSP-сервера.

HTTP Live Streaming

Протокол HLS появился в 2009 году и довольно быстро добился неплохой популярности. Этому способствовала его полная поддержка в экосистеме Apple и довольно понятная структура – есть текстовый мастер-файл, содержащий список ссылок на кусочки видеопотока, которые постоянно добавляются (в случае online-трансляции). В HLS также была предусмотрена возможность определять сразу несколько потоков для клиентов с разными требованиями к видео (быстрый канал/медленный канал и т.п.). Однако на практике такая двухступенчатая система и необходимость обновлять «мастер-файл» ограничивает сферу применения HLS. Как показывает практика, HLS слабо приспособлен для трансляций в режиме реального времени из-за следующих проблем:

  1. Трансляция нарезается на отдельные файлы небольшой длины (рекомендуется несколько секунд), в результате чего отставание трансляции от режима реального времени заложено в самой идее подобной «нарезки».
  2. При этом стандартная рекомендация по буферизации в видеоплеерах – наличие, как минимум, трех буферизованных сегментов, то есть на уровне плеера задержка из пункта 1 будет утроена;
  3. Кроме того, чтобы плеер узнал о появлении новых сегментов трансляции, ему необходимо регулярно перезапрашивать мастер-файл, что создает еще один фактор задержки (не обновив мастер-файл, плеер попросту не знает, что воспроизводить дальше).
  4. Каждый сегмент (chunk) образован как MPEG-TS файл, что означает существенный оверхед к основному медиаконтенту.

Для уменьшения задержек в HLS вполне естественно уменьшать размеры сегментов до минимума (1 секунда). Однако с такими маленькими размерами файлов на первый план выходят естественные нестабильности в работе сети. И в средних, «естественных» условиях добиться плавности воспроизведения практически невозможно — плеер больше оказывается занят перезапросами мастер-файла и очередного сегмента, чем показом видеопотока.

В попытке решить эти проблемы в 2011-2012 годах были предложены аналогичные подходы – MPEG-DASH от MPEG, Smooth Streaming от Microsoft и HDS от Adobe. Но ни одно из них не стало «стандартом де-факто» (хотя из этих трех MPEG-DASH является полноценным стандартом ISO) и на детальном уровне эти решения страдали теми же недостатками, а решения Adobe и Microsoft требовали, к тому же, особой поддержки на стороне сервера. Тут можно посмотреть таблицу сравнения между этими форматами.

Fragmented MP4

Время шло, и в итоге для простой организации трансляций приобрел популярность несколько другой подход – fMP4 (fragmented MP4). Это было небольшое (но существенное) расширение известного и хорошо поддерживаемого формата MP4, который уже тогда воспроизводился практически везде, поэтому широкая поддержка fMP4 тоже не заставила себя ждать.

Вся разница между обычным файлом MP4 и fMP4 заключается в расположении элементов, описывающих видео- и аудиостримы. В обычном MP4-файле подобные элементы расположены в конце, а в fMP4 – в начале. И так как MP4 изначально мог содержать несколько стримов, поделенных на отдельные блоки данных, – то это несложное изменение позволило создать “бесконечный файл” с точки зрения плеера.

Именно этим свойством fMP4 и пользуются при лайв-стриминге. Плеер, прочитав описание видео- или аудиопотока, начинает ждать данные и показывать (проигрывать) их по мере поступления. И если блоки с кадрами генерировать на лету, плеер автоматически будет проигрывать realtime-стрим без дополнительных усилий.

И это действительно работает! Конечно, при реализации генератора fMP4 могут возникнуть некоторые проблемы. Давайте рассмотрим их на конкретном примере – приложении DemoFMP4.

fMP4 Live Streaming on iOS

Это демонстрационное приложение берет кадры с камеры и отправляет в виде fMP4 любому зрителю, подключившемуся к устройству. Для подключения достаточно запросить у устройства виртуальный файл “MP4”, который устройство будет автоматически генерировать по адресу: http://<ip-адрес>:7000/index.mp4.
Для этого приложение запускает небольшой web-сервер на базе GCDWebServer, который слушает порт 7000 и отвечает на запросы на загрузку файла index.mp4.

Здесь есть ряд проблем, с которыми можно столкнуться.

  1. Во-первых, видеокамера выдает “сырые” кадры, которые нельзя просто так отправить плееру — они должны быть сжаты и собраны в правильном формате. К счастью, начиная с версии iOS 8.0, компания Apple открыла программный доступ к аппаратному сжатию видео, которое умеет генерировать H.264-блоки на лету. Для этого используются семейства функций VTCompressionSessionCreate и VTCompressionSessionEncodeFrame из фреймворка VideoToolbox.
    1. Аналогично сжимается и аудио   функциями семейства AudioConverterNewSpecific / AudioConverterFillComplexBuffer из фреймворка AudoToolbox — в результате чего мы
      получаем блоки данных в формате AAC.
  2. Во-вторых, камера выдает кадры с довольно высокой скоростью. Чтобы не терять их, мы сохраняем кадры в кольцевых буферах (CBCircularData), из которых блоки кадров по мере заполнения отправляются на сжатие. Эти же кольцевые буфера используются для генерации chunked-ответа, поэтому приложение не хранит в памяти больше наперед заданного числа кадров (иначе для бесконечной трансляции потребовался бы бесконечный объем памяти).
  3. В третьих, для корректной работы fMP4 необходимо правильно устанавливать начальные данные потока (включая Sps/Pps) в блоке moov MP4-файла. Для этого приложение просматривает H.264-блоки, которые генерирует hardware-кодировщик, находит очередной ключевой кадр и вытаскивает значения Sps/Pps. А при генерации moov-заголовка использует их, чтобы заставить плеер отсчитывать поток от правильного момента во времени. Таким образом, с точки зрения плеера файл всегда показывается “с самого начала”.
  4. Есть еще одна проблема — формат MP4 имеет свои требования к данным, и не может включать в себя блоки H.264 без правильного оформления. Мы решили эту проблему, подключив замечательную библиотеку Bento4, которая позволяет перепаковывать блоки H.264 в корректные MP4-atoms на лету.

flowchart-livestreaming-ru
Таким образом у нас получилось приложение, способное транслировать стрим с видеокамеры устройства практически без задержек, в реальном времени, отправляя “бесконечный MP4 файл” любому стандартному HTTP-клиенту. Такой подход дает довольно небольшое отставание: 1-2 секунды. В сочетании с широкой поддержкой fMP4 и простотой организации подобной трансляции (не требуется отдельный сервер) – генерация fMP4 на клиенте становится простым и надежным решением.

True Real-Time Live Streaming

Однако как быть, если нам нужен “настоящий реалтайм”, как в Skype? Для таких ситуаций fMP4, увы, уже не очень подходит. Несмотря на отсутствие мастер-файла (как в HLS) и небольшие размеры блоков, на которые делится видеопоток, эти блоки все еще присутствуют внутри MP4-файла. И пока такой блок не будет собран целиком, клиент никак не сможет получить кадры, что неизбежно создаст небольшую задержку при воспроизведении.

RTSP Live Streaming on iOS

Поэтому для полноценного реалтайма – когда плеер получает кадр практически сразу после его генерации в камере – больше подходит другой формат, изначально разработанный для стриминга. Речь идет о RTSP, который также обладает хорошей поддержкой среди плееров (к примеру, легко проигрывается популярным плеером VLC) и относительно не сложен в реализации. Рассмотрим пример приложения, которое обеспечивает трансляцию по стандарту RTSP – DemoRTSP.

В отличии от HLS и fMP4, которые полагаются для обмена данными на HTTP-протокол, – RTSP изначально использует свой собственный формат поверх “голых сокетов”. Кроме этого, для работы RTSP требуется два канала — один сигнальный, по которому клиент и сервер обмениваются управляющей информацией, а второй “для данных”, по которому сервер отправляет исключительно сжатые данные. Это немного усложняет схему обмена, однако позволяет добиться минимальных задержек – клиент по определению получает данные сразу после того, как сервер отправляет их по сети. В RTSP просто не предусмотрено никаких промежуточных звеньев!

DemoRTSP реализует минимальный набор для такого обмена. При запуске приложение начинает слушать сервисный порт (554) на предмет обращений от клиентов-плееров. При получении обращения, DemoRTSP отправляет в ответ простую строчку с указанием кодека, который будет использован для сжатия видео и аудио (для iOS это стандартная пара H.264/AAC) и номера порта данных, по которому сервер будет отправлять сжатые кадры. После этого клиент-плеер подключается к “порту данных” и проигрывает все, что получает от сервера. В этой схеме сервер никогда ничего не ждет и все сжатые кадры сразу уходят плееру, гарантируя минимальную задержку из возможных.

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

Live Video Effects on iOS

В нашем демо-приложении DemoRTSP использован весьма простой подход на базе PBVision, но в ваших приложениях вы можете использовать существенно более продвинутые решения на базе фреймворка GPUImage, который позволяет применять к видеопотоку целую цепочку OpenGL эффектов, при этом сведя задержку практически к нулю.
В DemoRTSP можно увидеть пример наложения на стрим простого Blur-эффекта.
Кто сказал, что делать Prisma-like video на лету невозможно!?

Можно пойти еще дальше, и использовать наиболее “быстрый” способ работы с изображениями в iOS на текущий момент — Metal, пришедший на смену OpenGL (в последних версиях iOS). Для примера можно посмотреть в MetalVideoCapture, где показано, как с помощью API-интерфейса CVMetalTextureCache передать результат захвата камеры в Metal Render Pass.

Кроме Metal, iOS последних версий появилась еще несколько интересных возможностей. Одна из них — ReplayKit, позволяющий в несколько строчек организовать трансляцию экрана устройства. Это довольно интересная платформа, однако на текущий момент она не позволяет “вмешиваться” в процесс создания кадра, не позволяет записывать изображение с камеры (только с экрана!), а получение записи ограничено штатными средствами. На текущий момент этот фреймворк не предназначен для полноценного создания управляемых трансляций, и больше похож на “задел на будущее”. Аналогично можно сказать и про другую популярную “новинку”, iOS-поддержку нового языка программирования Swift. К сожалению, он недостаточно хорошо интегрируется с низкоуровневыми возможностями, требуемыми для работы с видео и данными, поэтому в ближайшей перспективе его вряд ли можно будет использовать в подобных задачах (исключая интерфейс).

Ссылки

  1. iOS Live Streaming
  2. HLS
  3. HDS
  4. MPEG-DASH
  5. MP4/fMP4
  6. RTSP
  7. WebRTC
  8. Сравнение HLS и MPEG-DASH
  9. Metal app
  10. ReplayKit
  11. DemoFMP4 и DemoRTSP
  12. VideoToolbox
  13. AudioToolbox
  14. Bento4
  15. GCDWebServer
  16. PBJVision

Плеер плейлистов для iOS

DVPlaylistPlayer Title

Одной из основных частей приложения, так или иначе работающего с видео, является видеоплеер. Если вы хотя бы раз имели дело с интеграцией плеера в своё приложение, то наверняка знаете, что его настройка и кастомизация занимает определённое время. Также мы готовы поспорить, что чаще всего вам не нужен был плеер, который играл бы только одно видео за всё время работы с приложением. В большинстве случаев вы бы хотели использовать плейлисты. В этой статье мы хотим рассказать вам о разработанном нами открытом компоненте, который мы используем для воспроизведения видео в нашем проекте Together. Речь пойдёт о плеере плейлистов DVPlaylistPlayer.
Continue reading

OTT: видео сервисы на экранах Panasonic ТВ

Panasonic Viera Connect

Крупнейшие производители телевизоров в последние годы активно осваивают возможности предоставления услуг через интернет, и компания Panasonic не стала в этом отношении исключением. Свое видение концепции умного телевидения специалисты японской компании воплотили в технологии Viera Connect. Continue reading

Разработка видео платформ в DENIVIP Media

developers of video apps

Мы в DENIVIP Media создаем видео платформы с 2008 года (как правило вместе с самими сервисами/порталами/приложениями). Спустя 4 года создания специализированных видео платформ под разные проекты у нас накопился приличный опыт и информация о многих граблях, которые неизбежно встречаются в видео проектах. В этой статье я расскажу про то, как мы проектируем видео платформы и какие моменты важно учитывать при создании новой или апгрейде старой видео платформы. Также я постараюсь отметить основные тенденции в развитии видео платформ, которые видны в ближайшем будущем. Continue reading

Примеры из жизни: BBC Olympics



BBC-Olympics-2012

Сервис спортивных трансляций BBC Olympics стал одним из главных событий 2012 года. Индустрия видеосервисов вышла на новый уровень, а Олимпийские Игры 2012 года все уже привыкли называть «по-настоящему цифровыми». Очень важно отметить всю важность накопленного опыта и идти дальше на базе этих новых достижений. В этой статье мы рассмотрим этот проект, его реализацию и ценный опыт, который вы можете использовать в своих проектах. Continue reading

HTTP Live Streaming: лучшие рецепты

ios-video-hls

Создание идеальных с технической точки зрения приложений, как правило, является чрезвычайно сложной и трудоемкой задачей. При этом полезная информация зачастую рассеяна по множеству источников. Это относится, в том числе, к разработке видеоприложений для iOS. В данной статье собрана наиболее важная и полезная информация, позволяющая качественно использовать весь спектр возможностей HTTP Live Streaming, а также список первоисточников. Данные материалы будут полезны всем читателям, заинтересованным в создании качественных и удобных для пользователей видеосервисов. Continue reading

Сервис видео статистики

video-analytics
Ни для кого не секрет, что видео статистика и аналитика – важная составляющая любого видеопортала. Одна из главных целей сбора статистики просмотров – осуществление взаиморасчетов с правообладателями. Но, помимо этой задачи, есть  еще целый ряд важных задач, например:

  • ограничение количества одновременных просмотров с одного аккаунта (Вы же не хотите, чтобы под одним аккаунтом смотрели видео все знакомые одного счастливого покупателя? Точнее, пусть смотрят, но хотя бы по очереди, а не одновременно :)),
  • запрет на просмотр любого видео для пользователей, получивших абонемент на просмотр по ошибке или вследствие некой махинации,
  • оценка качества и популярности видео,
  • возврат в точку, где просмотр был прерван (с любого устройства),
  • и последнее в списке, но отнюдь не по важности – обеспечение удобства для пользователя.

Разумеется, не стоит забывать, что каждый видеопортал имеет свои специфичные задачи, которые немыслимы  без сведений о просмотрах. В этой статье мы обсудим особенности реализации такого сервиса. Continue reading

Как сделать онлайн трансляцию

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

  • Как показать всем игру, прохождение ее этапов или просто игровой процесс?
  • Как провести вебинар не используя сложного ПО?
  • Как провести презентацию/обучения для удаленных сотрудников?
  • Как сделать видео блог? Как записать видео обращение?
  • Как посмотреть, что не работает на компьютере пользователя, какая ошибка там возникает?

Описанные действия применимы не только к нашему демонстрационному сервису. С несущественными изменениями они применимы и к другим популярным ресурсам типа livestream.com, ustream.com, justin.tv.
Continue reading

Стратегии монетизации видео контента

Монетизация онлайн видео — это основная цель запуска множества дорогостоящих проектов и реализация средств монетизации является одной из важнейших задач онлайн видео сервисов. В статье рассмотрены основные бизнес модели и технические аспекты их реализации. Continue reading

Новые облачные сервисы для видео порталов

cloud video player

Запуск сложного онлайн видео портала или добавление интересного видео на популярный Интернет ресурс требуют много усилий со стороны разработчиков и инженеров. Множество облачных онлайн видео платформ предлагаемых по модели SaaS дают возможность избежать головной боли при внедрении онлайн видео технологий в ваши проекты. Но подобные предложения как правило накладывают существенные ограничения на техническую реализацию и не содержат некоторых очень важных модулей. Чтобы исправить эту ситуацию мы запускаем целую пачку сервисов по модели SaaS, которые могут быть полезны для любого онлайн видео проекта. Continue reading