diff --git a/crates/capture/src/main.rs b/crates/capture/src/main.rs index 07d284b7b7..66a01d976b 100644 --- a/crates/capture/src/main.rs +++ b/crates/capture/src/main.rs @@ -41,7 +41,7 @@ fn main() { ) .unwrap(); - let room = live_kit::Room::new(); + let room = Room::new(); cx.foreground() .spawn(async move { println!("connecting..."); @@ -51,6 +51,7 @@ fn main() { let window_id = windows.iter().next().unwrap().id; let track = LocalVideoTrack::screen_share_for_window(window_id); + room.publish_video_track(&track).await; }) .detach(); diff --git a/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift b/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift index a5783d69b4..5d30cc4d28 100644 --- a/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift +++ b/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift @@ -22,6 +22,17 @@ public func LKRoomConnect(room: UnsafeRawPointer, url: CFString, token: CFString }; } +@_cdecl("LKRoomPublishVideoTrack") +public func LKRoomPublishVideoTrack(room: UnsafeRawPointer, track: UnsafeRawPointer, callback: @escaping @convention(c) (UnsafeRawPointer) -> Void, callback_data: UnsafeRawPointer) { + let room = Unmanaged.fromOpaque(room).takeUnretainedValue(); + let track = Unmanaged.fromOpaque(track).takeUnretainedValue(); + room.localParticipant?.publishVideoTrack(track: track).then { _ in + callback(callback_data); + }.catch { error in + print(error); + }; +} + @_cdecl("LKCreateScreenShareTrackForWindow") public func LKCreateScreenShareTrackForWindow(windowId: uint32) -> UnsafeMutableRawPointer { let track = LocalVideoTrack.createMacOSScreenShareTrack(source: .window(id: windowId)); diff --git a/crates/live_kit/build.rs b/crates/live_kit/build.rs index 06f49c6618..4f23cc4e92 100644 --- a/crates/live_kit/build.rs +++ b/crates/live_kit/build.rs @@ -37,7 +37,11 @@ fn main() { } fn build_bridge(swift_target: &SwiftTarget) { - println!("cargo:rerun-if-changed={}", SWIFT_PACKAGE_NAME); + println!("cargo:rerun-if-changed={}/Sources", SWIFT_PACKAGE_NAME); + println!( + "cargo:rerun-if-changed={}/Package.swift", + SWIFT_PACKAGE_NAME + ); let swift_package_root = swift_package_root(); if !Command::new("swift") .args(&["build", "-c", &env::var("PROFILE").unwrap()]) diff --git a/crates/live_kit/src/live_kit.rs b/crates/live_kit/src/live_kit.rs index 7ea94298fd..a3b06cfcf6 100644 --- a/crates/live_kit/src/live_kit.rs +++ b/crates/live_kit/src/live_kit.rs @@ -14,6 +14,7 @@ use std::ffi::c_void; extern "C" { fn LKRelease(object: *const c_void); + fn LKRoomCreate() -> *const c_void; fn LKRoomConnect( room: *const c_void, @@ -22,6 +23,13 @@ extern "C" { callback: extern "C" fn(*mut c_void) -> (), callback_data: *mut c_void, ); + fn LKRoomPublishVideoTrack( + room: *const c_void, + track: *const c_void, + callback: extern "C" fn(*mut c_void) -> (), + callback_data: *mut c_void, + ); + fn LKCreateScreenShareTrackForWindow(windowId: u32) -> *const c_void; } @@ -35,25 +43,49 @@ impl Room { pub fn connect(&self, url: &str, token: &str) -> impl Future { let url = CFString::new(url); let token = CFString::new(token); - - let (tx, rx) = oneshot::channel(); - extern "C" fn did_connect(tx: *mut c_void) { - let tx = unsafe { Box::from_raw(tx as *mut oneshot::Sender<()>) }; - let _ = tx.send(()); - } - + let (did_connect, tx, rx) = Self::build_done_callback(); unsafe { LKRoomConnect( self.0, url.as_concrete_TypeRef(), token.as_concrete_TypeRef(), did_connect, - Box::into_raw(Box::new(tx)) as *mut c_void, + tx, ) } async { rx.await.unwrap() } } + + pub fn publish_video_track(&self, track: &LocalVideoTrack) -> impl Future { + let (did_publish, tx, rx) = Self::build_done_callback(); + unsafe { + LKRoomPublishVideoTrack( + self.0, + track.0, + did_publish, + Box::into_raw(Box::new(tx)) as *mut c_void, + ) + } + async { rx.await.unwrap() } + } + + fn build_done_callback() -> ( + extern "C" fn(*mut c_void), + *mut c_void, + oneshot::Receiver<()>, + ) { + let (tx, rx) = oneshot::channel(); + extern "C" fn done_callback(tx: *mut c_void) { + let tx = unsafe { Box::from_raw(tx as *mut oneshot::Sender<()>) }; + let _ = tx.send(()); + } + ( + done_callback, + Box::into_raw(Box::new(tx)) as *mut c_void, + rx, + ) + } } impl Drop for Room {