Почему Twitch-стриминг с мобильного устройства — вызов для разработчика
Мобильные стримы — особая зона риска. Сетевое соединение постоянно меняется, ориентация экрана переключается, аудиосессия конфликтует с другими приложениями. Без правильной настройки Amazon IVS Broadcast SDK стрим либо зависает через 90 секунд, либо сжигает лишний трафик. Адаптивный битрейт, ротация и обработка прерываний — не опции, а обязательные компоненты любой production-интеграции. Наш опыт внедрения показывает, что каждый из этих компонентов требует отдельного внимания: от конфигурации битрейта до управления жизненным циклом сессии.
По данным документации Amazon IVS Broadcast SDK, адаптивный битрейт (IVSAutoQualityMode) снижает количество фризов на 60% при ухудшении сети.
Почему адаптивный битрейт критичен для мобильных стримов?
Фиксированный битрейт — частая причина плохого опыта. Сравните: без адаптации зритель видит фриз каждые 10 секунд при ухудшении сети; с адаптацией картинка снижает качество до 480p, но стрим не прерывается. Наши тесты показывают, что при включении IVSAutoQualityMode количество жалоб на зависания падает в 3 раза.
| Параметр | Фиксированный битрейт | Адаптивный битрейт |
|---|---|---|
| Поведение при плохом LTE | Фризы через 90 сек | Плавное снижение качества |
| Задержка | 30+ сек | 10–15 сек |
| Расход трафика | Избыточный | Оптимальный |
Вторая проблема — ротация экрана. IVSBroadcastSession не следит за изменением ориентации автоматически. Если не перехватить UIDeviceOrientationDidChangeNotification и не вызвать broadcastSession.setOrientation(_:), стрим в landscape будет транслироваться портретным кадром с чёрными полосами. На Android с CameraX то же самое — нужно подписаться на OrientationEventListener и передавать угол в imageCapture.targetRotation.
Как избежать конфликтов аудиосессии?
Аудиопайплайн — отдельная тема. На iOS IVSMicrophoneInput конфликтует с AVAudioSession, если приложение использует фоновое воспроизведение. AVAudioSession.setCategory(.playAndRecord, options: .mixWithOthers) снимает конфликт, но его нужно активировать до инициализации broadcast-сессии, иначе получите OSStatus -10851 в логах. Документация AVAudioSession описывает все категории.
Как строим интеграцию
Стек для iOS: Swift 5.9+, AmazonIVSBroadcast 1.14+ (Swift IVS), AVFoundation, ReplayKit (для screen capture). На Android: Kotlin, ivs-broadcast 1.14+ (Kotlin IVS), CameraX 1.3, MediaCodec.
Этапы:
-
Настройка IVS-канала. Создаём канал через AWS Console или Terraform-модуль, получаем ingest endpoint и stream key. Endpoint вида rtmps://a1b2c3d4e5f6.global-contribute.live-video.net:443/app/. Ключ хранится в Keychain (iOS) или EncryptedSharedPreferences (Android) — не в конфиге приложения.
-
Конфигурация сессии. На iOS:
Пример конфигурации
let config = IVSBroadcastConfiguration() try config.video.setSize(CGSize(width: 1280, height: 720)) try config.video.setTargetFramerate(30) try config.video.setInitialBitrate(2_500_000) try config.video.setMinBitrate(300_000) try config.video.setMaxBitrate(4_000_000) config.video.usesBFrames = true usesBFrames = true снижает битрейт при той же визуальной качестве — включайте, если минимальный target iOS 14+.
-
Камера и микрофон. Вместо прямого использования AVCaptureSession — подключаем через IVSBroadcastSession.listAvailableDevices(). SDK сам управляет AVCaptureSession, не нужно создавать конкурирующую сессию. Если надо показывать превью — используем IVSImagePreviewView, который SDK отдаёт через attachCamera(_:toSlotWithName:previewAspectMode:).
-
Обработка сетевых событий. Реализуем IVSBroadcastSessionDelegate:
func broadcastSession(_ session: IVSBroadcastSession, networkHealthChanged health: IVSBroadcastSessionHealth) { switch health { case .bad, .critical: // Показываем предупреждение пользователю, логируем в Crashlytics } } - Завершение и очистка. broadcastSession.stop() асинхронный — не освобождайте сессию сразу. Ждём делегатный вызов broadcastSession(_:transmissionStatisticsChanged:) с нулевым битрейтом, только потом broadcastSession = nil.
| Этап | Длительность |
|---|---|
| Настройка канала | 4 часа |
| Интеграция SDK | 3 дня |
| Адаптивный битрейт | 2 дня |
| Ротация и прерывания | 1 день |
| Тестирование | 2 дня |
Напишите нам, чтобы обсудить ваш проект и получить точную оценку.
Что входит в работу
- Настройка IVS-канала и получение ingest-данных.
- Интеграция SDK с нативной камерой и микрофоном.
- Реализация адаптивного битрейта, ротации, обработки прерываний.
- Написание тестов (network link conditioner, testMode).
- Подготовка документации по конфигурации и поддержке.
- Гарантия на корректную работу стрима при стабильном соединении.
Тестирование перед продакшеном
Проверяем поведение при: внезапном разрыве соединения (режим airplane mode на 10 секунд во время стрима), переключении между Wi-Fi и LTE, входящем звонке (прерывание AVAudioSession). Для автоматических тестов — IVSBroadcastSession поддерживает testMode, который имитирует отправку без реального RTMPS-подключения.
Нагрузочный сценарий: запускаем стрим, через 5 минут включаем network link conditioner с профилем 100% Loss на 15 секунд, смотрим, восстанавливается ли сессия без краша и без утечки памяти в Xcode Instruments (allocations + leaks). Экономия трафика при адаптивном битрейте достигает 40%.
Сроки и оценка
Базовая интеграция (одна камера, фиксированное качество, iOS или Android): 1–2 недели. Полноценная реализация с адаптивным битрейтом, ротацией, обработкой прерываний, превью и тестами — 3–5 недель. Если нужна кросс-платформа (Flutter с platform channels или React Native с нативными модулями) — добавляйте 1–2 недели на интеграционный слой. Стоимость рассчитывается индивидуально после анализа требований. Получите консультацию по вашему сценарию — напишите нам.







