Screen Broadcasting с мобильного устройства: реализация и оптимизация

Screen Broadcasting — трансляция экрана мобильного приложения — востребована в сценариях демонстрации, технической поддержки, стриминга и удалённого обучения. На iOS доступен только ReplayKit с жёстким лимитом памяти 50 МБ в Broadcast Extension, а на Android — MediaProjection с возможностью захвата

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Screen Broadcasting с мобильного устройства: реализация и оптимизация
Средний
~3-5 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    896
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    1003
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    597

Screen Broadcasting — трансляция экрана мобильного приложения — востребована в сценариях демонстрации, технической поддержки, стриминга и удалённого обучения. На iOS доступен только ReplayKit с жёстким лимитом памяти 50 МБ в Broadcast Extension, а на Android — MediaProjection с возможностью захвата в реальном времени. Неправильная реализация ведёт к потере кадров, перерасходу памяти и сбоям под нагрузкой. Мы решаем эти проблемы: оптимизируем downscale видео, внедряем heartbeat-мониторинг для контроля состояния трансляции и подбираем оптимальный протокол — RTMP, SRT или WebRTC. Наши инженеры имеют 7+ лет опыта в мобильной разработке, реализовали более 30 проектов со стримингом экрана и с 2018 года на рынке. Получите предварительную оценку вашего проекта — просто свяжитесь с нами.

Особенности Screen Broadcasting на iOS

Трансляция экрана на iOS работает только через ReplayKit. Попытки захватить UIScreen напрямую с помощью UIScreen.main.snapshot дают единичный снимок, а не видеопоток. Как указано в документации Apple, ReplayKit — единственный публичный API для захвата экрана ReplayKit. Однако он накладывает ограничения: задержка 2–5 секунд и лимит памяти 50 МБ для Broadcast Extension.

Два режима ReplayKit и когда что использовать

RPScreenRecorder (in-app recording). Захватывает только контент внутри приложения. Пользователь не видит системный picker. Подходит для записи геймплея, capture UI приложения. Недостаток — захват прекращается при сворачивании.

RPBroadcastSampleHandler (broadcast upload extension). Работает как системный Extension — процесс живёт отдельно от основного приложения. Захватывает весь экран устройства, включая другие приложения и уведомления. Пользователь запускает через Control Center или RPSystemBroadcastPickerView. Именно этот режим нужен для трансляции «всего экрана».

Архитектура Broadcast Extension:

 iOS System → RPBroadcastSampleHandler (Extension process) ↓ CMSampleBuffer (video + audio) ↓ App Group shared container (если нужна коммуникация с основным приложением) ↓ RTMP/SRT → сервер трансляции 

Расширение не имеет UI и ограничено 50 МБ RAM. Это жёсткое ограничение: всё кодирование и отправка должны умещаться в этот бюджет.

RPBroadcastSampleHandler: реализация

