Інтеграція Agora SDK для відеозв'язку у мобільному застосунку
Agora — один з найпоширеніших managed-сервісів для real-time відео та аудіо. SDK береsorry на себе WebRTC під капотом, власну транспортну мережу (не публічний інтернет), адаптивний бітрейт та кодеки. Задача інтеграції — не просто додати залежність, а правильно налаштувати lifecycle, токени, обробку подій та UI.
Ініціалізація та токени
Agora працює за моделлю App ID + Token. App ID — публічний ідентифікатор з консолі. Token — короткоживучий JWT, який генерує ваш бекенд через Agora Token Builder та передається клієнту при вході в канал.
Інціалізуємо движок один раз при запуску застосунку:
// iOS
let config = AgoraRtcEngineConfig()
config.appId = "YOUR_APP_ID"
agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self)
// Android
val config = RtcEngineConfig()
config.mContext = context
config.mAppId = "YOUR_APP_ID"
config.mEventHandler = handler
rtcEngine = RtcEngine.create(config)
Повторна ініціалізація при кожному звонку — помилка. sharedEngine — синглтон, повторний виклик з тим же App ID просто повертає існуючий екземпляр. RtcEngine.create() на Android — ні: кожен виклик створює новий екземпляр, попередній потрібно знищити через RtcEngine.destroy(). Це не очевидно з документації, але витік нативних ресурсів проявляється через 3–5 звонків.
Вхід у канал та обробка відео
let option = AgoraRtcChannelMediaOptions()
option.clientRoleType = .broadcaster
option.channelProfile = .communication
agoraKit.joinChannel(
byToken: token,
channelId: channelName,
uid: 0, // 0 = автогенерація
mediaOptions: option
)
uid: 0 — Agora призначає UID сама. Якщо потрібна привʼязка до користувача системи — передавайте детерміністичний числовий ID (не UUID — Agora UID це UInt32).
Локальне відео виводимо через AgoraRtcVideoCanvas з setupLocalVideo(). Віддалене — через setupRemoteVideo() у делегатному методі didJoinedOfUid. Важливо: setupRemoteVideo() потрібно викликати на main thread, інакше EXC_BAD_ACCESS при швидкому підключенні/відключенні учасників.
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
DispatchQueue.main.async {
let canvas = AgoraRtcVideoCanvas()
canvas.uid = uid
canvas.renderMode = .hidden
canvas.view = self.remoteVideoView
self.agoraKit.setupRemoteVideo(canvas)
}
}
Налаштування якості відео
Agora надає предустановки (AgoraVideoEncoderConfiguration) та кастомні параметри:
let config = AgoraVideoEncoderConfiguration(
size: CGSize(width: 640, height: 360),
frameRate: .fps15,
bitrate: AgoraVideoBitrateStandard,
orientationMode: .adaptative,
mirrorMode: .auto
)
agoraKit.setVideoEncoderConfiguration(config)
Для мобільного 360p/15fps — розумний баланс якості та батарейної нагрузки. 720p/30fps — для планшетів або коли якість критична. AgoraVideoBitrateStandard — автоматичний вибір бітрейту під розрішення, працює краще, ніж ручна установка в більшості сценаріїв.
Обробка перериваннь та lifecycle
На iOS AVAudioSession.routeChangeNotification та AVAudioSession.interruptionNotification — Agora SDK обробляє автоматично при правильній налаштуванні AgoraAudioScenario. Сценарій .meeting — оптимален для відеозвонків: включає AEC (acoustic echo cancellation), ANS (noise suppression), AGC (нормалізація громкості).
При входящому системному звонку на iOS Agora не паузується автоматично. Реалізуємо через CXCallObserver та callObserver(_:callChanged:): при CXCall.hasConnected == true — mute локального аудіо у Agora (muteLocalAudioStream(true)), при завершенні — размьютимо.
На Android при переходу в фоновий режим без ForegroundService — Android 8+ убиває процес через 5–10 хвилин. Запускаємо ForegroundService при початку звонку з сповіщенням. android:foregroundServiceType="camera|microphone" у маніфесті обов'язковий з Android 14.
Помилки аутентифікації токена
AgoraErrorCode.tokenExpired (109) та AgoraErrorCode.invalidToken (110) — найчастіші проблеми в продакшені. Token має обмежений TTL (від 24 годин до 1 години в залежності від налаштувань). Реалізуємо обробку через делегатний метод tokenPrivilegeWillExpire — отримуємо новий токен з бекенду та викликаємо renewToken() без розриву з'єднання.
Типова помилка: токен генерується з UID 0 на бекенді, але клієнт після joinChannel отримує конкретний UID від Agora — при наступному renewToken передає токен, сгенерований під неправильний UID. Потрібно зберігати UID з didJoinChannel та використовувати при запиті нового токена.
Строки
Базова інтеграція (1-на-1 відеозвонок з управлінням камерою, mute, flip) — 3–5 днів. З підтримкою групи до 8 учасників, token-менеджментом та фоновим режимом — 1–2 тижні. Вартість розраховується після аналізу вимог.







