WebRTC
lastmod 2026-04-02created 2014-03-11113 edits
WebRTC (Web Real-Time Communication) is an API designed to let web browsers communicate with each other without the help of plugins. It is a draft proposed by the W3C and can be used for voice calls, video calls, P2P file sharing, and more.
Categories
- Object Real-time Communications (ORTC)
- WebRTC:NativeCode
- WebRTC:NativeCode:GnArgumentList
- WebRTC:API (Web browser, JavaScript code API)
- WebRTC:IsolatedNetwork: How to use WebRTC in an isolated network environment (Offline).
- WebRTC:Connectivity
- WebRTC HTTP
About Streaming
- Media Streaming
- Media Streaming#Demo video: Collection of Streaming sample video URLs
- Low Latency Streaming
Terms
- Network address translation (NAT)
- Session Traversal Utilities for NAT (STUN)
- Traversal Using Relays around NAT (TURN)
- Interactive Connectivity Establishment (ICE)
- Session Description Protocol (SDP)
- JavaScript Session Establishment Protocol (JSEP) - Includes an Offer/Answer flow diagram.
- Trickle ICE
Tools
- Firefox:Plugin:DevToolsMediaPanel
- Chrome: chrome://webrtc-internals/
- Firefox: about:webrtc
Server/libraries
- Overview of WebRTC Open Source Media Servers
- Best 5 open source WebRTC Media Servers
- libjingle
- aiortc (python)
- jitsi (Java)
- Pion (Go)
- Janus (Open Source) WebRTC Gateway
- LibSourcey
- Kurento Media Server
- Licode
- Medooze
- wowza - Pricing reference
- Mediasoup
- PJSIP
- Jam - WebRTC-based live audio service (open-source alternative to Clubhouse)
- Jitsi Video Bridge
- Open WebRTC Toolkit (OWT)
- Ant Media Server - Pricing reference
- Open-EasyRTC - https://github.com/open-easyrtc/open-easyrtc
- openVidu - https://openvidu.io/
- Galene - https://github.com/jech/galene
- SaltyRTC - https://github.com/saltyrtc
- ion media server - https://github.com/ionorg/ion
- OvenMediaEngine - https://airensoft.com/ome
- Temasys - https://temasys.github.io/
- JSCommunicator - https://jscommunicator.org/
- PeerJS Server and Library - https://peerjs.com/
- WebRTC-Streamer - Worth installing on embedded devices... (there is a Docker image too)
Client
- webrtc-adapter - adapter.js is a shim to insulate apps from spec changes and prefix differences.
- OvenPlayer (HTML5 player)
Libraries
-
webrtcsink - https://github.com/centricular/webrtcsinkIMPORTANT: this repository is now archived - libwebrtc - Google's WebRTC implementation in a single static library.
- Trystero - Build instant multiplayer web apps without a server
- RecordRTC.js
Use case
WebRTC is basically a P2P protocol, so depending on the purpose of the service, such as building a large-scale media broadcasting service or when content processing is needed, you may need to set up a separate central server. Depending on the use case, the following architectures can be considered.
- P2P (Peer to Peer)
- Direct end-to-end connection without a central server is advantageous in terms of cost, but as the number of peers grows (mesh structure), it demands high system and network capacity. Suitable for 1:1 or small-scale media exchange.
- SFU (Selective Forwarding Unit)
- A central server approach that relays end-to-end media traffic through a central server, accepting the cost of allocating each peer connection and of decrypt/encrypt processing. Suitable for 1:M (or minimum-N:M) streaming service structures such as video broadcasting.
- MCU (Multi-point Control Unit)
- A central server approach in which the central server mixes (muxing) or processes (transcoding) multiple outgoing media streams and delivers them to the receivers; it significantly reduces the load on clients and the network, but requires high computing power on the central server.
| - | P2P | SFU | MCU |
| Client Uplink | High | Low | Low |
| Client Downlink | High | Low | High |
| Client CPU Usage | High | Low | Medium |
| Server CPU Usage | - | High | Low |
| Possible Latency | Depends on Network Bandwidth | Depends on CPU Power | Depends on Network Bandwidth |
| Transcode Capability | - | Yes | No |
| Simulcast/SVC Capability | - | - | Yes |
ICE candidate
Contains information about the network connection. There are two kinds, UDP and TCP. UDP is normally used. One user is assigned as the controlling agent and the other as the controlled agent.
- The controlling agent decides which candidate pair to use
- The chosen candidate pair is used until an ICE reset
UDP types
Fast, and relatively easier to recover even if the MediaStream fails
-
host: Uses the user's actual IP address -
prflx: peer reflexive; uses an IP address produced by a Symmetric NAT between the two users -
srflx: server reflexive; uses an IP address generated by a STUN/TURN server -
relay: Uses an IP address generated by a TURN server
TCP types
-
active: Attempts an outbound connection -
passive: Set up to accept connections -
so: Attempts to open the connection between users simultaneously
WebRTC Server streaming
Yes it is possible as the server can be one of the peers in that peer-to-peer session. If you respect the protocols and send the video in SRTP packets using VP8, the browser will play it. To help you build these components on other applications or servers, you can check this page and this project as a guide.
Now, comparing WebRTC with other streaming services... It will depend on several variables like the Codec or the protocol. But, for instance, comparing WebRTC (SRTP over UDP with VP8 Codec) against Flash (RTMP over TCP with H264 Codec), I would say that WebRTC wins.
- The player will be Flash Player against the native <code><video>
</code> tag.
- The transport would be TCP against UDP.
But of course, everything depends on what you are sending to the client.
SDP Offer/Answer
See JavaScript Session Establishment Protocol (JSEP) for details.
TypeScript development setup
no-undef error
Using a symbol such as RTCConfiguration may produce an ESLint error (no-undef) like this:
The symbol is defined in the dom lib of TypeScript. Add the following to compilerOptions:
Or install the type symbols,
and add the type to compilerOptions as follows:
If it still does not work, register global symbols in ESLint:
"eslintConfig": {
"root": true,
"env": {
"browser": true,
"node": true
},
"globals": {
"RTCIceGatheringState": true,
"RTCIceServer": true,
"RTCConfiguration": true,
"RTCSessionDescriptionInit": true,
"RTCErrorEvent": true
},
Sample URLs
Troubleshooting
stun:localhost is not connect
See Session Traversal Utilities for NAT#stun:localhost is not connect.
ICE failed, your TURN server appears to be broken, see about:webrtc for more details
If the STUN or TURN server is on localhost and you use Firefox, change the setting below on the about:config page.
ICE failed, add a TURN server and see about:webrtc for more details
In Firefox, if the host information of candidate in the RTCPeerConnection.onicecandidate event comes in a form like 127.0.0.1, or if event.candidate is not Null but the value of event.candidate.candidate is an empty string "", it is a good idea to check the connection URL. Do not connect via an address like 0.0.0.0.
Normal case:
RTCIceCandidate { candidate: "candidate:0 1 UDP 2122252543 192.168.1.10 50077 typ host", sdpMid: "2", sdpMLineIndex: 2, usernameFragment: "2c97a5b3" }
RTCIceCandidate { candidate: "candidate:2 1 TCP 2105524479 192.168.1.10 9 typ host tcptype active", sdpMid: "2", sdpMLineIndex: 2, usernameFragment: "2c97a5b3" }
RTCIceCandidate { candidate: "candidate:0 1 UDP 2122252543 192.168.1.10 49330 typ host", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "2c97a5b3" }
RTCIceCandidate { candidate: "candidate:2 1 TCP 2105524479 192.168.1.10 9 typ host tcptype active", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "2c97a5b3" }
RTCIceCandidate { candidate: "candidate:0 2 UDP 2122252542 192.168.1.10 50790 typ host", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "2c97a5b3" }
RTCIceCandidate { candidate: "candidate:2 2 TCP 2105524478 192.168.1.10 9 typ host tcptype active", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "2c97a5b3" }
RTCIceCandidate { candidate: "candidate:0 1 UDP 2122252543 192.168.1.10 64160 typ host", sdpMid: "1", sdpMLineIndex: 1, usernameFragment: "2c97a5b3" }
RTCIceCandidate { candidate: "candidate:2 1 TCP 2105524479 192.168.1.10 9 typ host tcptype active", sdpMid: "1", sdpMLineIndex: 1, usernameFragment: "2c97a5b3" }
RTCIceCandidate { candidate: "candidate:0 2 UDP 2122252542 192.168.1.10 58270 typ host", sdpMid: "1", sdpMLineIndex: 1, usernameFragment: "2c97a5b3" }
RTCIceCandidate { candidate: "candidate:2 2 TCP 2105524478 192.168.1.10 9 typ host tcptype active", sdpMid: "1", sdpMLineIndex: 1, usernameFragment: "2c97a5b3" }
Abnormal case:
RTCIceCandidate { candidate: "candidate:0 1 UDP 2122252543 127.0.0.1 49837 typ host", sdpMid: "2", sdpMLineIndex: 2, usernameFragment: "4ecc8976" }
RTCIceCandidate { candidate: "candidate:2 1 TCP 2105524479 127.0.0.1 9 typ host tcptype active", sdpMid: "2", sdpMLineIndex: 2, usernameFragment: "4ecc8976" }
RTCIceCandidate { candidate: "candidate:2 1 TCP 2105524479 127.0.0.1 9 typ host tcptype active", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "4ecc8976" }
RTCIceCandidate { candidate: "candidate:2 2 TCP 2105524478 127.0.0.1 9 typ host tcptype active", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "4ecc8976" }
RTCIceCandidate { candidate: "", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "4ecc8976" }
RTCIceCandidate { candidate: "candidate:2 1 TCP 2105524479 127.0.0.1 9 typ host tcptype active", sdpMid: "1", sdpMLineIndex: 1, usernameFragment: "4ecc8976" }
RTCIceCandidate { candidate: "candidate:2 2 TCP 2105524478 127.0.0.1 9 typ host tcptype active", sdpMid: "1", sdpMLineIndex: 1, usernameFragment: "4ecc8976" }
RTCIceCandidate { candidate: "", sdpMid: "1", sdpMLineIndex: 1, usernameFragment: "4ecc8976" }
Sending a Close signal to the remote Peer
- Stackoverflow - Detecting that the peer's browser was closed in a webrtc videochat
- Stackoverflow - Why does calling
RTCPeerConnection.close()not sendclosedevent? - Stackoverflow - WebRTC issue on closing peer connection in have-local-offer state
When you close a peer, the remote peer does not receive the close immediately. (A typical example is when connected over UDP.) This is because signaling is done through ICE. When signaling through ICE, about 5 seconds are needed for the ICE check.
If you want to close immediately, you must close it yourself using a method such as JSEP.
Alternatively, create a DataChannel connected over SCTP and terminate when the DataChannel closes.
See also
Favorite site
-
WebRTC website - WebRTC Home - WebRTC
- Google Groups - discuss-webrtc
- Wikipedia (en) description of WebRTC
- A collection of WebRTC technical acronyms - Mozilla Web Tech Blog
- RTCS: A challenge for real-time web services 1
- WebRTC in the real world: STUN, TURN and signaling
- Getting Started with WebRTC
Documentation
- [Recommended] Signaling and video calling - Web API | MDN
Guide
- [Recommended] JIYUN.ME | WebRTC overview 4
- WebRTC Basic – cryingnavi – Assorted development stories
- [Recommended] 7 ways to stream RTSP on the page 5
- Embedding a WebRTC player for live broadcasts to a website
- [Recommended] Browser-based WebRTC stream from RTSP IP camera with low latency
- [Recommended] Kurento - Interoperating WebRTC and IP cameras (Kurento example)
- Migrating your native/mobile application to Unified Plan/WebRTC 1 6
- WebRTC - Full Stack Python (collection of tutorials, resources)
- WebRTC: Configure Your Own TURN/STUN Server (red5, TURN, STUN, WebRTC)
Understanding WebRTC and ICE
- webrtc-story-01 - Getting WebRTC started | Doublem.org
- webrtc-story-02 - Implementing a WebRTC signaling server | Doublem.org
- How can WebRTC exchange data in real time? - Jaegeujigeu's dev blog
- clux/sdp-transform: A simple parser/writer for the Session Description Protocol
- The signaling server · webRTC-kor
Video Chat Tutorials
- Developing video conferencing with webRTC
- (webRTC) Implementing video chat with a WebRTC example. :: Annongi
- Implementing video chat with webRTC
Article
- WebRTC and the Early API
- How can WebRTC exchange data in real time? - Jaegeujigeu's dev blog
- [Figure] What is WebRTC? (Understanding STUN and TURN servers) (2)
Demo
- Github - WebRTC C++ sample
- Github - WebRTC native C++ to browser PeerConnection example
- Github - WebRTC Nuts and Bolts
- Learn end to end how WebRTC actually works, through code and examples
- You can see each step of initializing the webcam in a web page and communicating with the backend, along with logs and output
- Open source with the Front in TypeScript and the backend in Go
References
- Aiortc
- Chrome:WebRTC
- Chromium
- Closed-circuit television
- Clubhouse
- Coturn
- Go
- Google Chrome
- Interactive Connectivity Establishment
- Jam
- Janus
- JavaScript Session Establishment Protocol
- JavaScript:Libraries
- Kurento
- Libjingle
- Live Streaming
- Media Streaming
- MediaMTX
- Network address translation
- Programming
- Push technology
- Real Time Streaming Protocol
- Real-time Transport Protocol
- Red5
- RTCPeerConnection
- Secure Real-time Transport Protocol
- Server
- Session Description Protocol
- Session Traversal Utilities for NAT
- SolutionStack:FullStackDeveloper:Curriculum
- SRT
- Traversal Using Relays around NAT
- Trickle ICE
- Trystero
- Web development
- WebRTC adapter
- WebRTC Internals
- WebRTC:API
- WebRTC:IsolatedNetwork
- WebRTC:NativeCode
- WebRTC:NativeCode:GnArgumentList
- World Wide Web