1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//! RTSP 1.0 client implementation (RFC 2326).
//!
//! Pure-Rust async client that speaks the IP-camera dialect of RTSP:
//! - `OPTIONS`, `DESCRIBE`, `SETUP`, `PLAY`, `PAUSE`, `GET_PARAMETER`, `TEARDOWN`
//! - HTTP Basic and Digest (MD5, with or without `qop=auth`) authentication
//! - TCP-interleaved transport (`Transport: RTP/AVP/TCP;interleaved=N-N+1`),
//! which is the only transport that traverses NAT reliably
//! - SDP parsing sufficient to discover tracks and rtpmap/fmtp parameters
//! - RTP packet header parsing with sequence-loss / reorder / duplicate detection
//!
//! # Example
//!
//! ```ignore
//! use oximedia_net::rtsp::{RtspClient, SetupTransport};
//!
//! # async fn run() -> Result<(), Box<dyn std::error::Error>> {
//! let mut client = RtspClient::connect("rtsp://admin:secret@10.0.0.5/stream1").await?;
//! let _methods = client.options().await?;
//! let sdp = client.describe().await?;
//! let video = sdp.video().expect("expected a video track");
//! let control = video.control.as_deref().unwrap_or_default();
//! client
//! .setup(control, &SetupTransport::tcp_interleaved(0))
//! .await?;
//! client.play().await?;
//!
//! loop {
//! match client.next_event().await? {
//! oximedia_net::rtsp::ServerEvent::Packet(pkt) => {
//! let rtp = oximedia_net::rtsp::RtpPacket::parse(&pkt.data)?;
//! println!("ch={} pt={} seq={}", pkt.channel, rtp.payload_type, rtp.sequence);
//! }
//! oximedia_net::rtsp::ServerEvent::Message(_) => {}
//! }
//! }
//! # }
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use RtspUrl;