Skip to main content

RtmpClient

Struct RtmpClient 

Source
pub struct RtmpClient { /* private fields */ }

Implementations§

Source§

impl RtmpClient

Source

pub fn connect(url: &str) -> Result<Self>

Dial the given rtmp://host[:port]/app/stream_name URL, perform the full handshake + connect + createStream + publish sequence, and return a ready-to-send client.

Source

pub fn connect_with_type(url: &str, publish_type: &str) -> Result<Self>

Same as connect but lets the caller pick the RTMP publish type (typically "live", "record", or "append").

Source

pub fn connect_with_capabilities( url: &str, publish_type: &str, caps: &ConnectCapabilities, ) -> Result<Self>

Connect and advertise the supplied Enhanced RTMP v1+v2 capability block in the NetConnection connect command (enhanced-rtmp-v2.pdf §“Enhancing NetConnection connect Command”). The block is appended to the legacy Command Object in the documented order — peers that don’t speak E-RTMP keep parsing the message correctly because the extras are tacked on after the historical videoFunction field.

The server’s _result properties object is parsed for the same set of keys and stashed on the client; retrieve it via server_capabilities to learn which v1+v2 features the peer agreed to support.

Source

pub fn server_capabilities(&self) -> &ConnectCapabilities

Capability block advertised by the server in _result(connect).

Empty when the peer is pre-2023 / unaware of E-RTMP — callers can detect that with ConnectCapabilities::is_empty. Otherwise describes which FourCC codecs the server reports it can decode / encode / forward, plus the v2 capsEx bitfield (Reconnect, Multitrack, ModEx, TimestampNanoOffset).

Source

pub fn tc_url(&self) -> &str

