В видеозвонках на мобильных платформах главные проблемы — lifecycle и управление токенами. Без правильной настройки получаете утечки ресурсов, обрывы сессий и перерасход лицензий. Наш опыт более 30 проектов с Agora SDK позволил сформулировать рабочий подход.
Почему Agora SDK — лучший выбор для видеозвонков?
Agora SDK — managed-сервис real-time видео и аудио, который берёт на себя WebRTC под капотом, собственную транспортную сеть SD-RTN, адаптивный битрейт и кодеки. В сравнении с raw WebRTC: Agora ускоряет разработку видеозвонков в 12 раз (с 3 месяцев до 1 недели), но требует грамотного токен-менеджмента. Правильная интеграция даёт сокращение расходов на инфраструктуру до 40% за счёт использования SD-RTN.
Как правильно настроить токены и избежать ошибок?
Agora работает по модели App ID + Token. App ID — публичный идентификатор из консоли. Token — короткоживущий JWT, который ваш бэкенд генерирует через Agora Token Builder и передаёт клиенту при входе в канал. Самые частые ошибки в продакшене: tokenExpired (109) и invalidToken (110). Token имеет ограниченный TTL (от 24 часов до 1 часа). Реализуем обработку через tokenPrivilegeWillExpire делегатный метод — получаем новый токен с бэкенда и вызываем renewToken() без разрыва соединения.
Типичная ошибка: токен генерируется с UID 0 на бэкенде, но клиент после joinChannel получает конкретный UID от Agora — и при следующем renewToken передаёт токен под неправильный UID. Решение: сохраняем UID из didJoinChannel и используем его при запросе нового токена.
| Сценарий | TTL | Рекомендация |
|---|---|---|
| Стандартный | 24 часа | Баланс безопасности и частоты обновлений |
| Высокая нагрузка | 1 час | Снижает риск компрометации токена |
Инициализация движка
Инициализируйте движок один раз при старте приложения:
let config = AgoraRtcEngineConfig()
config.appId = "YOUR_APP_ID"
agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self) val config = RtcEngineConfig()
config.mContext = context
config.mAppId = "YOUR_APP_ID"
config.mEventHandler = handler
rtcEngine = RtcEngine.create(config)Не создавайте движок заново под каждый звонок. sharedEngine — синглтон, повторный вызов с тем же App ID возвращает существующий экземпляр. На Android RtcEngine.create() каждый раз создаёт новый экземпляр; предыдущий нужно уничтожить через RtcEngine.destroy(). Иначе утечка нативных ресурсов проявляется через 3–5 звонков. Используйте LifecycleObserver для автоматического уничтожения движка при завершении активности.
Подключение к каналу и обработка видео
let option = AgoraRtcChannelMediaOptions()
option.clientRoleType = .broadcaster
option.channelProfile = .communication
agoraKit.joinChannel(
byToken: token,
channelId: channelName,
uid: 0,
mediaOptions: option
)uid: 0 — Agora назначает UID сама. Если нужна привязка к пользователю — передавайте детерминированный числовой ID (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 — для планшетов или когда качество критично. 1080p не подходит для мобильных: потребляет много энергии и ресурсов, а разница в восприятии между 720p и 1080p незначительна.
| Разрешение | fps | Битрейт | Нагрузка на батарею |
|---|---|---|---|
| 360p | 15 | Standard | Низкая |
| 720p | 30 | Standard | Средняя |
| 1080p | 30 | High | Высокая |
Как обработать прерывания и lifecycle?
На iOS AVAudioSession.routeChangeNotification и AVAudioSession.interruptionNotification — Agora SDK обрабатывает их автоматически при корректной настройке AgoraAudioScenario. Сценарий .meeting — оптимален для видеозвонков: включает AEC, ANS, AGC.
При входящем системном звонке Agora не паузируется автоматически. Реализуем через CXCallObserver: при CXCall.hasConnected == true — muteLocalAudioStream(true), при завершении — размьютим.
На Android без ForegroundService Android 8+ убьёт процесс через 5–10 минут. Запускаем ForegroundService при начале звонка с уведомлением. android:foregroundServiceType="camera|microphone" в манифесте обязателен с Android 14.
Что входит в интеграцию
- Анализ требований: количество участников, качество, бэкенд-интеграция, бюджет.
- Настройка токенов: генерация, кэширование, обработка протуханий.
- Реализация UI: видеоканвасы, органы управления, виртуальный фон.
- Lifecycle: ForegroundService на Android, CXCallObserver на iOS.
- Тестирование: 10+ сценариев (обрыв сети, входящий звонок, быстрая перекоммутация).
- Документация: README, комментарии кода, схема токенов.
- Поддержка: 2 недели после релиза, фиксация багов.
Сроки и стоимость
Базовая интеграция (1-на-1 видеозвонок с управлением камерой, mute, flip) — 3–5 дней. С поддержкой группы до 8 участников, токен-менеджментом и фоновым режимом — 1–2 недели. Стоимость рассчитывается после анализа требований. Свяжитесь с нами для оценки вашего проекта — мы подготовим смету и roadmap. Получите консультацию по интеграции Agora или закажите внедрение видеозвонков.







