Kotlin + WebRTC: Building Real-Time Audio/Video Applications
WebRTC enables real-time peer-to-peer audio and video communication.
Typical use cases include:
- video calls
- voice calls
- remote assistance
- online classrooms
- telemedicine
- live collaboration
A simplified architecture is:
Android A Android B
| |
Camera / Mic Camera / Mic
| |
+-------- WebRTC Peer Connection--+
|
Media Transport
WebRTC Is More Than a Camera API
A complete WebRTC application usually needs:
- media capture
- peer connections
- signaling
- ICE candidate exchange
- STUN/TURN infrastructure
- connection state handling
- permissions
- lifecycle management
Signaling
WebRTC itself does not define your application's signaling server.
Signaling is used to exchange:
- SDP offers
- SDP answers
- ICE candidates
A typical sequence:
Caller Signaling Server Callee
|------ SDP Offer ------------>|
| |------ SDP Offer ---------->|
| |<----- SDP Answer ----------|
|<----- SDP Answer ------------|
| |
|------ ICE Candidate -------->|
|<----- ICE Candidate ---------|
The signaling server does not normally carry the actual media stream.
Android Permissions
For camera and microphone access, request the appropriate runtime permissions.
Your application should clearly explain why it needs them.
Conceptually:
CAMERA
RECORD_AUDIO
Follow Android's current permission requirements and privacy guidance.
WebRTC Peer Connection
The exact Android API depends on the WebRTC distribution used by your project.
Conceptually:
val peerConnection = peerConnectionFactory.createPeerConnection(
rtcConfig,
observer
)
The peer connection manages the media transport.
Capturing Camera and Microphone
The media pipeline is approximately:
Camera
↓
Video Source
↓
Video Track
↓
Peer Connection
Microphone
↓
Audio Source
↓
Audio Track
↓
Peer Connection
Add tracks to the peer connection before negotiating.
SDP Offer / Answer
Caller:
Create PeerConnection
↓
Create Offer
↓
Set Local Description
↓
Send SDP through signaling
Callee:
Receive Offer
↓
Set Remote Description
↓
Create Answer
↓
Set Local Description
↓
Send Answer
ICE Candidates
ICE candidates describe possible network paths.
Exchange them through your signaling layer:
Peer A
|
| ICE candidate
v
Signaling
|
| ICE candidate
v
Peer B
STUN and TURN
Direct peer-to-peer connectivity is not always possible.
STUN helps peers discover their public network address.
TURN relays media when a direct path cannot be established.
Production deployments should plan for TURN capacity because relay traffic can be expensive.
Connection States
Track states such as:
NEW
CONNECTING
CONNECTED
DISCONNECTED
FAILED
CLOSED
The UI should respond appropriately.
For example:
Connecting...
Connected
Reconnecting...
Call ended
Call Lifecycle
A robust Android implementation needs to handle:
- app backgrounding
- screen rotation
- permission changes
- incoming calls
- network changes
- Bluetooth/headset changes
- call termination
Do not assume the Activity lifetime equals the call lifetime.
Architecture
A scalable application can use:
UI
|
CallViewModel
|
CallRepository
|
WebRTC Engine
|
Signaling Client
|
Signaling Server
Keep WebRTC-specific APIs out of UI components whenever possible.
Video Rendering
Remote video is normally rendered through the WebRTC video rendering API supplied by your WebRTC implementation.
Keep rendering separate from call control.
Security
Use:
- authenticated signaling
- secure signaling transport
- authorization
- encrypted WebRTC media
- server-side access control
- careful handling of call metadata
Never trust identifiers received from the client.
Testing
Test:
- camera permission denied
- microphone permission denied
- Wi-Fi to mobile-data transition
- poor connectivity
- call rejection
- call termination
- background/foreground transitions
- TURN fallback
- multiple calls
Conclusion
Building a WebRTC application is a systems problem rather than simply adding a video widget.
The media engine, signaling layer, network traversal, Android lifecycle, permissions, and application state must work together.
A clean architecture keeps WebRTC complexity behind a dedicated call engine or repository so the rest of the Android application remains maintainable.
Useful Links
SDK Flutter: https://github.com/v-modal/vmodal_sdk_flutter
SDK Android: https://github.com/v-modal/vmodal_sdk_android
Discord: https://discord.gg/K72z28KUx
Top comments (0)