pub trait RtmpHandler:
Send
+ Sync
+ 'static {
Show 18 methods
// Provided methods
fn on_connection<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_handshake_complete<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_connect<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_params: &'life2 ConnectParams,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn on_fc_publish<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_stream_key: &'life2 str,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn on_publish<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_params: &'life2 PublishParams,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn on_play<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_params: &'life2 PlayParams,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn on_metadata<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_metadata: &'life2 HashMap<String, AmfValue>,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn on_media_tag<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_tag: &'life2 FlvTag,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn on_video_frame<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_frame: &'life2 H264Data,
_timestamp: u32,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn on_audio_frame<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_frame: &'life2 AacData,
_timestamp: u32,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn on_keyframe<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_timestamp: u32,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_publish_stop<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_play_stop<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_pause<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_unpause<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_disconnect<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn media_delivery_mode(&self) -> MediaDeliveryMode { ... }
fn on_stats_update<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
}Expand description
Handler trait for RTMP applications
Implement this trait to customize RTMP server behavior. All methods have default implementations that accept/allow everything.
§Example
use rtmp_rs::{RtmpHandler, AuthResult};
use rtmp_rs::session::SessionContext;
use rtmp_rs::protocol::message::{ConnectParams, PublishParams};
struct MyHandler;
#[async_trait::async_trait]
impl RtmpHandler for MyHandler {
async fn on_connect(&self, ctx: &SessionContext, params: &ConnectParams) -> AuthResult {
// Validate application name
if params.app == "live" {
AuthResult::Accept
} else {
AuthResult::Reject("Unknown application".into())
}
}
async fn on_publish(&self, ctx: &SessionContext, params: &PublishParams) -> AuthResult {
// Validate stream key (e.g., check against database)
if params.stream_key.starts_with("valid_") {
AuthResult::Accept
} else {
AuthResult::Reject("Invalid stream key".into())
}
}
}Provided Methods§
Sourcefn on_connection<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_connection<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called when a new TCP connection is established
Return false to immediately close the connection. Use this for IP-based rate limiting or blocklists.
Sourcefn on_handshake_complete<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_handshake_complete<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called after successful handshake, before connect command
Sourcefn on_connect<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_params: &'life2 ConnectParams,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn on_connect<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_params: &'life2 ConnectParams,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Called on RTMP ‘connect’ command
Validate the application name, auth tokens in tcUrl, etc.
Sourcefn on_fc_publish<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_stream_key: &'life2 str,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn on_fc_publish<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_stream_key: &'life2 str,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Called on FCPublish command (OBS/Twitch compatibility)
This is called before ‘publish’ and can be used for early stream key validation.
Sourcefn on_publish<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_params: &'life2 PublishParams,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn on_publish<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_params: &'life2 PublishParams,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Called on ‘publish’ command
Validate the stream key. This is the main authentication point for publishers.
Sourcefn on_play<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_params: &'life2 PlayParams,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn on_play<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
_params: &'life2 PlayParams,
) -> Pin<Box<dyn Future<Output = AuthResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Called on ‘play’ command
Validate play access. Return Reject to deny playback.
Sourcefn on_metadata<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_metadata: &'life2 HashMap<String, AmfValue>,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn on_metadata<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_metadata: &'life2 HashMap<String, AmfValue>,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Called when stream metadata is received (@setDataFrame/onMetaData)
Sourcefn on_media_tag<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_tag: &'life2 FlvTag,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn on_media_tag<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_tag: &'life2 FlvTag,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Called for each raw FLV tag (when MediaDeliveryMode includes RawFlv)
Return true to continue processing, false to drop the tag.
Sourcefn on_video_frame<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_frame: &'life2 H264Data,
_timestamp: u32,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn on_video_frame<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_frame: &'life2 H264Data,
_timestamp: u32,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Called for each video frame (when MediaDeliveryMode includes ParsedFrames)
Sourcefn on_audio_frame<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_frame: &'life2 AacData,
_timestamp: u32,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn on_audio_frame<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_frame: &'life2 AacData,
_timestamp: u32,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Called for each audio frame (when MediaDeliveryMode includes ParsedFrames)
Sourcefn on_keyframe<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_timestamp: u32,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_keyframe<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
_timestamp: u32,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called when a keyframe is received
Sourcefn on_publish_stop<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_publish_stop<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called when the publish stream ends
Sourcefn on_play_stop<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_play_stop<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called when the play stream ends
Sourcefn on_pause<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_pause<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called when a subscriber pauses playback
Sourcefn on_unpause<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_unpause<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 StreamContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called when a subscriber resumes playback
Sourcefn on_disconnect<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_disconnect<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called when the connection closes
Sourcefn media_delivery_mode(&self) -> MediaDeliveryMode
fn media_delivery_mode(&self) -> MediaDeliveryMode
Get the media delivery mode for this handler
Sourcefn on_stats_update<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_stats_update<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called periodically with stats update