Overview
A WebRTC-based video conferencing app built without third-party streaming services (no Daily, Twilio, or Agora), keeping infrastructure costs at zero and giving full control over the signaling and media layers.
Technical Challenges
WebRTC Signaling from Scratch
Implemented the full offer/answer/ICE-candidate exchange over WebSockets using an Express server. The trickle ICE flow is handled manually candidates are buffered on the receiving peer until the remote description is set to avoid race conditions that silently drop connections.
Topology Decision: Mesh vs SFU
For small rooms (≤4 peers) a full mesh is used each peer holds N-1 RTCPeerConnection objects. Scaling beyond that within the current architecture would require an SFU; the current design documents this as the next architectural step.
Live Transcription (ASR)
Audio tracks are captured from the local MediaStream, resampled to 16 kHz mono (required by the ASR model), and streamed over WebSocket to a backend ASR service. Partial transcripts are sent back incrementally and rendered as captions with a debounce to avoid flicker on word boundaries.
Deployment
The signaling and transcription backend runs on GCP Cloud Run in a Docker container. Cloud Run's per-request scaling model required keeping WebSocket connections alive via HTTP/2, which needed explicit configuration in the Express server and Cloud Run's timeout settings.
System architecture
Custom WebRTC implementation (no third-party streaming API). The Express backend on GCP Cloud Run handles signaling and feeds an ASR pipeline that pushes live captions back to both peers over WebSocket.


