Early tech preview. We are early in development and several parts remain unfinished. Among the most prominent gaps right now: Windows support is mostly missing, on-device testing has been very limited, audio-video sync is quite basic, the room feature is functional but lightly tested, and the relay has no authentication yet. Frequent API changes are still to be expected.
Real-time audio and video over iroh (QUIC), written in Rust. iroh-live handles the full pipeline from camera capture through encoding, transport, decoding, and rendering. Connections are peer-to-peer by default, and an optional relay server bridges to browsers via WebTransport. The transport layer uses Media over QUIC (MoQ), where each video rendition and audio track travels as an independent QUIC stream, so a dropped video packet never blocks audio delivery.
Install the irl CLI and publish your camera and microphone:
cargo install --path iroh-live-cli --all-features
# Terminal 1: publish camera and mic, prints a ticket and QR code
irl publish
# Terminal 2: watch the stream
irl play <TICKET>For a 1:1 call:
# Side A: wait for incoming call
irl call
# Side B: dial with the ticket from side A
irl call <TICKET>To watch a stream in a browser, start a relay and open the URL it prints:
# Terminal 1: start a local relay (self-signed TLS, dev mode)
irl relay
# Terminal 2: publish to the relay
irl publish --relay <RELAY_ADDR>
# Open http://localhost:4443/?name=hello in a browser to watchFor a multi-party room (early stage, limited testing):
# First participant creates the room
irl room
# Others join with the printed ticket
irl room <TICKET>Note: Right now iroh-live uses unreleased versions of several crates. Downstream users should copy the
[patch.crates-io]section of Cargo.toml for now.
The iroh-live crate provides the high-level API. A minimal publisher that
captures camera and microphone, encodes them, and prints a ticket:
let live = Live::from_env().await?.with_router().spawn();
let broadcast = LocalBroadcast::new();
let camera = CameraCapturer::new()?;
broadcast.video().set_source(camera, VideoCodec::H264, [VideoPreset::P720])?;
let audio = AudioBackend::default();
let mic = audio.default_input().await?;
broadcast.audio().set(mic, AudioCodec::Opus, [AudioPreset::Hq])?;
live.publish("hello", &broadcast).await?;
let ticket = LiveTicket::new(live.endpoint().addr(), "hello");
println!("{ticket}");On the subscribe side, connect with a ticket and decode video frames:
let live = Live::from_env().await?.spawn();
let sub = live.subscribe(ticket.endpoint, &ticket.broadcast_name).await?;
let audio = AudioBackend::default();
let tracks = sub.media(&audio, Default::default()).await?;
if let Some(mut video) = tracks.video {
while let Some(frame) = video.next_frame().await {
// render the frame
println!("frame {}x{}", frame.dimensions[0], frame.dimensions[1]);
}
}Both snippets are extracted from a compilable example at
examples/demo.rs.
Details: docs/guide/desktop.md
Software codecs (H.264 via openh264, AV1 via rav1e/rav1d, Opus) work on every platform Rust targets. Hardware acceleration and capture depend on the OS:
| Platform | Codecs | Capture | GPU render | Status |
|---|---|---|---|---|
| Linux (Intel/AMD) | Software and VAAPI HW | PipeWire, V4L2, X11 | Vulkan and DMA-BUF zero-copy | Mostly working |
| macOS | Software and VideoToolbox | ScreenCaptureKit, AVFoundation | Metal via wgpu | Mostly working |
| Android | Software and MediaCodec HW | CameraX via JNI | EGL and HardwareBuffer zero-copy | Mostly working |
| Raspberry Pi | Software and V4L2 HW | V4L2 camera | Vulkan (RPi 5) | Mostly working |
| Windows | Software only | Not yet implemented | DX12 via wgpu | Missing |
| iOS | Software and VideoToolbox | AVFoundation | Metal via wgpu | Compiles, untested |
Details: docs/platforms.md
The irl binary is in the iroh-live-cli crate. It is a demo application
that showcases iroh-live's capabilities, using egui for its GUI. It covers
the full workflow from device discovery through publishing, playback, calls,
rooms, and running a relay server.
| Command | Description |
|---|---|
irl devices |
List cameras, screens, audio devices, and codecs |
irl publish |
Broadcast camera and microphone (default) |
irl publish --video file:<FILE> |
Stream a media file |
irl play <TICKET> |
Subscribe and render a remote broadcast |
irl call [TICKET] |
1:1 bidirectional video call |
irl room [TICKET] |
Multi-party room with participant grid |
irl record <TICKET> |
Record a remote broadcast to raw files |
irl run <CONFIG.toml> |
Multi-stream session from TOML config |
irl relay |
Start a local relay server for browser access |
Common flags for publish: --video cam, --video screen, --video test,
--video file:path.fmp4, --audio none, --codec h264, --audio-codec opus,
--video-presets 360p,720p, --relay <endpoint>, --room <ticket>.
Details: docs/cli.md
These demos are experimental and incomplete previews of what iroh-live can do.
demos/android/— Kotlin and Rust Android app with bidirectional video calling, rendered with EGL (README).demos/pi-zero/— Raspberry Pi Zero 2 W camera stream with e-paper QR code (README).demos/opengl/— Minimal GLES2 viewer using glutin and winit, no egui or wgpu.moq-media/examples/viewer.rs— Standalone egui video viewer.iroh-live/examples/split.rs— Local split-screen with full encode, transport, and decode loop on localhost, rendered with egui.
| Crate | Description |
|---|---|
iroh-live |
High-level API: live sessions, rooms, tickets. Depends on moq-media and iroh. |
iroh-moq |
MoQ transport layer over iroh/quinn via web-transport-iroh. |
moq-media |
Media pipelines: capture, encode, decode, publish, subscribe, playout, adaptive bitrate. No iroh dependency. |
rusty-codecs |
Codec implementations (H.264, AV1, Opus), VAAPI/V4L2/VideoToolbox HW accel, and wgpu rendering. |
rusty-capture |
Cross-platform screen and camera capture: PipeWire, V4L2, X11, Apple ScreenCaptureKit/AVFoundation. |
moq-media-egui |
egui integration for video rendering (wgpu texture upload, DMA-BUF import). |
moq-media-dioxus |
dioxus-native integration for video rendering. |
moq-media-android |
Android camera, EGL rendering, JNI bridge. |
iroh-live-relay |
Relay server for browser WebTransport bridging (no auth yet). |
iroh-live-cli |
CLI tool for publishing, playing, calls, and rooms. |
The default build compiles all codecs from bundled source, with no system libraries required:
cargo build --workspaceFor hardware-accelerated codecs and native capture on Linux, install development headers:
# Debian/Ubuntu
sudo apt install libpipewire-0.3-dev libspa-0.2-dev libclang-dev libva-dev
# Arch
sudo pacman -S pipewire libclang libvaThen build with all features:
cargo build --workspace --all-featuresBuild for Raspberry Pi and other aarch64 Linux devices:
cargo make cross-sysroot-aarch64 # one-time sysroot setup
cargo make cross-build-aarch64 -- -p iroh-live-cli --release # build irl CLIA Docker path is available for macOS/Windows hosts. See cross/README.md for setup, prerequisites, and the full Docker workflow.
The workspace uses many feature flags for codecs, hardware backends, and capture
sources. Most are enabled by default in the respective crates. The table below
shows the flags relevant to iroh-live (which delegates to moq-media and
rusty-codecs):
| Flag | What it enables | Default |
|---|---|---|
h264 |
H.264 codec (openh264) | Yes |
opus |
Opus audio codec | Yes |
av1 |
AV1 codec (rav1e encoder, rav1d decoder) | No |
capture |
Camera and screen capture | Yes |
vaapi |
VAAPI hardware encode and decode (Linux) | Yes |
videotoolbox |
VideoToolbox hardware codecs (macOS) | Yes |
wgpu |
GPU rendering via wgpu | Yes |
dmabuf-import |
Zero-copy VAAPI decode to Vulkan render (Linux) | Yes |
metal-import |
Zero-copy VideoToolbox decode to Metal render (macOS) | Yes |
pcm |
Raw PCM audio (no encoding) | No |
jack |
JACK audio backend via cpal | No |
v4l2 |
V4L2 hardware codecs (Raspberry Pi, embedded Linux) | No |
See DEVELOPMENT.md for workspace structure, key types, architecture notes, and build/test workflows. Open issues are tracked in the issue tracker.
# Full check (all feature combinations, clippy, fmt)
cargo make check-all
# Test
cargo test --workspace --all-featuresCopyright 2025 N0, INC.
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.