Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T01:51:43.375Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

lib.rs

254 lines · 6.7 KB · rust
1use anyhow::Context as _;
2use collections::HashMap;
3use cpal::DeviceId;
4
5mod remote_video_track_view;
6pub use remote_video_track_view::{RemoteVideoTrackView, RemoteVideoTrackViewEvent};
7use rodio::DeviceTrait as _;
8
9mod record;
10pub use record::CaptureInput;
11
12#[cfg(any(
13    rust_analyzer,
14    not(any(
15        test,
16        feature = "test-support",
17        all(target_os = "windows", target_env = "gnu"),
18        target_os = "freebsd"
19    ))
20))]
21mod livekit_client;
22#[cfg(any(
23    rust_analyzer,
24    not(any(
25        test,
26        feature = "test-support",
27        all(target_os = "windows", target_env = "gnu"),
28        target_os = "freebsd"
29    ))
30))]
31pub use livekit_client::*;
32
33#[cfg(all(
34    not(rust_analyzer),
35    any(
36        test,
37        feature = "test-support",
38        all(target_os = "windows", target_env = "gnu"),
39        target_os = "freebsd"
40    )
41))]
42mod mock_client;
43#[cfg(all(
44    not(rust_analyzer),
45    any(
46        test,
47        feature = "test-support",
48        all(target_os = "windows", target_env = "gnu"),
49        target_os = "freebsd"
50    )
51))]
52pub mod test;
53#[cfg(all(
54    not(rust_analyzer),
55    any(
56        test,
57        feature = "test-support",
58        all(target_os = "windows", target_env = "gnu"),
59        target_os = "freebsd"
60    )
61))]
62pub use mock_client::*;
63
64#[derive(Debug, Clone)]
65pub enum Participant {
66    Local(LocalParticipant),
67    Remote(RemoteParticipant),
68}
69
70#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
71pub enum ConnectionQuality {
72    Excellent,
73    Good,
74    Poor,
75    Lost,
76}
77
78#[derive(Debug, Clone)]
79pub enum TrackPublication {
80    Local(LocalTrackPublication),
81    Remote(RemoteTrackPublication),
82}
83
84impl TrackPublication {
85    pub fn sid(&self) -> TrackSid {
86        match self {
87            TrackPublication::Local(local) => local.sid(),
88            TrackPublication::Remote(remote) => remote.sid(),
89        }
90    }
91
92    pub fn is_muted(&self) -> bool {
93        match self {
94            TrackPublication::Local(local) => local.is_muted(),
95            TrackPublication::Remote(remote) => remote.is_muted(),
96        }
97    }
98}
99
100#[derive(Clone, Debug)]
101pub enum RemoteTrack {
102    Audio(RemoteAudioTrack),
103    Video(RemoteVideoTrack),
104}
105
106impl RemoteTrack {
107    pub fn sid(&self) -> TrackSid {
108        match self {
109            RemoteTrack::Audio(remote_audio_track) => remote_audio_track.sid(),
110            RemoteTrack::Video(remote_video_track) => remote_video_track.sid(),
111        }
112    }
113}
114
115#[derive(Clone, Debug)]
116pub enum LocalTrack {
117    Audio(LocalAudioTrack),
118    Video(LocalVideoTrack),
119}
120
121#[derive(Clone, Debug)]
122#[non_exhaustive]
123pub enum RoomEvent {
124    ParticipantConnected(RemoteParticipant),
125    ParticipantDisconnected(RemoteParticipant),
126    LocalTrackPublished {
127        publication: LocalTrackPublication,
128        track: LocalTrack,
129        participant: LocalParticipant,
130    },
131    LocalTrackUnpublished {
132        publication: LocalTrackPublication,
133        participant: LocalParticipant,
134    },
135    LocalTrackSubscribed {
136        track: LocalTrack,
137    },
138    TrackSubscribed {
139        track: RemoteTrack,
140        publication: RemoteTrackPublication,
141        participant: RemoteParticipant,
142    },
143    TrackUnsubscribed {
144        track: RemoteTrack,
145        publication: RemoteTrackPublication,
146        participant: RemoteParticipant,
147    },
148    TrackSubscriptionFailed {
149        participant: RemoteParticipant,
150        // error: livekit::track::TrackError,
151        track_sid: TrackSid,
152    },
153    TrackPublished {
154        publication: RemoteTrackPublication,
155        participant: RemoteParticipant,
156    },
157    TrackUnpublished {
158        publication: RemoteTrackPublication,
159        participant: RemoteParticipant,
160    },
161    TrackMuted {
162        participant: Participant,
163        publication: TrackPublication,
164    },
165    TrackUnmuted {
166        participant: Participant,
167        publication: TrackPublication,
168    },
169    RoomMetadataChanged {
170        old_metadata: String,
171        metadata: String,
172    },
173    ParticipantMetadataChanged {
174        participant: Participant,
175        old_metadata: String,
176        metadata: String,
177    },
178    ParticipantNameChanged {
179        participant: Participant,
180        old_name: String,
181        name: String,
182    },
183    ParticipantAttributesChanged {
184        participant: Participant,
185        changed_attributes: HashMap<String, String>,
186    },
187    ActiveSpeakersChanged {
188        speakers: Vec<Participant>,
189    },
190    ConnectionQualityChanged {
191        participant: Participant,
192        quality: ConnectionQuality,
193    },
194    ConnectionStateChanged(ConnectionState),
195    Connected {
196        participants_with_tracks: Vec<(RemoteParticipant, Vec<RemoteTrackPublication>)>,
197    },
198    Disconnected {
199        reason: &'static str,
200    },
201    Reconnecting,
202    Reconnected,
203}
204
205pub(crate) fn default_device(
206    input: bool,
207    device_id: Option<&DeviceId>,
208) -> anyhow::Result<(cpal::Device, cpal::SupportedStreamConfig)> {
209    let device = audio::resolve_device(device_id, input)?;
210    let config = if input {
211        device
212            .default_input_config()
213            .context("failed to get default input config")?
214    } else {
215        device
216            .default_output_config()
217            .context("failed to get default output config")?
218    };
219    Ok((device, config))
220}
221
222pub(crate) fn get_sample_data(
223    sample_format: cpal::SampleFormat,
224    data: &cpal::Data,
225) -> anyhow::Result<Vec<i16>> {
226    match sample_format {
227        cpal::SampleFormat::I8 => Ok(convert_sample_data::<i8, i16>(data)),
228        cpal::SampleFormat::I16 => Ok(data.as_slice::<i16>().unwrap().to_vec()),
229        cpal::SampleFormat::I24 => Ok(convert_sample_data::<cpal::I24, i16>(data)),
230        cpal::SampleFormat::I32 => Ok(convert_sample_data::<i32, i16>(data)),
231        cpal::SampleFormat::I64 => Ok(convert_sample_data::<i64, i16>(data)),
232        cpal::SampleFormat::U8 => Ok(convert_sample_data::<u8, i16>(data)),
233        cpal::SampleFormat::U16 => Ok(convert_sample_data::<u16, i16>(data)),
234        cpal::SampleFormat::U32 => Ok(convert_sample_data::<u32, i16>(data)),
235        cpal::SampleFormat::U64 => Ok(convert_sample_data::<u64, i16>(data)),
236        cpal::SampleFormat::F32 => Ok(convert_sample_data::<f32, i16>(data)),
237        cpal::SampleFormat::F64 => Ok(convert_sample_data::<f64, i16>(data)),
238        _ => anyhow::bail!("Unsupported sample format"),
239    }
240}
241
242pub(crate) fn convert_sample_data<
243    TSource: cpal::SizedSample,
244    TDest: cpal::SizedSample + cpal::FromSample<TSource>,
245>(
246    data: &cpal::Data,
247) -> Vec<TDest> {
248    data.as_slice::<TSource>()
249        .unwrap()
250        .iter()
251        .map(|e| e.to_sample::<TDest>())
252        .collect()
253}
254
Served at tenant.openagents/omega Member data and write actions are omitted.