Expand description
§Async WebRTC
webrtc is an async-friendly, runtime-agnostic WebRTC implementation in Rust.
It is built as a thin async layer on top of the battle-tested Sans-I/O rtc protocol core.
§Architecture
The crate separates protocol state from I/O using a driver-based architecture:
PeerConnection: The user-facing API handle. All operations (e.g., creating offers, adding tracks, creating data channels) are asynchronous and communicate with a background driver.PeerConnectionDriver: An internal background event loop spawned automatically. It coordinates network sockets (UDP/TCP), handles timeouts, drives the underlying Sans-I/Ortccore, and dispatches events.Runtime: A trait abstracting async operations (timers, spawning, sockets). This allows the crate to be completely runtime-agnostic.
§Async Runtime Support
The library supports multiple async runtimes through Cargo features:
| Feature | Default | Description |
|---|---|---|
runtime-tokio | ✅ | Timers, task spawning and sockets via Tokio |
runtime-smol | The same, via smol |
The two are mutually exclusive in practice, so selecting smol means turning the default off — otherwise both runtimes are compiled in:
[dependencies]
webrtc = { version = "0.20", default-features = false, features = ["runtime-smol"] }Additional runtimes (async-std, embassy) are on the roadmap behind the same
Runtime abstraction.
§Where to Start
| Module | What lives there |
|---|---|
peer_connection | PeerConnectionBuilder, the PeerConnection trait, and the PeerConnectionEventHandler you implement — start here |
data_channel | The DataChannel trait: send, try_send, and send-buffer back-pressure |
media_stream | Local and remote tracks. Sending encoded frames? TrackLocalStaticSample. Forwarding RTP? TrackLocalStaticRTP |
rtp_transceiver | The RtpSender / RtpReceiver traits and per-stream statistics |
runtime | The Runtime trait, for supplying your own executor |
error | Error and Result, re-exported so you never import from rtc-shared directly |
Beyond the Quick Start below, the repository ships 35 runnable examples covering data channels, media playback and recording, simulcast, ICE restart, and insertable streams.
§Quick Start
Below is a simple example showing how to build a PeerConnection
and initiate an SDP offer.
use webrtc::peer_connection::{
PeerConnection, PeerConnectionBuilder, PeerConnectionEventHandler,
RTCConfigurationBuilder, RTCIceServer, RTCPeerConnectionIceEvent,
};
use std::sync::Arc;
// 1. Implement the PeerConnectionEventHandler trait to handle events
#[derive(Clone)]
struct MyHandler;
#[async_trait::async_trait]
impl PeerConnectionEventHandler for MyHandler {
async fn on_ice_candidate(&self, event: RTCPeerConnectionIceEvent) {
println!("New local ICE candidate gathered: {}", event.candidate);
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 2. Configure the peer connection
let config = RTCConfigurationBuilder::default()
.with_ice_servers(vec![RTCIceServer {
urls: vec!["stun:stun.l.google.com:19302".to_owned()],
..Default::default()
}])
.build();
// 3. Build the PeerConnection
let pc = PeerConnectionBuilder::new()
.with_configuration(config)
.with_handler(Arc::new(MyHandler))
.with_udp_addrs(vec!["0.0.0.0:0"])
.build()
.await?;
// 4. Create an SDP offer and set it as local description
let offer = pc.create_offer(None).await?;
pc.set_local_description(offer).await?;
println!("Local description set successfully!");
Ok(())
}Modules§
- data_
channel - DataChannel API
- error
- Error and Result types
- media_
stream - Media Stream Tracks
- peer_
connection - PeerConnection API
- rtp_
transceiver - RTP Transceiver, Sender, and Receiver API
- runtime
- Async Runtime Abstraction