use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AudioCodec {
Pcm,
}
#[derive(Debug, Clone, Copy)]
pub struct AudioFormat {
pub codec: AudioCodec,
pub bits: u8,
pub channels: u8,
pub sample_rate: u32,
}
pub trait AudioHandler: Send + Sync + 'static {
fn audio_init(&self, format: AudioFormat) -> Box<dyn AudioSession>;
fn on_volume(&self, _volume: f32) {}
fn on_metadata(&self, _metadata: &crate::proto::dmap::TrackMetadata) {}
fn on_coverart(&self, _coverart: &[u8]) {}
fn on_progress(&self, _start: u32, _current: u32, _end: u32) {}
fn on_remote_control(&self, _remote: Arc<dyn RemoteControl>) {}
fn on_client_connected(&self, _addr: &str) {}
fn on_client_disconnected(&self, _addr: &str) {}
fn on_error(&self, error: &crate::error::ShairplayError) {
tracing::warn!(%error, "AirPlay error");
}
}
#[cfg(feature = "ap2")]
pub trait PairingStore: Send + Sync + 'static {
fn get(&self, device_id: &str) -> Option<[u8; 32]>;
fn put(&self, device_id: &str, public_key: [u8; 32]);
fn remove(&self, device_id: &str);
}
#[cfg(feature = "ap2")]
#[derive(Default)]
pub struct MemoryPairingStore {
keys: std::sync::Mutex<std::collections::HashMap<String, [u8; 32]>>,
}
#[cfg(feature = "ap2")]
impl PairingStore for MemoryPairingStore {
fn get(&self, device_id: &str) -> Option<[u8; 32]> {
self.keys.lock().ok()?.get(device_id).copied()
}
fn put(&self, device_id: &str, public_key: [u8; 32]) {
if let Ok(mut keys) = self.keys.lock() {
keys.insert(device_id.to_string(), public_key);
}
}
fn remove(&self, device_id: &str) {
if let Ok(mut keys) = self.keys.lock() {
keys.remove(device_id);
}
}
}
pub trait AudioSession: Send + Sync {
fn audio_process(&mut self, samples: &[f32]);
fn audio_flush(&mut self) {}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RemoteCommand {
Play,
Pause,
NextTrack,
PreviousTrack,
SetVolume(u8),
ToggleShuffle,
ToggleRepeat,
Stop,
}
pub trait RemoteControl: Send + Sync {
fn send_command(&self, cmd: RemoteCommand) -> Result<(), crate::error::ShairplayError>;
fn available_commands(&self) -> Vec<RemoteCommand>;
}