diff --git a/Cargo.lock b/Cargo.lock index a9448065c9..9dbdfe1fc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2940,6 +2940,7 @@ dependencies = [ name = "live_kit" version = "0.1.0" dependencies = [ + "anyhow", "core-foundation", "core-graphics", "futures", diff --git a/crates/capture/src/main.rs b/crates/capture/src/main.rs index 66a01d976b..82a6934fa7 100644 --- a/crates/capture/src/main.rs +++ b/crates/capture/src/main.rs @@ -45,13 +45,15 @@ fn main() { cx.foreground() .spawn(async move { println!("connecting..."); - room.connect("wss://zed.livekit.cloud", &token).await; + room.connect("wss://zed.livekit.cloud", &token) + .await + .unwrap(); let windows = live_kit::list_windows(); println!("connected! {:?}", windows); let window_id = windows.iter().next().unwrap().id; let track = LocalVideoTrack::screen_share_for_window(window_id); - room.publish_video_track(&track).await; + room.publish_video_track(&track).await.unwrap(); }) .detach(); diff --git a/crates/live_kit/Cargo.toml b/crates/live_kit/Cargo.toml index 325753b7f9..d98b7eae88 100644 --- a/crates/live_kit/Cargo.toml +++ b/crates/live_kit/Cargo.toml @@ -9,6 +9,7 @@ path = "src/live_kit.rs" doctest = false [dependencies] +anyhow = "1.0.38" core-foundation = "0.9.3" core-graphics = "0.22.3" futures = "0.3" diff --git a/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift b/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift index 5d30cc4d28..a33aeeb6de 100644 --- a/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift +++ b/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift @@ -12,24 +12,24 @@ public func LKRoomCreate() -> UnsafeMutableRawPointer { } @_cdecl("LKRoomConnect") -public func LKRoomConnect(room: UnsafeRawPointer, url: CFString, token: CFString, callback: @escaping @convention(c) (UnsafeRawPointer) -> Void, callback_data: UnsafeRawPointer) { +public func LKRoomConnect(room: UnsafeRawPointer, url: CFString, token: CFString, callback: @escaping @convention(c) (UnsafeRawPointer, CFString?) -> Void, callback_data: UnsafeRawPointer) { let room = Unmanaged.fromOpaque(room).takeUnretainedValue(); room.connect(url as String, token as String).then { _ in - callback(callback_data); + callback(callback_data, UnsafeRawPointer(nil) as! CFString?); }.catch { error in - print(error); + callback(callback_data, error.localizedDescription as CFString); }; } @_cdecl("LKRoomPublishVideoTrack") -public func LKRoomPublishVideoTrack(room: UnsafeRawPointer, track: UnsafeRawPointer, callback: @escaping @convention(c) (UnsafeRawPointer) -> Void, callback_data: UnsafeRawPointer) { +public func LKRoomPublishVideoTrack(room: UnsafeRawPointer, track: UnsafeRawPointer, callback: @escaping @convention(c) (UnsafeRawPointer, CFString?) -> 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); + callback(callback_data, UnsafeRawPointer(nil) as! CFString?); }.catch { error in - print(error); + callback(callback_data, error.localizedDescription as CFString); }; } diff --git a/crates/live_kit/src/live_kit.rs b/crates/live_kit/src/live_kit.rs index a3b06cfcf6..0db2ac1e34 100644 --- a/crates/live_kit/src/live_kit.rs +++ b/crates/live_kit/src/live_kit.rs @@ -1,3 +1,4 @@ +use anyhow::{anyhow, Context, Result}; use core_foundation::{ array::CFArray, base::{TCFType, TCFTypeRef}, @@ -20,13 +21,13 @@ extern "C" { room: *const c_void, url: CFStringRef, token: CFStringRef, - callback: extern "C" fn(*mut c_void) -> (), + callback: extern "C" fn(*mut c_void, CFStringRef) -> (), callback_data: *mut c_void, ); fn LKRoomPublishVideoTrack( room: *const c_void, track: *const c_void, - callback: extern "C" fn(*mut c_void) -> (), + callback: extern "C" fn(*mut c_void, CFStringRef) -> (), callback_data: *mut c_void, ); @@ -40,7 +41,7 @@ impl Room { Self(unsafe { LKRoomCreate() }) } - pub fn connect(&self, url: &str, token: &str) -> impl Future { + pub fn connect(&self, url: &str, token: &str) -> impl Future> { let url = CFString::new(url); let token = CFString::new(token); let (did_connect, tx, rx) = Self::build_done_callback(); @@ -54,10 +55,10 @@ impl Room { ) } - async { rx.await.unwrap() } + async { rx.await.unwrap().context("error connecting to room") } } - pub fn publish_video_track(&self, track: &LocalVideoTrack) -> impl Future { + pub fn publish_video_track(&self, track: &LocalVideoTrack) -> impl Future> { let (did_publish, tx, rx) = Self::build_done_callback(); unsafe { LKRoomPublishVideoTrack( @@ -67,18 +68,23 @@ impl Room { Box::into_raw(Box::new(tx)) as *mut c_void, ) } - async { rx.await.unwrap() } + async { rx.await.unwrap().context("error publishing video track") } } fn build_done_callback() -> ( - extern "C" fn(*mut c_void), + extern "C" fn(*mut c_void, CFStringRef), *mut c_void, - oneshot::Receiver<()>, + 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(()); + extern "C" fn done_callback(tx: *mut c_void, error: CFStringRef) { + let tx = unsafe { Box::from_raw(tx as *mut oneshot::Sender>) }; + if error.is_null() { + let _ = tx.send(Ok(())); + } else { + let error = unsafe { CFString::wrap_under_get_rule(error).to_string() }; + let _ = tx.send(Err(anyhow!(error))); + } } ( done_callback,