The tcUrl this client dialled (e.g. rtmp://host:1935/app) — the base every Enhanced RTMP v2 reconnect target resolves against.

Source

pub fn resolve_reconnect_url(&self, tc_url: Option<&str>) -> String

Resolve the tcUrl carried by an Enhanced RTMP v2 ClientEvent::ReconnectRequest into the absolute URL to re-dial, per enhanced-rtmp-v2.pdf §“Reconnect Request”:

  • None → “use the tcUrl for the current connection”.
  • Some(reference) → “absolute or relative URI reference of the server to which to reconnect. A relative URI reference should be resolved relative to the tcUrl for the current connection.” All four spec example shapes are honoured: rtmp://foo.mydomain.com:1935/realtimeapp (absolute), //192.0.2.0/realtimeapp (network-path: keep our scheme), /realtimeapp (absolute-path: keep scheme + authority), and realtimeapp (relative-path: merge onto our tcUrl’s path).

Append the stream key (/{stream_name}) and feed the result to RtmpClient::connect to complete the spec’s reconnect flow.

Source

pub fn send_video_sequence_header(&mut self, avc_c: &[u8]) -> Result<()>

Send the AVC sequence header (AVCDecoderConfigurationRecord aka avcC). Must be called once before any NALU-carrying send_video.

Source

pub fn send_video( &mut self, timestamp_ms: u32, is_keyframe: bool, body: &[u8], ) -> Result<()>

Send one video access unit. body is the AVCC-formatted content (one or more [u32 length BE][NALU bytes] pairs). is_keyframe drives the FLV frame_type bits.

Source

pub fn send_audio_sequence_header(&mut self, asc: &[u8]) -> Result<()>

Send the AAC AudioSpecificConfig (2 bytes for LC-AAC 44.1k stereo: 0x12 0x10). Must be called once before any raw-frame send_audio.

Source

pub fn send_audio(&mut self, timestamp_ms: u32, aac_frame: &[u8]) -> Result<()>

Send one raw AAC frame.

Source

pub fn send_metadata(&mut self, metadata: Amf0Value) -> Result<()>

Send @setDataFrame("onMetaData", metadata). Metadata is an AMF0 value, typically an ECMA array or object populated with width, height, duration, videodatarate, framerate, videocodecid, audiodatarate, audiocodecid, etc.

Source

pub fn send_metadata_amf3(&mut self, metadata: Amf3Value) -> Result<()>

Send onMetaData as an AMF3-encoded data message (RTMP message type 15) instead of the AMF0 default.

The body is framed per AMF 3 spec §4.1 / AMF 0 spec §3.1: the outer NetConnection message structure is AMF0, and each value switches to AMF3 by prefixing it with the avmplus-object-marker (0x11). Most ingest endpoints stay on AMF0, so prefer send_metadata; this exists for peers that negotiated an AMF3 channel.

Source

pub fn send_aggregate(&mut self, subs: &[Message]) -> Result<()>

Send a batch of audio / video / data sub-messages as one Aggregate Message (RTMP 1.0 §7.1.6, message type id 22).

An aggregate trades one extra 11-byte sub-header per sub-message (plus a 4-byte back-pointer) for the chunk-header overhead the chunk writer would emit on each sub if it sent them individually. For an active publish with several A/V messages queued at the same timestamp this can cut the chunk-header surface in half.

subs carries pre-built FLV-shaped messages — typically AVC video (type 9) and AAC audio (type 8) bodies the caller has already framed via flv::build_video / flv::build_audio. Caller-supplied msg_stream_id fields are overridden to this client’s publish stream id per §7.1.6 (“the message stream ID of the aggregate message overrides the message stream IDs of the sub-messages”). The aggregate’s own wire timestamp is set to the first sub’s timestamp so the §7.1.6 re-normalisation offset is zero on the wire.

Returns the same errors as build_aggregate plus any I/O error from the underlying chunk writer. An empty subs slice is a no-op.

Source

pub fn send_ping_request(&mut self, timestamp_ms: u32) -> Result<()>

Send a UserControl PingRequest (RTMP 1.0 §3.7, UCM type 6) carrying the supplied 4-byte timestamp.

The peer is expected to echo the value back as a PingResponse (UCM type 7), which surfaces from poll_event as ClientEvent::PingResponse. Typical use is round-trip-time measurement: stamp the local monotonic clock into the request, then subtract from the response timestamp once the matching PingResponse arrives. The publish direction normally never needs this — but a publisher pumping a low-bandwidth feed over a flaky link may want to probe liveness explicitly rather than wait for TCP keepalive.

Source

pub fn poll_event(&mut self) -> Result<Option<ClientEvent>>

Poll for one server-originated event.

Reads up to one inbound RTMP message from the server, applies protocol-level housekeeping internally (set-chunk-size, window-ack-size, set-peer-bandwidth, ping-request/response, acks), and surfaces externally-visible notifications as a ClientEvent:

Returns Ok(None) once the server has signalled a clean stream end (StreamEOF) or once the TCP read half observes EOF / connection-reset. After Ok(None) is returned the caller should stop writing and finish the session with close.

This is a blocking call. Set a finite read timeout on inner_mut ahead of time if you want poll_event to return periodically with an Err(Error::Io) kind WouldBlock / TimedOut so an outer event loop can do other work between polls — the underlying TCP read deadline is the timeout granularity, not a poll interval.

Source

pub fn close(self) -> Result<()>

Send closeStream / deleteStream and shut the TCP socket.

Source

pub fn inner_mut(&mut self) -> &mut TcpStream

Source

pub fn set_read_timeout(&mut self, d: Option<Duration>) -> Result<()>

Apply a recv timeout to the chunk reader’s actual socket clone (the one poll_event blocks on) rather than the session’s bookkeeping clone.

On Linux a sockopt set through one try_clone descriptor carries to its sibling clones because they share one file description; on Windows each clone has its own kernel handle with independent socket options, so the timeout has to be installed on the exact socket the recv call will issue against. Use this rather than inner_mut.set_read_timeout(...) when the goal is to bound poll_event’s block time.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.