rtmp_rs/client/
config.rs

1//! Client configuration
2
3use std::time::Duration;
4
5/// Client configuration
6#[derive(Debug, Clone)]
7pub struct ClientConfig {
8    /// RTMP URL to connect to (rtmp://host[:port]/app/stream)
9    pub url: String,
10
11    /// Connection timeout
12    pub connect_timeout: Duration,
13
14    /// Read timeout
15    pub read_timeout: Duration,
16
17    /// Enable TCP_NODELAY
18    pub tcp_nodelay: bool,
19
20    /// Flash version string to send
21    pub flash_ver: String,
22
23    /// SWF URL to send
24    pub swf_url: Option<String>,
25
26    /// Page URL to send
27    pub page_url: Option<String>,
28
29    /// Receive buffer size in milliseconds
30    pub buffer_length: u32,
31}
32
33impl Default for ClientConfig {
34    fn default() -> Self {
35        Self {
36            url: String::new(),
37            connect_timeout: Duration::from_secs(10),
38            read_timeout: Duration::from_secs(30),
39            tcp_nodelay: true,
40            flash_ver: "LNX 9,0,124,2".to_string(),
41            swf_url: None,
42            page_url: None,
43            buffer_length: 1000,
44        }
45    }
46}
47
48impl ClientConfig {
49    /// Create a new config with the given URL
50    pub fn new(url: impl Into<String>) -> Self {
51        Self {
52            url: url.into(),
53            ..Default::default()
54        }
55    }
56
57    /// Parse URL into components
58    pub fn parse_url(&self) -> Option<ParsedUrl> {
59        // rtmp://host[:port]/app[/stream]
60        let url = self.url.strip_prefix("rtmp://")?;
61
62        let (host_port, path) = url.split_once('/')?;
63        let (host, port) = if let Some((h, p)) = host_port.split_once(':') {
64            (h.to_string(), p.parse().ok()?)
65        } else {
66            (host_port.to_string(), 1935)
67        };
68
69        let (app, stream_key) = if let Some((a, s)) = path.split_once('/') {
70            (a.to_string(), Some(s.to_string()))
71        } else {
72            (path.to_string(), None)
73        };
74
75        Some(ParsedUrl {
76            host,
77            port,
78            app,
79            stream_key,
80        })
81    }
82}
83
84/// Parsed RTMP URL components
85#[derive(Debug, Clone)]
86pub struct ParsedUrl {
87    pub host: String,
88    pub port: u16,
89    pub app: String,
90    pub stream_key: Option<String>,
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    #[test]
98    fn test_url_parsing() {
99        let config = ClientConfig::new("rtmp://localhost/live/test");
100        let parsed = config.parse_url().unwrap();
101        assert_eq!(parsed.host, "localhost");
102        assert_eq!(parsed.port, 1935);
103        assert_eq!(parsed.app, "live");
104        assert_eq!(parsed.stream_key, Some("test".into()));
105
106        let config = ClientConfig::new("rtmp://example.com:1936/app");
107        let parsed = config.parse_url().unwrap();
108        assert_eq!(parsed.host, "example.com");
109        assert_eq!(parsed.port, 1936);
110        assert_eq!(parsed.app, "app");
111        assert_eq!(parsed.stream_key, None);
112    }
113}