cacophony
High-performance Discord voice runtime for Rust. cacophony provides the Discord
voice transport path: voice gateway negotiation, UDP discovery, RTP send/receive,
AEAD transport crypto, Opus packet playout, DAVE coordination, and typed
connection observers.
It is designed for applications that need direct control over latency and media flow without binding the runtime to a logging, metrics, bot-framework, or audio pipeline stack.
Features
- Discord voice transport: websocket identify/select-protocol, heartbeat, UDP discovery, RTP packet construction/parsing, speaking state commands, and close-aware async send/receive APIs.
- Real-time Opus playout: bounded driver-owned media sink, clocked 20 ms Discord Opus packet scheduling, stale-frame handling, and playout timing statistics.
- Opus utilities: PCM-to-Discord-Opus streaming/batch encoding, caller-buffer decode helpers, Ogg Opus capture, and explicit 48 kHz stereo frame validation.
- DAVE integration: protocol-version negotiation, MLS external sender, proposals, commit/welcome, transition-ready, staged sender activation, and pending encrypted-media retry.
- Typed observability:
ConnectionObservercallbacks are generic, typed, and backend-agnostic. Leave them asNoopConnectionObserverfor zero application telemetry work. - Compile-time raw capture policy: normal receive returns compact media
frames; raw UDP/RTP packet retention is selected explicitly with the
FrameRawtype parameter. - Curated API boundary: high-level connection/media types live at the crate
root; protocol inspection types are grouped under
cacophony::low_level.
Current media support
cacophony negotiates and packetizes the full Discord/DAVE media set: Opus
audio plus AV1, H265, H264, VP8, and VP9 video. Opus has high-level
encode/decode and playout helpers; video callers provide encoded frames directly
and receive assembled encoded frames through the low-level media APIs.
Example
use ;
use Packet;
async
Use an observer when the application wants typed timing or protocol events without wiring tracing into the runtime:
use ;
;
async
Observer callbacks execute inline on the connection driver task. Keep them O(1), nonblocking, and allocation-light; send expensive aggregation to application-owned queues or tasks.
Raw packet retention is opt-in:
use RawFramePackets;
async
Related crates
dave: Discord DAVE media-frame transform and MLS ratchet primitives used bycacophony.
License
AGPL-3.0-only. See LICENSE for details.