Publish screen-sharing video track on the newly-created Room

Antonio Scandurra created

Change summary

crates/capture/src/main.rs                                              |  3 
crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift | 11 
crates/live_kit/build.rs                                                |  6 
crates/live_kit/src/live_kit.rs                                         | 48 
4 files changed, 58 insertions(+), 10 deletions(-)

Detailed changes

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();
 

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<Room>.fromOpaque(room).takeUnretainedValue();
+    let track = Unmanaged<LocalVideoTrack>.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));

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()])

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<Output = ()> {
         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<Output = ()> {
+        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 {