Интеграция трансляции в VK Live из мобильного приложения
VK Live не предоставляет официальный мобильный SDK для сторонних приложений — это первое, что нужно понять. Трансляция организуется через RTMP/RTMPS-протокол на endpoint, который пользователь получает в настройках своей трансляции VK. Задача разработчика — захватить видео с камеры, закодировать его в H.264/H.265 и отправить на rtmp://vp.vkforms.ru/live с корректным stream key.
Ключевые технические сложности
Самая частая проблема — получение RTMP-ключа без участия пользователя. VK API (video.startStreaming) требует авторизацию через VK Connect с scope video. Если токен просрочен или не содержит нужный scope, метод возвращает error_code: 15 (access denied), и трансляция не запускается. Токен храним в Keychain/EncryptedSharedPreferences, обновляем через refresh flow до истечения, не по факту ошибки.
Кодирование на мобиле. На iOS используем VideoToolbox через AVAssetWriter + AVAssetWriterInput с параметрами:
-
AVVideoCodecKey: AVVideoCodecType.h264 -
AVVideoWidthKey: 1280,AVVideoHeightKey: 720 -
AVVideoCompressionPropertiesKey→AVVideoAverageBitRateKey: 2_500_000 -
AVVideoMaxKeyFrameIntervalKey: 60(keyframe каждые 2 секунды при 30fps)
Без явного AVVideoMaxKeyFrameIntervalKey энкодер расставляет keyframe слишком редко, RTMP-сервер VK начинает буферизировать дольше, зрители замечают рывки при смене сцены.
На Android — MediaCodec с MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.KEY_BITRATE_MODE = BITRATE_MODE_CBR. VBR режим на нестабильном соединении даёт всплески, которые дроп-пакеты на VK-ингесте превращают в артефакты на 2–3 секунды.
Как реализуем
Для RTMP-передачи на iOS используем HaishinKit (Swift, активно поддерживается). На Android — rtmp-rtsp-stream-client-java от pedroSG94 или собственный MediaMuxer с RTMP-клиентом поверх java.net.Socket. В продакшен-проектах предпочитаем нативный MediaCodec-путь с кастомным RTMP без тяжёлых зависимостей.
Схема для iOS с HaishinKit:
let rtmpConnection = RTMPConnection()
let rtmpStream = RTMPStream(connection: rtmpConnection)
rtmpStream.videoSettings = VideoCodecSettings(
videoSize: CGSize(width: 1280, height: 720),
bitRate: 2_500_000,
profileLevel: kVTProfileLevel_H264_High_AutoLevel as String
)
rtmpStream.audioSettings = AudioCodecSettings(bitRate: 128_000)
rtmpConnection.connect("rtmp://vp.vkforms.ru/live")
rtmpStream.publish(streamKey)
Мониторинг качества — подписываемся на RTMPConnection.Event.rtmpStatus, отслеживаем NetStream.Publish.BadName (неверный ключ), NetStream.Failed (разрыв соединения). При NetStream.Failed логируем в Firebase Crashlytics с параметрами: битрейт в момент разрыва, тип соединения (Wi-Fi/Cellular), версия ОС.
Переподключение реализуем с exponential backoff: 2s → 4s → 8s → 16s → 30s (максимум). Бесконечный retry без паузы заблокирует аккаунт на VK-стороне за flood.
Авторизация и получение stream key
Через VK SDK (iOS: VKSDK, Android: vk-android-sdk) или прямой OAuth2-flow:
- Открываем WebView или SFSafariViewController на
https://oauth.vk.com/authorize?client_id=APP_ID&scope=video&response_type=token - Перехватываем redirect на
https://oauth.vk.com/blank.html#access_token=... - Вызываем
video.startStreamingс полученным токеном - Из ответа берём
rtmp_urlиkey
Ключ сессионный — действует одну трансляцию. Сохранять между сессиями нельзя.
Сроки
Интеграция на одной платформе (iOS или Android): 2–3 недели с учётом OAuth-flow, захвата видео и базовой обработки сетевых ошибок. Добавление адаптивного битрейта и автопереподключения — ещё неделя. Стоимость рассчитывается индивидуально после анализа требований.







