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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! An embeddable AirPlay 2 audio **receiver**: a real Mac/iPhone discovers
//! it, pairs with it, and streams to it; the host application gets decoded
//! PCM and session events. The library owns network → PCM (discovery
//! advertisement, transient pairing, the encrypted control channel, the
//! buffered-audio channel, decrypt, AAC decode, and the pause/seek/
//! backpressure semantics); the host owns PCM → speaker via an [`AudioSink`].
//!
//! Deliberate scope: one sender → one stream → one output. No PTP — for a
//! single output, the sender's buffering plus this library's backpressure
//! suffice (blocking [`AudioSink::write`] paces playback). No AirPlay wire
//! concepts (plists, `shk`, sequence numbers) appear in this API.
//!
//! ```no_run
//! use openairplay2::{AudioSink, Event, Receiver};
//!
//! struct MySink;
//!
//! impl AudioSink for MySink {
//! fn write(&mut self, pcm: &[i16]) { /* blocking write paces playback */ }
//! fn flush(&mut self) { /* seek: drop device/prebuffer state */ }
//! }
//!
//! #[tokio::main]
//! async fn main() -> std::io::Result<()> {
//! let receiver = Receiver::builder()
//! .name("Office")
//! .identity_path("/var/lib/myapp/airplay-identity")
//! .build()?;
//! let (events, mut rx) = tokio::sync::mpsc::unbounded_channel();
//! tokio::spawn(async move {
//! while let Some(event) = rx.recv().await {
//! if let Event::Volume { db } = event { /* your gain path */ }
//! }
//! });
//! receiver.run(|_rate, _channels| Box::new(MySink), events).await
//! }
//! ```
// Sender-side pieces the integration tests (and a future test-sender) drive
// the real server with. Public so the tests can reach them, but not part of
// the documented embedding API.
pub use ;
pub use Identity;
pub use txt_records;
pub use ;
pub use ;
/// Receiver-wide configuration, resolved by [`ReceiverBuilder::build`].