A high-performance, full-featured real-time communication library — WebRTC, RTP/SRTP, T.38 Fax, and RTP Latching — all through a unified PeerConnection API.
- ** Unified API** — A single
PeerConnectioninterface for all transport modes: WebRTC (ICE/DTLS/SRTP), raw RTP, SRTP-only, and T.38 fax. No fragmented APIs. - ** High performance** — ~2.8x faster than
pion(Go) and ~2.8x faster thanwebrtc-rsin throughput benchmarks. ~48% less memory thanwebrtc-rs. - ** WebRTC Compliant** — Full compliance with Chrome/WebRTC. Supports offer/answer, renegotiation, and all standard SDP attributes.
- ** Media Support** — RTP/SRTP handling for audio and video with packetizer, depacketizer, jitter buffer, NACK/FIR/PLI, TWCC, and REMB.
- ** ICE/STUN/TURN** — Full ICE implementation with STUN, TURN (UDP + TCP), ICE Lite, and nominated pair management.
- ** T.38 Fax** — Fax over IP via T.38 (UDPTL, IFP ASN.1 PER encoding, T.30 state machine). Gated behind
features = ["t38"]. - ** RTP Latching** — Dynamic remote address detection for RTP-only NAT traversal. Probation-based candidate selection with configurable observation window.
- ** Transport Modes** —
TransportMode::WebRtc(full ICE/DTLS),TransportMode::Srtp(SRTP without ICE),TransportMode::Rtp(raw RTP without encryption). - ** UPnP IGD** — Automatic port mapping via UPnP for NAT traversal without STUN/TURN.
- ** Port Range Control** — Restrict RTP/ICE ports to a specific range (
rtp_start_port/rtp_end_port) for firewall-friendly deployment. - ** RTP Rewrite Bridge** — Transparent RTP proxy/rewrite between
PeerConnectioninstances (SSRC offset, PT remap, sequence rewriting). - ** Built-in Stats** — WebRTC-compatible stats model: inbound/outbound RTP, transport, candidate pair, and data channel stats.
CPU: AMD Ryzen 7 5700X 8-Core Processor
OS 5.15.0-118-generic #128-Ubuntu
Compiler rustc 1.91.0 (f8297e351 2025-10-28), go version go1.23.0 linux/amd64
nice@miuda.ai rustrtc % cargo run -r --example benchmark
Comparison (Baseline: webrtc)
Metric | webrtc | rustrtc | pion
--------------------------------------------------------------------------------
Duration (s) | 10.07 | 10.02 | 10.13
Setup Latency (ms) | 1.36 | 0.22 | 0.90
Throughput (MB/s) | 254.55 | 713.66 | 309.11
Msg Rate (msg/s) | 260659.38 | 730788.92 | 316533.37
CPU Usage (%) | 1480.45 | 1497.50 | 1121.20
Memory (MB) | 29.00 | 15.00 | 44.00
--------------------------------------------------------------------------------
Performance Charts
==================
Throughput (MB/s) (Higher is better)
webrtc | ██████████████ 254.55
rustrtc | ████████████████████████████████████████ 713.66
pion | █████████████████ 309.11
Message Rate (msg/s) (Higher is better)
webrtc | ██████████████ 260659.38
rustrtc | ████████████████████████████████████████ 730788.92
pion | █████████████████ 316533.37
Setup Latency (ms) (Lower is better)
webrtc | ████████████████████████████████████████ 1.36
rustrtc | ██████ 0.22
pion | ██████████████████████████ 0.90
CPU Usage (%) (Lower is better)
webrtc | ███████████████████████████████████████ 1480.45
rustrtc | ████████████████████████████████████████ 1497.50
pion | █████████████████████████████ 1121.20
Memory (MB) (Lower is better)
webrtc | ██████████████████████████ 29.00
rustrtc | █████████████ 15.00
pion | ████████████████████████████████████████ 44.00Key Findings:
- Throughput:
rustrtcis ~2.8x faster thanwebrtc-rsand ~2.3x faster thanpion. - Memory:
rustrtcuses ~48% less memory thanwebrtc-rsand ~66% less thanpion. - Setup Latency: Significantly faster connection setup (0.22ms vs 1.36ms/0.90ms).
Here is a simple example of how to create a PeerConnection and handle an offer:
use rustrtc::{PeerConnection, RtcConfiguration, SessionDescription, SdpType};
#[tokio::main]
async fn main() {
let config = RtcConfiguration::default();
let pc = PeerConnection::new(config);
// Create a Data Channel
let dc = pc.create_data_channel("data", None).unwrap();
// Handle received messages
let dc_clone = dc.clone();
tokio::spawn(async move {
while let Some(event) = dc_clone.recv().await {
if let rustrtc::DataChannelEvent::Message(data) = event {
println!("Received: {:?}", String::from_utf8_lossy(&data));
}
}
});
// Create an offer
let offer = pc.create_offer().unwrap();
pc.set_local_description(offer).unwrap();
// Wait for ICE gathering to complete
pc.wait_for_gathering_complete().await;
// Get the complete SDP with candidates
let complete_offer = pc.local_description().unwrap();
println!("Offer SDP: {}", complete_offer.to_sdp_string());
}All configuration goes through RtcConfiguration (or its builder RtcConfigurationBuilder):
transport_mode—TransportMode::WebRtc(default),TransportMode::Srtp, orTransportMode::Rtp.ice_servers— STUN/TURN server list.ice_transport_policy—AllorRelay.rtp_start_port/rtp_end_port— Restrict RTP/ICE to a port range.external_ip— Override the external IP for ICE candidates (NAT scenarios).bind_ip— Bind to a specific local IP.disable_ipv6— Disable IPv6 candidate gathering.enable_ice_lite— Enable ICE Lite mode.
enable_upnp— Auto-map ports via UPnP IGD.upnp_lease_duration— UPnP port mapping lease duration in seconds (default: 3600).
enable_latching— Enable dynamic remote address detection for RTP-only mode.probation_max_packets— Number of packets to observe before committing a latched address.
media_capabilities— Configure audio/video/image (T.38) codecs and SCTP port viaMediaCapabilities.ssrc_start— Starting SSRC value for local tracks.
sctp_rto_initial,sctp_rto_min,sctp_rto_max,sctp_max_association_retransmits,sctp_receive_window,sctp_heartbeat_interval,sctp_max_heartbeat_failures,sctp_max_burst,sctp_max_cwnd
rtp_buffer_capacity— Per-SSRC receive buffer capacity.buffer_drop_strategy—DropNeworDropOldestwhen buffer is full.
use rustrtc::{
PeerConnection, RtcConfiguration, RtcConfigurationBuilder,
IceServer, TransportMode, config::T38Capability,
};
// Using builder
let config = RtcConfigurationBuilder::new()
.transport_mode(TransportMode::Rtp)
.enable_latching(true)
.probation_max_packets(Some(5))
.rtp_port_range(50000, 50100)
.enable_upnp(true)
.ice_server(IceServer::new(vec!["stun:stun.l.google.com:19302"]))
.build();
let pc = PeerConnection::new(config);// Direct field access
let mut config = RtcConfiguration::default();
config.transport_mode = TransportMode::WebRtc;
config.enable_latching = true;
config.rtp_start_port = Some(50000);
config.rtp_end_port = Some(50100);
config.enable_upnp = true;You can run the examples provided in the repository.
A multi-user video conferencing server. It receives media from each participant and forwards it to others.
-
Run the server:
cargo run --example rustrtc_sfu
-
Open your browser and navigate to
http://127.0.0.1:8081. Open multiple tabs/windows to simulate multiple users.
The echo server example demonstrates how to accept a WebRTC connection, receive data on a data channel, and echo it back. It also supports video playback if an IVF file is provided.
-
Run the server:
cargo run --example echo_server
-
Open your browser and navigate to
http://127.0.0.1:3000.
A multi-user chat room using WebRTC DataChannels.
-
Run the server:
cargo run --example datachannel_chat
-
Open your browser and navigate to
http://127.0.0.1:3000. Open multiple tabs to chat between them.
Records audio from the browser's microphone and saves it to a file (output.ulaw) on the server.
-
Run the server:
cargo run --example audio_saver
-
Open your browser and navigate to
http://127.0.0.1:3000. Click "Start" to begin recording.
Streams a video file (examples/static/output.ivf) via RTP to a UDP port, which can be played back using ffplay.
-
Run the server:
cargo run --example rtp_play
-
In a separate terminal, run
ffplay(requires ffmpeg installed):ffplay -protocol_whitelist file,udp,rtp -i examples/rtp_play.sdp
This project is licensed under the MIT License.
