Expand description
A reusable multi-client SFU (Selective Forwarding Unit) kit built on top of str0m.
str0m is a sans-I/O Rust WebRTC library — you plug in your own networking.
This crate adds the multi-client glue: per-peer state machines, UDP packet
routing, event fanout, and simulcast layer forwarding. It does not replace
str0m; it connects multiple str0m Rtc instances together into
a functioning room.
§What this gives you
Client— per-peer state wrapping a str0mRtcinstance. Handlespoll_output, incoming datagrams, keyframe requests, and simulcast layer filtering.Registry— room-level packet router. Routes UDP datagrams to the correct peer viartc.accepts(), drivespoll_all, and fans out events to every non-origin peer.Propagated— the event enum flowing between the registry and clients.SfuConfig— runtime configuration (UDP port, bind address).run_udp_loop— a ready-to-use async UDP receive loop for the simple single-room case.
§Quick start
use std::sync::Arc;
use oxpulse_sfu_kit::{Client, Registry, SfuConfig, SfuRtcBuilder, udp_loop};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let config = SfuConfig {
udp_port: 3478,
..SfuConfig::default()
};
// Shutdown on Ctrl-C.
let shutdown = async { tokio::signal::ctrl_c().await.unwrap() };
udp_loop::run_udp_loop(config, shutdown).await
}Clients are inserted into the registry via Registry::insert after
completing ICE/DTLS signaling (your responsibility — bring your own
WebSocket/HTTP signaling layer).
§Feature flags
| Feature | What it enables |
|---|---|
active-speaker | Dominant speaker detection via rust-dominant-speaker. Adds Propagated::ActiveSpeakerChanged and Registry::tick_active_speaker / Registry::record_audio_level. |
metrics-prometheus | Prometheus counters exposed via SfuMetrics. The library carries the handles; you choose how to expose them (e.g. via axum). |
test-utils | Exposes test seam helpers (test_seed module, Registry::*_for_tests methods). Gate your own tests on this. |
§Not included (by design)
- Signaling (bring your own — WebSocket, HTTP, gRPC)
- TURN server (run coturn or similar alongside)
- End-to-end encryption payload processing (use SFrame; see
sframe::KeyEpoch) - Server-side audio/video mixing (MCU mode)
- WHIP / WHEP ingestion endpoints
§Examples
examples/basic-sfu.rs— a complete single-node SFU that binds a UDP port and handles signaling stubs. Run withcargo run --example basic-sfu --features active-speaker,metrics-prometheus.
§Relationship to str0m
We build on str0m’s Rtc state machine. We do not replace it — we connect
multiple instances together for multi-party rooms. All credit for the
underlying protocol work goes to Martin Algesten
and the str0m contributors.
§Extracted from
Originally built as part of OxPulse Chat. Published standalone for the broader Rust WebRTC ecosystem.
Re-exports§
pub use av1::Av1DdInfo;av1-ddpub use bandwidth::BandwidthEstimate;pub use bwe::feedback::TwccFeedback;kalman-bwepub use bwe::feedback::TwccSample;kalman-bwepub use bwe::kalman::DelayEstimator;kalman-bwepub use bwe::loss::LossEstimator;kalman-bwepub use bwe::subscriber::ClientHint;kalman-bwepub use bwe::subscriber::PerSubscriber;kalman-bwepub use bwe::BandwidthEstimator;kalman-bwepub use bwe::GoogCcEstimator;googcc-bwepub use bwe::PacerAction;pacerpub use bwe::SubscriberPacer;pacerpub use bwe::PacerConfig;pacerpub use bwe::PacerConfigError;pacerpub use cc::CongestionControl;pub use cc::DefaultGoogCC;pub use client::Client;pub use client::TrackIn;pub use config::SfuConfig;pub use dc::ChannelConfig;pub use ids::InvalidRid;pub use ids::SfuMid;pub use ids::SfuPt;pub use ids::SfuRid;pub use keyframe::SfuKeyframeKind;pub use keyframe::SfuKeyframeRequest;pub use layer_selector::BestFitSelector;pub use layer_selector::LayerSelector;pub use media::SfuMediaKind;pub use media::SfuMediaPayload;pub use metrics::SfuMetrics;pub use net::IncomingDatagram;pub use net::OutgoingDatagram;pub use net::SfuProtocol;pub use origin::ClientOrigin;pub use propagate::ClientId;pub use propagate::Propagated;pub use raw::rtc_config;pub use registry::Registry;pub use rtc::SfuRtc;pub use rtc::SfuRtcBuilder;pub use rtcp_stats::PeerRtcpStats;pub use sframe::KeyEpoch;pub use udp_loop::bind;pub use udp_loop::run_udp_loop;pub use udp_loop::serve;pub use udp_loop::serve_socket;pub use vfm::FrameMarkingInfo;vfm
Modules§
- av1
av1-dd - AV1 codec support (
feature = "av1-dd"). - bandwidth
- Bandwidth estimation types for the kit.
- bwe
pacerorkalman-bweorgoogcc-bwe - Bandwidth-adaptive layer selection ().
- cc
- Congestion control plugin seam.
- client
- Per-peer state machine wrapping a str0m
Rtcinstance. - config
- SFU runtime configuration.
- dc
- DataChannel configuration wrappers.
- fanout
- Cross-client event fanout.
- ids
- Opaque newtype wrappers for str0m identifier types.
- keyframe
- Keyframe request wrapper.
- layer_
selector - Trait for per-subscriber simulcast layer selection.
- media
- Media payload wrapper over
str0m::media::MediaData. - metrics
- Prometheus metrics for the SFU.
- net
- UDP datagram wrappers over
str0m::net::{Protocol, Transmit}. - origin
- Publisher origin — local client or upstream SFU relay connection.
- propagate
- Cross-client propagated events.
- raw
- Escape hatch for advanced str0m access.
- registry
- Multi-client registry — routes UDP datagrams to the owning client and fans
out propagated events. Single-task ownership model (no
Arc<RwLock>). - rtc
- Opaque SFU-owned handle over a str0m
Rtcstate machine. - rtcp_
stats - Per-peer RTCP-derived stats.
- sframe
- SFrame (RFC 9605) key-epoch forwarding seam.
- udp_
loop - Async UDP socket loop.
- vfm
vfm - Video Frame Marking RTP header extension (
feature = "vfm").
Structs§
- RawRtc
- The underlying str0m
Rtc. Semver-exempt. Instance that does WebRTC. Main struct of the entire library. - RawRtc
Config - The underlying str0m
RtcConfigbuilder. Semver-exempt. Customized config for creating anRtcinstance.