class BroadcastHandler: RPBroadcastSampleHandler { private var rtmpStream: RTMPStream? override func broadcastStarted(withSetupInfo setupInfo: [String: NSObject]?) { // Инициализируем RTMP или SRT соединение // setupInfo — данные от основного приложения через Info.plist } override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) { switch sampleBufferType { case .video: rtmpStream?.append(sampleBuffer) case .audioApp: rtmpStream?.append(sampleBuffer) // аудио приложений case .audioMic: // аудио микрофона — отдельный поток, требует явного разрешения break } } override func broadcastFinished() { rtmpStream?.close() } } 

Передача параметров (stream key, endpoint) из основного приложения в Extension — через App Group UserDefaults:

let defaults = UserDefaults(suiteName: "group.com.yourapp.broadcast") defaults?.set(streamKey, forKey: "streamKey") 

Почему задержка на iOS неизбежна?

ReplayKit screen broadcast добавляет буферизацию ~2–5 секунд. Это не баг — Apple буферизирует для защиты конфиденциальности (показ системных диалогов с паролями). Снизить нельзя.

Разрешение зависит от модели устройства: современные топовые модели отдают 1668×2388 (native scale), что избыточно для стрима. В processSampleBuffer перед энкодированием нужно downscale через VTPixelTransferSession или CIContext:

// Масштабируем до 1280×720 перед отправкой в энкодер let scaledBuffer = pixelTransferSession.scale(pixelBuffer, to: CGSize(width: 1280, height: 720)) 

Без downscale Extension превысит 50 МБ RAM на первом же I-frame в 4K.

Сравнение протоколов трансляции

Протокол Задержка Надёжность Сложность реализации
RTMP 2-5 с Средняя (требует ретрансляции) Низкая
SRT 0.5-2 с Высокая (FEC, автоматическое восстановление) Средняя
WebRTC <0.5 с Высокая (P2P, адаптивный битрейт) Высокая

Выбор протокола зависит от сценария: RTMP — для массовых стримов, SRT — для стабильности, WebRTC — для минимальной задержки. Мы помогаем подобрать оптимальный вариант под ваш проект.

Реализация трансляции экрана на Android

На Android аналог — MediaProjection. Пользователь подтверждает разрешение через системный диалог (startActivityForResult с MediaProjectionManager.createScreenCaptureIntent()). После получения MediaProjection создаём VirtualDisplay и направляем его в MediaCodec через Surface:

val virtualDisplay = mediaProjection.createVirtualDisplay( "ScreenCapture", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaCodec.createInputSurface(), null, null ) 

В отличие от iOS, задержки ReplayKit нет — захват идёт почти в реальном времени. Но на более новых версиях Android появилось требование: если MediaProjection-сессия используется в ForegroundService, нужен тип FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION. Документация MediaProjection API описывает все нюансы.

Параметр iOS (ReplayKit) Android (MediaProjection)
Задержка 2–5 секунд (встроенная) Минимальная (реальное время)
Ограничение памяти 50 МБ RAM на Extension Нет жёсткого лимита, но рекомендуется управление
Захват других приложений Да (Broadcast Extension) Да (с разрешения)
Версии iOS 10+ Android 5+ (API 21)
Параметры запуска Через Control Center Через системный диалог

Android MediaProjection обеспечивает задержку менее 100 мс, что в 20–50 раз меньше задержки ReplayKit на iOS.

Как избежать падения Broadcast Extension?

На iOS Extension может работать бесконечно, но если процесс превышает 50 МБ — система его убивает без предупреждения. Для мониторинга из основного приложения — heartbeat через App Group: Extension пишет timestamp каждые 5 секунд, приложение проверяет. Если timestamp не обновлялся 15 секунд — считаем Extension упавшим и показываем предупреждение.

Мы внедряем heartbeat-механизм: Extension каждые 5 секунд сохраняет текущее время в UserDefaults через App Group. Основное приложение проверяет это значение каждые 15 секунд. Если с момента последнего обновления прошло больше 15 секунд — значит Extension упал. Пользователь получает уведомление и может перезапустить трансляцию.

Что входит в работу

  • Проектирование архитектуры с выбором протокола (RTMP, SRT, WebRTC) и сервера.
  • Разработка Broadcast Extension для iOS или сервиса захвата для Android.
  • Настройка App Group и коммуникации между процессами.
  • Оптимизация downscale видео и настройка битрейта.
  • Внедрение heartbeat-мониторинга и обработки ошибок.
  • Интеграция с сервером и тестирование на реальных устройствах.
  • Документация по интеграции и обучение команды.
  • Поддержка при релизе в App Store и Google Play.

Сроки ориентировочно

iOS Broadcast Extension с RTMP/SRT, downscaling, App Group коммуникацией: 2–3 недели. Android MediaProjection: 1.5–2 недели. Кросс-платформа с общим управляющим кодом: 4–5 недель. Стоимость рассчитывается индивидуально. Закажите предварительную оценку — свяжитесь с нами.

Важно соблюдать App Store Review Guidelines Section 4.2 — трансляция экрана должна быть явно указана в описании. Получите консультацию по архитектуре и оптимальное решение для вашего проекта.