diff --git a/crates/live_kit_client/examples/test_app.rs b/crates/live_kit_client/examples/test_app.rs index 8efcf6ff49..faf1b54798 100644 --- a/crates/live_kit_client/examples/test_app.rs +++ b/crates/live_kit_client/examples/test_app.rs @@ -1,9 +1,10 @@ - use std::time::Duration; use futures::StreamExt; use gpui::{actions, keymap_matcher::Binding, Menu, MenuItem}; -use live_kit_client::{LocalVideoTrack, RemoteVideoTrackUpdate, Room, LocalAudioTrack, RemoteAudioTrackUpdate}; +use live_kit_client::{ + LocalAudioTrack, LocalVideoTrack, RemoteAudioTrackUpdate, RemoteVideoTrackUpdate, Room, +}; use live_kit_server::token::{self, VideoGrant}; use log::LevelFilter; use simplelog::SimpleLogger; @@ -14,7 +15,6 @@ fn main() { SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger"); gpui::App::new(()).unwrap().run(|cx| { - #[cfg(any(test, feature = "test-support"))] println!("USING TEST LIVEKIT"); @@ -63,7 +63,9 @@ fn main() { let audio_track = LocalAudioTrack::create(); let audio_track_publication = room_a.publish_audio_track(&audio_track).await.unwrap(); - if let RemoteAudioTrackUpdate::Subscribed(track) = audio_track_updates.next().await.unwrap() { + if let RemoteAudioTrackUpdate::Subscribed(track) = + audio_track_updates.next().await.unwrap() + { let remote_tracks = room_b.remote_audio_tracks("test-participant-1"); assert_eq!(remote_tracks.len(), 1); assert_eq!(remote_tracks[0].publisher_id(), "test-participant-1"); @@ -98,9 +100,14 @@ fn main() { let display = displays.into_iter().next().unwrap(); let local_video_track = LocalVideoTrack::screen_share_for_display(&display); - let local_video_track_publication = room_a.publish_video_track(&local_video_track).await.unwrap(); + let local_video_track_publication = room_a + .publish_video_track(&local_video_track) + .await + .unwrap(); - if let RemoteVideoTrackUpdate::Subscribed(track) = video_track_updates.next().await.unwrap() { + if let RemoteVideoTrackUpdate::Subscribed(track) = + video_track_updates.next().await.unwrap() + { let remote_video_tracks = room_b.remote_video_tracks("test-participant-1"); assert_eq!(remote_video_tracks.len(), 1); assert_eq!(remote_video_tracks[0].publisher_id(), "test-participant-1"); diff --git a/crates/live_kit_client/src/live_kit_client.rs b/crates/live_kit_client/src/live_kit_client.rs index 2ded570828..0467018c00 100644 --- a/crates/live_kit_client/src/live_kit_client.rs +++ b/crates/live_kit_client/src/live_kit_client.rs @@ -4,7 +4,7 @@ pub mod prod; pub use prod::*; #[cfg(any(test, feature = "test-support"))] -mod test; +pub mod test; #[cfg(any(test, feature = "test-support"))] pub use test::*; diff --git a/crates/live_kit_client/src/prod.rs b/crates/live_kit_client/src/prod.rs index b56ab3d968..6ae493d306 100644 --- a/crates/live_kit_client/src/prod.rs +++ b/crates/live_kit_client/src/prod.rs @@ -84,17 +84,13 @@ extern "C" { ) -> *const c_void; fn LKRemoteAudioTrackGetSid(track: *const c_void) -> CFStringRef; - fn LKRemoteAudioTrackStart( - track: *const c_void, - callback: extern "C" fn(*mut c_void, bool), - callback_data: *mut c_void - ); + // fn LKRemoteAudioTrackStart( + // track: *const c_void, + // callback: extern "C" fn(*mut c_void, bool), + // callback_data: *mut c_void + // ); - fn LKVideoTrackAddRenderer( - track: *const c_void, - renderer: *const c_void - , - ); + fn LKVideoTrackAddRenderer(track: *const c_void, renderer: *const c_void); fn LKRemoteVideoTrackGetSid(track: *const c_void) -> CFStringRef; fn LKDisplaySources( @@ -537,7 +533,7 @@ impl Drop for LocalTrackPublication { #[derive(Debug)] pub struct RemoteAudioTrack { - native_track: *const c_void, + _native_track: *const c_void, sid: Sid, publisher_id: String, } @@ -548,7 +544,7 @@ impl RemoteAudioTrack { CFRetain(native_track); } Self { - native_track, + _native_track: native_track, sid, publisher_id, } @@ -561,24 +557,6 @@ impl RemoteAudioTrack { pub fn publisher_id(&self) -> &str { &self.publisher_id } - - pub fn start(&self) -> futures::channel::oneshot::Receiver { - let (tx, rx) = futures::channel::oneshot::channel(); - - extern "C" fn on_start(callback_data: *mut c_void, success: bool) { - unsafe { - let tx = - Box::from_raw(callback_data as *mut futures::channel::oneshot::Sender); - tx.send(success).ok(); - } - } - - unsafe { - LKRemoteAudioTrackStart(self.native_track, on_start, Box::into_raw(Box::new(tx)) as *mut c_void) - } - - rx - } } #[derive(Debug)] diff --git a/crates/live_kit_client/src/test.rs b/crates/live_kit_client/src/test.rs index 92781942d6..2f89617363 100644 --- a/crates/live_kit_client/src/test.rs +++ b/crates/live_kit_client/src/test.rs @@ -67,7 +67,7 @@ impl TestServer { } } - async fn create_room(&self, room: String) -> Result<()> { + pub async fn create_room(&self, room: String) -> Result<()> { self.background.simulate_random_delay().await; let mut server_rooms = self.rooms.lock(); if server_rooms.contains_key(&room) { @@ -104,7 +104,7 @@ impl TestServer { room_name )) } else { - for track in &room.tracks { + for track in &room.video_tracks { client_room .0 .lock() @@ -182,7 +182,7 @@ impl TestServer { frames_rx: local_track.frames_rx.clone(), }); - room.tracks.push(track.clone()); + room.video_tracks.push(track.clone()); for (id, client_room) in &room.client_rooms { if *id != identity { @@ -199,6 +199,43 @@ impl TestServer { Ok(()) } + async fn publish_audio_track( + &self, + token: String, + _local_track: &LocalAudioTrack, + ) -> Result<()> { + self.background.simulate_random_delay().await; + let claims = live_kit_server::token::validate(&token, &self.secret_key)?; + let identity = claims.sub.unwrap().to_string(); + let room_name = claims.video.room.unwrap(); + + let mut server_rooms = self.rooms.lock(); + let room = server_rooms + .get_mut(&*room_name) + .ok_or_else(|| anyhow!("room {} does not exist", room_name))?; + + let track = Arc::new(RemoteAudioTrack { + sid: nanoid::nanoid!(17), + publisher_id: identity.clone(), + }); + + room.audio_tracks.push(track.clone()); + + for (id, client_room) in &room.client_rooms { + if *id != identity { + let _ = client_room + .0 + .lock() + .audio_track_updates + .0 + .try_broadcast(RemoteAudioTrackUpdate::Subscribed(track.clone())) + .unwrap(); + } + } + + Ok(()) + } + fn video_tracks(&self, token: String) -> Result>> { let claims = live_kit_server::token::validate(&token, &self.secret_key)?; let room_name = claims.video.room.unwrap(); @@ -207,18 +244,26 @@ impl TestServer { let room = server_rooms .get_mut(&*room_name) .ok_or_else(|| anyhow!("room {} does not exist", room_name))?; - Ok(room.tracks.clone()) + Ok(room.video_tracks.clone()) } - async fn publish_audio_track(&self, _token: String, _local_track: &LocalAudioTrack) -> Result<()> { - todo!() + fn audio_tracks(&self, token: String) -> Result>> { + let claims = live_kit_server::token::validate(&token, &self.secret_key)?; + let room_name = claims.video.room.unwrap(); + + let mut server_rooms = self.rooms.lock(); + let room = server_rooms + .get_mut(&*room_name) + .ok_or_else(|| anyhow!("room {} does not exist", room_name))?; + Ok(room.audio_tracks.clone()) } } #[derive(Default)] struct TestServerRoom { client_rooms: HashMap>, - tracks: Vec>, + video_tracks: Vec>, + audio_tracks: Vec>, } impl TestServerRoom {} @@ -350,10 +395,19 @@ impl Room { } } - pub fn unpublish_track(&self, _: LocalTrackPublication) {} + pub fn unpublish_track(&self, _publication: LocalTrackPublication) {} - pub fn remote_audio_tracks(&self, _publisher_id: &str) -> Vec> { - todo!() + pub fn remote_audio_tracks(&self, publisher_id: &str) -> Vec> { + if !self.is_connected() { + return Vec::new(); + } + + self.test_server() + .audio_tracks(self.token()) + .unwrap() + .into_iter() + .filter(|track| track.publisher_id() == publisher_id) + .collect() } pub fn remote_video_tracks(&self, publisher_id: &str) -> Vec> { @@ -476,10 +530,6 @@ impl RemoteAudioTrack { pub fn publisher_id(&self) -> &str { &self.publisher_id } - - pub fn start(&self) -> futures::channel::oneshot::Receiver { - todo!(); - } } #[derive(Clone)]