При розробці мобільного додатку з функцією прямого ефіру на YouTube, Twitch або Facebook Live ви швидко впираєтеся в обмеження: ні iOS, ні Android не надають вбудованого API для RTMP. Доводиться інтегрувати сторонні бібліотеки, а це — налаштування апаратного кодування через VideoToolbox або MediaCodec, управління сесією захоплення, обробка обривів з'єднання та адаптація бітрейту під канал зв'язку. Наша команда виконала десятки інтеграцій RTMP-стрімінгу — від фітнес-додатків до платформ для онлайн-навчання. Типовий запит клієнта: потрібно, щоб користувач міг транслювати екран або камеру в реальному часі з мінімальною затримкою, при цьому стрім має коректно працювати в фоні та відновлюватися після втрати мережі.
Протокол RTMP працює поверх TCP, що забезпечує надійну доставку даних, але потребує правильного налаштування таймаутів та повторних підключень. Для наднизької затримки (<500 мс) використовують WebRTC, однак популярні платформи його не приймають напряму — потрібен рестрімер на стороні сервера. Тому RTMP залишається найпрактичнішим вибором для мобільного стрімінгу.
Чому RTMP залишається стандартом для мобільного стрімінгу?
RTMP використовує TCP, забезпечує надійну доставку даних і працює через більшість корпоративних фаєрволів (порт 1935). Затримка — 1-3 секунди, що прийнятно для стрімінгу на платформи. WebRTC дає затримку <500 мс, але YouTube і Twitch не приймають його напряму — потрібен серверний рестрімер. SRT працює поверх UDP, але також потребує додаткового серверного ПЗ. Порівняння протоколів:
| Протокол | Затримка | TCP/UDP | Підтримка платформ | Призначення |
|---|---|---|---|---|
| RTMP | 1-3 с | TCP | YouTube, Twitch, Facebook | Потокове мовлення на великі платформи |
| WebRTC | <500 мс | UDP (і TCP) | Не підтримується напряму YouTube/Twitch | Відеодзвінки, низька затримка |
| SRT | 0.5-2 с | UDP | Потребує серверного рестрімера | Надійна передача в складних мережах |
Як уникнути чорного екрану та втрати з'єднання?
Три типові проблеми мобільного RTMP-стрімінгу та їх вирішення:
Затримка при старті. Перші секунди стрім нестабільний — SPS/PPS NAL units ще не кешовані на сервері. На iOS рішення: встановлюємо kVTCompressionPropertyKey_AllowFrameReordering: false — B-frames відключені, затримка знижується на 50%.
Втрата з'єднання. При обриві мережі необхідно автоматично перепідключатися. На iOS HaishinKit має вбудований механізм реконекту. На Android потрібна обробка onConnectionFailedRtmp з повторним викликом startStream() з експоненційною затримкою (початковий інтервал 2 с, збільшення до 30 с).
Чорний екран. Виникає, якщо startStream() викликаний до ініціалізації захоплення. Порядок: attachCamera → startPreview → connect → publish. На iOS також важливо налаштувати AVCaptureSession до запуску.
Що потрібно перевірити перед стрімом?
- Дозвіл камери та мікрофона (на iOS —
NSCameraUsageDescription,NSMicrophoneUsageDescription; на Android —CAMERA,RECORD_AUDIO). - Налаштування бітрейту: для HD (1280x720) рекомендується 2 000 000 – 3 000 000 біт/с.
- TLS-сертифікат для rtmps (на Android —
RtmpsCamera2, на iOS —rtmps://). - Тестовий стрім на платформи з перевіркою затримки.
iOS: HaishinKit
Найкращий Swift-нативний варіант. Без залежності від FFmpeg, апаратне кодування через VideoToolbox. HaishinKit запускає стрім у 2 рази швидше, ніж бібліотеки на FFmpeg.
Мінімальне налаштування:
import HaishinKit let rtmpConnection = RTMPConnection() let rtmpStream = RTMPStream(connection: rtmpConnection) rtmpStream.videoSettings = VideoCodecSettings( videoSize: CGSize(width: 1280, height: 720), bitRate: 2_000_000, profileLevel: kVTProfileLevel_H264_High_AutoLevel as String ) rtmpStream.audioSettings = AudioCodecSettings(bitRate: 128_000) // Прив'язуємо камеру let camera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) try rtmpStream.attachCamera(camera) try rtmpStream.attachAudio(AVCaptureDevice.default(for: .audio)) // Прев'ю let hkView = MTHKView(frame: previewView.bounds) hkView.videoGravity = .resizeAspectFill rtmpStream.addOutput(hkView) previewView.addSubview(hkView) // Запуск rtmpConnection.connect("rtmp://live.example.com/live") rtmpStream.publish("stream_key") Перепідключення при обриві: підписуємося на RTMPConnection.Event.rtmpStatus, при code == RTMPStatusCode.connectClosed — reconnectDelay(3) і повтор connect(). HaishinKit має вбудований reconnect механізм.
Моніторинг: rtmpStream.info.byteCount та RTMPStream.currentFPS — слідкуємо за реальним FPS. Якщо падає нижче 20 — сигнал поганого з'єднання.
Android: rtmp-rtsp-stream-client-java
Бібліотека Pedro Vicente. Підтримує Camera1, Camera2, CameraX, Screen capture. Апаратне кодування через MediaCodec.
val rtmpCamera = RtmpCamera2(binding.surfaceView, object : ConnectCheckerRtmp { override fun onConnectionSuccessRtmp() { /* оновити UI */ } override fun onConnectionFailedRtmp(reason: String) { rtmpCamera.stopStream() retryConnection() } override fun onDisconnectRtmp() { retryConnection() } override fun onAuthErrorRtmp() { /* показати помилку */ } override fun onAuthSuccessRtmp() {} override fun onNewBitrateRtmp(bitrate: Long) { updateBitrateUI(bitrate) } }) // Підготовка (роздільна здатність, бітрейт, FPS, аудіо) rtmpCamera.prepareVideo(1280, 720, 30, 2_000_000) && rtmpCamera.prepareAudio(128_000, 44100, true) rtmpCamera.startStream("rtmp://live.example.com/live/stream_key") RtmpCamera2 приймає SurfaceView або TextureView. Для Jetpack Compose: AndroidView { RtmpCamera2(context, ...) }.
Адаптація бітрейту: rtmpCamera.setVideoBitrateOnFly(newBitrate) — змінюємо бітрейт без перезапуску стріму.
Порівняння бібліотек:
| Параметр | iOS (HaishinKit) | Android (rtmp-rtsp-stream-client-java) |
|---|---|---|
| Мова | Swift | Kotlin/Java |
| Кодування | VideoToolbox | MediaCodec |
| TLS | rtmps | RtmpsCamera2 |
| Адаптація бітрейту | Налаштування параметрів | setVideoBitrateOnFly |
| Реконект | Вбудований | Ручна обробка |
Як ми це робимо: стек і конфігурація
Ми використовуємо описані бібліотеки з додатковим налаштуванням адаптивного бітрейту. На iOS моніторимо завантаження CPU та знижуємо бітрейт на 25%, якщо FPS падає нижче 20. На Android використовуємо onNewBitrateRtmp для динамічного регулювання. Економія трафіку — до 40% без втрати якості. Для аутентифікації використовуємо stream key в URL або RTMP auth. Підтримуємо rtmps для YouTube Live.
Наші інженери налаштовують параметри кодування під конкретні сценарії: для стрімінгу екрану — нижчий бітрейт, для камери — високий. Гарантуємо стабільну роботу на пристроях з iOS 15+ та Android 10+. Зв'яжіться з нами для оцінки вашого проекту.
Процес роботи
- Аналітика — вибираємо протокол (RTMP/WebRTC), сервер, платформу. Визначаємо вимоги до затримки та якості.
- Проектування — архітектура модуля стрімінгу, обробка фонового режиму, реконект, моніторинг.
- Реалізація — інтеграція бібліотеки, налаштування кодування, тестування на реальних пристроях.
- Тестування — перевірка затримки, якості відео, поведінки при обривах мережі, публікація в TestFlight/Google Play.
- Деплой — підготовка до публікації, документація, підтримка.
Що входить в роботу
- Інтеграція RTMP-стрімінгу на iOS та/або Android
- Налаштування апаратного кодування та адаптивного бітрейту
- Реалізація реконекту та обробки помилок
- Підтримка TLS (rtmps)
- Документація з налаштування сервера та стрімінгової платформи
- Допомога з проходженням рев'ю в App Store та Google Play (урахування вимог до фонового режиму та приватності)
- Гарантія сумісності з останніми версіями ОС
Чому обирають нас
Ми займаємося мобільною розробкою понад 5 років та виконали більше 50 проектів з відео. Наші розробники сертифіковані по iOS та Android. Ми гарантуємо якість коду та дотримання термінів. Досвід інтеграції RTMP-стрімінгу дозволяє уникнути типових помилок і здати проект вчасно.
Якщо вам потрібен RTMP-стрімінг у мобільному додатку — зв'яжіться з нами для оцінки проекту. Ми розрахуємо вартість та терміни індивідуально. Замовте інтеграцію RTMP-стрімінгу під ключ та отримайте готовий модуль за 2-3 дні.







