oxideav-rtmp
Pure-Rust RTMP for the
oxideav framework — accept an
incoming publisher (server / source) or push your own stream to a
remote RTMP server (client / sink). Zero external dependencies,
blocking-thread-per-connection.
Server (accept a publisher)
use ;
let server = bind?;
let req = server.accept?; // blocks until one publisher connects
if req.stream_name != "my-secret-key"
let mut session = req.accept?; // sends NetStream.Publish.Start
while let Some = session.next_packet?
Multi-client variant — one thread per connection:
server.serve?;
Client (push to a remote RTMP server)
use RtmpClient;
let mut client = connect?;
client.send_video_sequence_header?; // AVCDecoderConfigurationRecord
client.send_audio_sequence_header?; // 2-byte AudioSpecificConfig
loop
client.close?;
Scope
- RTMP (
rtmp://, plain TCP port 1935). No RTMPS yet — wrap ourRead + Writewith rustls if you need it, or request anrtmpsfeature. - Publish direction only. The server accepts incoming publishers; the client pushes to remote servers. RTMP play (subscribe / pull) is a follow-up.
- AMF0 command flow. AMF3, shared objects, RTMFP, and the Adobe digest-verified handshake are not implemented; they're essentially unused in modern ingest workflows.
- H.264 + AAC are the expected payloads. The crate passes
through FLV tag bytes verbatim, so other codecs (MP3, H.263,
Speex, …) work end-to-end but the framing helpers focus on
VIDEO_CODEC_AVC+AUDIO_FORMAT_AAC.
Reusable building blocks
The lower-level modules are public so callers can compose something non-standard:
amf::{encode, decode, encode_command, Amf0Value}chunk::{ChunkReader, ChunkWriter, Message}handshake::{client_handshake, server_handshake}flv::{parse_video, build_video, parse_audio, build_audio}message::build_*— builders for every protocol-control / command message we emit