VK Live Streaming Integration from Mobile Application
VK Live doesn't provide official mobile SDK for third-party apps — first thing to understand. Broadcasting organized via RTMP/RTMPS protocol to endpoint user gets in broadcast settings. Developer's task — capture video from camera, encode to H.264/H.265, send to rtmp://vp.vkforms.ru/live with correct stream key.
Key Technical Challenges
Most common problem — getting RTMP key without user. VK API (video.startStreaming) requires VK Connect authorization with video scope. If token expired or missing scope, method returns error_code: 15 (access denied), broadcast doesn't start. Store token in Keychain/EncryptedSharedPreferences, refresh via refresh flow before expiry, not on error.
Encoding on mobile. On iOS use VideoToolbox via AVAssetWriter + AVAssetWriterInput with parameters:
-
AVVideoCodecKey: AVVideoCodecType.h264 -
AVVideoWidthKey: 1280,AVVideoHeightKey: 720 -
AVVideoCompressionPropertiesKey→AVVideoAverageBitRateKey: 2_500_000 -
AVVideoMaxKeyFrameIntervalKey: 60(keyframe every 2 seconds at 30fps)
Without explicit AVVideoMaxKeyFrameIntervalKey encoder spaces keyframes too far, VK ingestion server buffers longer, viewers notice stuttering on scene change.
Android — MediaCodec with MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.KEY_BITRATE_MODE = BITRATE_MODE_CBR. VBR mode on unstable connection gives spikes which dropped packets on VK ingestion turn into artifacts for 2–3 seconds.
How We Implement
For RTMP delivery on iOS use HaishinKit (Swift, actively maintained). Android — rtmp-rtsp-stream-client-java by pedroSG94 or custom MediaMuxer with RTMP client over java.net.Socket. Production projects prefer native MediaCodec path with custom RTMP without heavy dependencies.
Scheme for iOS with 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)
Quality monitoring — subscribe to RTMPConnection.Event.rtmpStatus, track NetStream.Publish.BadName (invalid key), NetStream.Failed (connection break). On NetStream.Failed log to Firebase Crashlytics with params: bitrate at break, connection type (Wi-Fi/Cellular), OS version.
Reconnection implement with exponential backoff: 2s → 4s → 8s → 16s → 30s (max). Infinite retry without pause will block account on VK for flood.
Authorization and Stream Key
Via VK SDK (iOS: VKSDK, Android: vk-android-sdk) or direct OAuth2 flow:
- Open WebView or SFSafariViewController to
https://oauth.vk.com/authorize?client_id=APP_ID&scope=video&response_type=token - Intercept redirect to
https://oauth.vk.com/blank.html#access_token=... - Call
video.startStreamingwith obtained token - From response take
rtmp_urlandkey
Key is session-based — valid for one broadcast. Can't save between sessions.
Timeline
Integration on one platform (iOS or Android): 2–3 weeks accounting OAuth flow, video capture, basic network error handling. Adding adaptive bitrate and auto-reconnection — another week. Cost calculated individually after requirements analysis.







