Remove 2 suffix from live_kit_client
Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
ce4bc994e7
commit
3c81dda8e2
21 changed files with 199 additions and 2725 deletions
|
@ -23,7 +23,7 @@ test-support = [
|
|||
|
||||
[dependencies]
|
||||
collections = { path = "../collections", optional = true }
|
||||
gpui = { path = "../gpui", optional = true }
|
||||
gpui = { package = "gpui2", path = "../gpui2", optional = true }
|
||||
live_kit_server = { path = "../live_kit_server", optional = true }
|
||||
media = { path = "../media" }
|
||||
|
||||
|
@ -41,7 +41,7 @@ nanoid = { version ="0.4", optional = true}
|
|||
|
||||
[dev-dependencies]
|
||||
collections = { path = "../collections", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
|
||||
live_kit_server = { path = "../live_kit_server" }
|
||||
media = { path = "../media" }
|
||||
nanoid = "0.4"
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
"repositoryURL": "https://github.com/apple/swift-protobuf.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "0af9125c4eae12a4973fb66574c53a54962a9e1e",
|
||||
"version": "1.21.0"
|
||||
"revision": "ce20dc083ee485524b802669890291c0d8090170",
|
||||
"version": "1.22.1"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -61,12 +61,14 @@ fn build_bridge(swift_target: &SwiftTarget) {
|
|||
|
||||
let swift_package_root = swift_package_root();
|
||||
let swift_target_folder = swift_target_folder();
|
||||
let swift_cache_folder = swift_cache_folder();
|
||||
if !Command::new("swift")
|
||||
.arg("build")
|
||||
.arg("--disable-automatic-resolution")
|
||||
.args(["--configuration", &env::var("PROFILE").unwrap()])
|
||||
.args(["--triple", &swift_target.target.triple])
|
||||
.args(["--build-path".into(), swift_target_folder])
|
||||
.args(["--cache-path".into(), swift_cache_folder])
|
||||
.current_dir(&swift_package_root)
|
||||
.status()
|
||||
.unwrap()
|
||||
|
@ -133,9 +135,17 @@ fn swift_package_root() -> PathBuf {
|
|||
}
|
||||
|
||||
fn swift_target_folder() -> PathBuf {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
env::current_dir()
|
||||
.unwrap()
|
||||
.join(format!("../../target/{SWIFT_PACKAGE_NAME}"))
|
||||
.join(format!("../../target/{target}/{SWIFT_PACKAGE_NAME}_target"))
|
||||
}
|
||||
|
||||
fn swift_cache_folder() -> PathBuf {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
env::current_dir()
|
||||
.unwrap()
|
||||
.join(format!("../../target/{target}/{SWIFT_PACKAGE_NAME}_cache"))
|
||||
}
|
||||
|
||||
fn copy_dir(source: &Path, destination: &Path) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::time::Duration;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use futures::StreamExt;
|
||||
use gpui::{actions, keymap_matcher::Binding, Menu, MenuItem};
|
||||
use gpui::{actions, KeyBinding};
|
||||
use live_kit_client::{
|
||||
LocalAudioTrack, LocalVideoTrack, RemoteAudioTrackUpdate, RemoteVideoTrackUpdate, Room,
|
||||
};
|
||||
|
@ -9,30 +9,32 @@ use live_kit_server::token::{self, VideoGrant};
|
|||
use log::LevelFilter;
|
||||
use simplelog::SimpleLogger;
|
||||
|
||||
actions!(capture, [Quit]);
|
||||
actions!(live_kit_client, [Quit]);
|
||||
|
||||
fn main() {
|
||||
SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
|
||||
|
||||
gpui::App::new(()).unwrap().run(|cx| {
|
||||
gpui::App::production(Arc::new(())).run(|cx| {
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
println!("USING TEST LIVEKIT");
|
||||
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
println!("USING REAL LIVEKIT");
|
||||
|
||||
cx.platform().activate(true);
|
||||
cx.add_global_action(quit);
|
||||
cx.activate(true);
|
||||
|
||||
cx.add_bindings([Binding::new("cmd-q", Quit, None)]);
|
||||
cx.set_menus(vec![Menu {
|
||||
name: "Zed",
|
||||
items: vec![MenuItem::Action {
|
||||
name: "Quit",
|
||||
action: Box::new(Quit),
|
||||
os_action: None,
|
||||
}],
|
||||
}]);
|
||||
cx.on_action(quit);
|
||||
cx.bind_keys([KeyBinding::new("cmd-q", Quit, None)]);
|
||||
|
||||
// todo!()
|
||||
// cx.set_menus(vec![Menu {
|
||||
// name: "Zed",
|
||||
// items: vec![MenuItem::Action {
|
||||
// name: "Quit",
|
||||
// action: Box::new(Quit),
|
||||
// os_action: None,
|
||||
// }],
|
||||
// }]);
|
||||
|
||||
let live_kit_url = std::env::var("LIVE_KIT_URL").unwrap_or("http://localhost:7880".into());
|
||||
let live_kit_key = std::env::var("LIVE_KIT_KEY").unwrap_or("devkey".into());
|
||||
|
@ -100,7 +102,7 @@ fn main() {
|
|||
}
|
||||
|
||||
println!("Pausing for 5 seconds to test audio, make some noise!");
|
||||
let timer = cx.background().timer(Duration::from_secs(5));
|
||||
let timer = cx.background_executor().timer(Duration::from_secs(5));
|
||||
timer.await;
|
||||
let remote_audio_track = room_b
|
||||
.remote_audio_tracks("test-participant-1")
|
||||
|
@ -163,12 +165,12 @@ fn main() {
|
|||
panic!("unexpected message");
|
||||
}
|
||||
|
||||
cx.platform().quit();
|
||||
cx.update(|cx| cx.shutdown()).ok();
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
}
|
||||
|
||||
fn quit(_: &Quit, cx: &mut gpui::AppContext) {
|
||||
cx.platform().quit();
|
||||
cx.quit();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,29 @@ use std::{
|
|||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
// SAFETY: Most live kit types are threadsafe:
|
||||
// https://github.com/livekit/client-sdk-swift#thread-safety
|
||||
macro_rules! pointer_type {
|
||||
($pointer_name:ident) => {
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct $pointer_name(pub *const std::ffi::c_void);
|
||||
unsafe impl Send for $pointer_name {}
|
||||
};
|
||||
}
|
||||
|
||||
mod swift {
|
||||
pointer_type!(Room);
|
||||
pointer_type!(LocalAudioTrack);
|
||||
pointer_type!(RemoteAudioTrack);
|
||||
pointer_type!(LocalVideoTrack);
|
||||
pointer_type!(RemoteVideoTrack);
|
||||
pointer_type!(LocalTrackPublication);
|
||||
pointer_type!(RemoteTrackPublication);
|
||||
pointer_type!(MacOSDisplay);
|
||||
pointer_type!(RoomDelegate);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn LKRoomDelegateCreate(
|
||||
callback_data: *mut c_void,
|
||||
|
@ -25,8 +48,8 @@ extern "C" {
|
|||
callback_data: *mut c_void,
|
||||
publisher_id: CFStringRef,
|
||||
track_id: CFStringRef,
|
||||
remote_track: *const c_void,
|
||||
remote_publication: *const c_void,
|
||||
remote_track: swift::RemoteAudioTrack,
|
||||
remote_publication: swift::RemoteTrackPublication,
|
||||
),
|
||||
on_did_unsubscribe_from_remote_audio_track: extern "C" fn(
|
||||
callback_data: *mut c_void,
|
||||
|
@ -46,49 +69,50 @@ extern "C" {
|
|||
callback_data: *mut c_void,
|
||||
publisher_id: CFStringRef,
|
||||
track_id: CFStringRef,
|
||||
remote_track: *const c_void,
|
||||
remote_track: swift::RemoteVideoTrack,
|
||||
),
|
||||
on_did_unsubscribe_from_remote_video_track: extern "C" fn(
|
||||
callback_data: *mut c_void,
|
||||
publisher_id: CFStringRef,
|
||||
track_id: CFStringRef,
|
||||
),
|
||||
) -> *const c_void;
|
||||
) -> swift::RoomDelegate;
|
||||
|
||||
fn LKRoomCreate(delegate: *const c_void) -> *const c_void;
|
||||
fn LKRoomCreate(delegate: swift::RoomDelegate) -> swift::Room;
|
||||
fn LKRoomConnect(
|
||||
room: *const c_void,
|
||||
room: swift::Room,
|
||||
url: CFStringRef,
|
||||
token: CFStringRef,
|
||||
callback: extern "C" fn(*mut c_void, CFStringRef),
|
||||
callback_data: *mut c_void,
|
||||
);
|
||||
fn LKRoomDisconnect(room: *const c_void);
|
||||
fn LKRoomDisconnect(room: swift::Room);
|
||||
fn LKRoomPublishVideoTrack(
|
||||
room: *const c_void,
|
||||
track: *const c_void,
|
||||
callback: extern "C" fn(*mut c_void, *mut c_void, CFStringRef),
|
||||
room: swift::Room,
|
||||
track: swift::LocalVideoTrack,
|
||||
callback: extern "C" fn(*mut c_void, swift::LocalTrackPublication, CFStringRef),
|
||||
callback_data: *mut c_void,
|
||||
);
|
||||
fn LKRoomPublishAudioTrack(
|
||||
room: *const c_void,
|
||||
track: *const c_void,
|
||||
callback: extern "C" fn(*mut c_void, *mut c_void, CFStringRef),
|
||||
room: swift::Room,
|
||||
track: swift::LocalAudioTrack,
|
||||
callback: extern "C" fn(*mut c_void, swift::LocalTrackPublication, CFStringRef),
|
||||
callback_data: *mut c_void,
|
||||
);
|
||||
fn LKRoomUnpublishTrack(room: *const c_void, publication: *const c_void);
|
||||
fn LKRoomUnpublishTrack(room: swift::Room, publication: swift::LocalTrackPublication);
|
||||
|
||||
fn LKRoomAudioTracksForRemoteParticipant(
|
||||
room: *const c_void,
|
||||
room: swift::Room,
|
||||
participant_id: CFStringRef,
|
||||
) -> CFArrayRef;
|
||||
|
||||
fn LKRoomAudioTrackPublicationsForRemoteParticipant(
|
||||
room: *const c_void,
|
||||
room: swift::Room,
|
||||
participant_id: CFStringRef,
|
||||
) -> CFArrayRef;
|
||||
|
||||
fn LKRoomVideoTracksForRemoteParticipant(
|
||||
room: *const c_void,
|
||||
room: swift::Room,
|
||||
participant_id: CFStringRef,
|
||||
) -> CFArrayRef;
|
||||
|
||||
|
@ -98,9 +122,9 @@ extern "C" {
|
|||
on_drop: extern "C" fn(callback_data: *mut c_void),
|
||||
) -> *const c_void;
|
||||
|
||||
fn LKRemoteAudioTrackGetSid(track: *const c_void) -> CFStringRef;
|
||||
fn LKVideoTrackAddRenderer(track: *const c_void, renderer: *const c_void);
|
||||
fn LKRemoteVideoTrackGetSid(track: *const c_void) -> CFStringRef;
|
||||
fn LKRemoteAudioTrackGetSid(track: swift::RemoteAudioTrack) -> CFStringRef;
|
||||
fn LKVideoTrackAddRenderer(track: swift::RemoteVideoTrack, renderer: *const c_void);
|
||||
fn LKRemoteVideoTrackGetSid(track: swift::RemoteVideoTrack) -> CFStringRef;
|
||||
|
||||
fn LKDisplaySources(
|
||||
callback_data: *mut c_void,
|
||||
|
@ -110,25 +134,25 @@ extern "C" {
|
|||
error: CFStringRef,
|
||||
),
|
||||
);
|
||||
fn LKCreateScreenShareTrackForDisplay(display: *const c_void) -> *const c_void;
|
||||
fn LKLocalAudioTrackCreateTrack() -> *const c_void;
|
||||
fn LKCreateScreenShareTrackForDisplay(display: swift::MacOSDisplay) -> swift::LocalVideoTrack;
|
||||
fn LKLocalAudioTrackCreateTrack() -> swift::LocalAudioTrack;
|
||||
|
||||
fn LKLocalTrackPublicationSetMute(
|
||||
publication: *const c_void,
|
||||
publication: swift::LocalTrackPublication,
|
||||
muted: bool,
|
||||
on_complete: extern "C" fn(callback_data: *mut c_void, error: CFStringRef),
|
||||
callback_data: *mut c_void,
|
||||
);
|
||||
|
||||
fn LKRemoteTrackPublicationSetEnabled(
|
||||
publication: *const c_void,
|
||||
publication: swift::RemoteTrackPublication,
|
||||
enabled: bool,
|
||||
on_complete: extern "C" fn(callback_data: *mut c_void, error: CFStringRef),
|
||||
callback_data: *mut c_void,
|
||||
);
|
||||
|
||||
fn LKRemoteTrackPublicationIsMuted(publication: *const c_void) -> bool;
|
||||
fn LKRemoteTrackPublicationGetSid(publication: *const c_void) -> CFStringRef;
|
||||
fn LKRemoteTrackPublicationIsMuted(publication: swift::RemoteTrackPublication) -> bool;
|
||||
fn LKRemoteTrackPublicationGetSid(publication: swift::RemoteTrackPublication) -> CFStringRef;
|
||||
}
|
||||
|
||||
pub type Sid = String;
|
||||
|
@ -140,30 +164,29 @@ pub enum ConnectionState {
|
|||
}
|
||||
|
||||
pub struct Room {
|
||||
native_room: *const c_void,
|
||||
native_room: Mutex<swift::Room>,
|
||||
connection: Mutex<(
|
||||
watch::Sender<ConnectionState>,
|
||||
watch::Receiver<ConnectionState>,
|
||||
)>,
|
||||
remote_audio_track_subscribers: Mutex<Vec<mpsc::UnboundedSender<RemoteAudioTrackUpdate>>>,
|
||||
remote_video_track_subscribers: Mutex<Vec<mpsc::UnboundedSender<RemoteVideoTrackUpdate>>>,
|
||||
_delegate: RoomDelegate,
|
||||
_delegate: Mutex<RoomDelegate>,
|
||||
}
|
||||
|
||||
// SAFETY: LiveKit objects are thread-safe: https://github.com/livekit/client-sdk-swift#thread-safety
|
||||
unsafe impl Send for Room {}
|
||||
unsafe impl Sync for Room {}
|
||||
trait AssertSendSync: Send {}
|
||||
impl AssertSendSync for Room {}
|
||||
|
||||
impl Room {
|
||||
pub fn new() -> Arc<Self> {
|
||||
Arc::new_cyclic(|weak_room| {
|
||||
let delegate = RoomDelegate::new(weak_room.clone());
|
||||
Self {
|
||||
native_room: unsafe { LKRoomCreate(delegate.native_delegate) },
|
||||
native_room: Mutex::new(unsafe { LKRoomCreate(delegate.native_delegate) }),
|
||||
connection: Mutex::new(watch::channel_with(ConnectionState::Disconnected)),
|
||||
remote_audio_track_subscribers: Default::default(),
|
||||
remote_video_track_subscribers: Default::default(),
|
||||
_delegate: delegate,
|
||||
_delegate: Mutex::new(delegate),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -178,7 +201,7 @@ impl Room {
|
|||
let (did_connect, tx, rx) = Self::build_done_callback();
|
||||
unsafe {
|
||||
LKRoomConnect(
|
||||
self.native_room,
|
||||
*self.native_room.lock(),
|
||||
url.as_concrete_TypeRef(),
|
||||
token.as_concrete_TypeRef(),
|
||||
did_connect,
|
||||
|
@ -210,7 +233,7 @@ impl Room {
|
|||
} else {
|
||||
let sources = CFArray::wrap_under_get_rule(sources)
|
||||
.into_iter()
|
||||
.map(|source| MacOSDisplay::new(*source))
|
||||
.map(|source| MacOSDisplay::new(swift::MacOSDisplay(*source)))
|
||||
.collect();
|
||||
|
||||
let _ = tx.send(Ok(sources));
|
||||
|
@ -232,7 +255,11 @@ impl Room {
|
|||
track: LocalVideoTrack,
|
||||
) -> impl Future<Output = Result<LocalTrackPublication>> {
|
||||
let (tx, rx) = oneshot::channel::<Result<LocalTrackPublication>>();
|
||||
extern "C" fn callback(tx: *mut c_void, publication: *mut c_void, error: CFStringRef) {
|
||||
extern "C" fn callback(
|
||||
tx: *mut c_void,
|
||||
publication: swift::LocalTrackPublication,
|
||||
error: CFStringRef,
|
||||
) {
|
||||
let tx =
|
||||
unsafe { Box::from_raw(tx as *mut oneshot::Sender<Result<LocalTrackPublication>>) };
|
||||
if error.is_null() {
|
||||
|
@ -244,7 +271,7 @@ impl Room {
|
|||
}
|
||||
unsafe {
|
||||
LKRoomPublishVideoTrack(
|
||||
self.native_room,
|
||||
*self.native_room.lock(),
|
||||
track.0,
|
||||
callback,
|
||||
Box::into_raw(Box::new(tx)) as *mut c_void,
|
||||
|
@ -258,7 +285,11 @@ impl Room {
|
|||
track: LocalAudioTrack,
|
||||
) -> impl Future<Output = Result<LocalTrackPublication>> {
|
||||
let (tx, rx) = oneshot::channel::<Result<LocalTrackPublication>>();
|
||||
extern "C" fn callback(tx: *mut c_void, publication: *mut c_void, error: CFStringRef) {
|
||||
extern "C" fn callback(
|
||||
tx: *mut c_void,
|
||||
publication: swift::LocalTrackPublication,
|
||||
error: CFStringRef,
|
||||
) {
|
||||
let tx =
|
||||
unsafe { Box::from_raw(tx as *mut oneshot::Sender<Result<LocalTrackPublication>>) };
|
||||
if error.is_null() {
|
||||
|
@ -270,7 +301,7 @@ impl Room {
|
|||
}
|
||||
unsafe {
|
||||
LKRoomPublishAudioTrack(
|
||||
self.native_room,
|
||||
*self.native_room.lock(),
|
||||
track.0,
|
||||
callback,
|
||||
Box::into_raw(Box::new(tx)) as *mut c_void,
|
||||
|
@ -281,14 +312,14 @@ impl Room {
|
|||
|
||||
pub fn unpublish_track(&self, publication: LocalTrackPublication) {
|
||||
unsafe {
|
||||
LKRoomUnpublishTrack(self.native_room, publication.0);
|
||||
LKRoomUnpublishTrack(*self.native_room.lock(), publication.0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remote_video_tracks(&self, participant_id: &str) -> Vec<Arc<RemoteVideoTrack>> {
|
||||
unsafe {
|
||||
let tracks = LKRoomVideoTracksForRemoteParticipant(
|
||||
self.native_room,
|
||||
*self.native_room.lock(),
|
||||
CFString::new(participant_id).as_concrete_TypeRef(),
|
||||
);
|
||||
|
||||
|
@ -299,7 +330,7 @@ impl Room {
|
|||
tracks
|
||||
.into_iter()
|
||||
.map(|native_track| {
|
||||
let native_track = *native_track;
|
||||
let native_track = swift::RemoteVideoTrack(*native_track);
|
||||
let id =
|
||||
CFString::wrap_under_get_rule(LKRemoteVideoTrackGetSid(native_track))
|
||||
.to_string();
|
||||
|
@ -317,7 +348,7 @@ impl Room {
|
|||
pub fn remote_audio_tracks(&self, participant_id: &str) -> Vec<Arc<RemoteAudioTrack>> {
|
||||
unsafe {
|
||||
let tracks = LKRoomAudioTracksForRemoteParticipant(
|
||||
self.native_room,
|
||||
*self.native_room.lock(),
|
||||
CFString::new(participant_id).as_concrete_TypeRef(),
|
||||
);
|
||||
|
||||
|
@ -328,7 +359,7 @@ impl Room {
|
|||
tracks
|
||||
.into_iter()
|
||||
.map(|native_track| {
|
||||
let native_track = *native_track;
|
||||
let native_track = swift::RemoteAudioTrack(*native_track);
|
||||
let id =
|
||||
CFString::wrap_under_get_rule(LKRemoteAudioTrackGetSid(native_track))
|
||||
.to_string();
|
||||
|
@ -349,7 +380,7 @@ impl Room {
|
|||
) -> Vec<Arc<RemoteTrackPublication>> {
|
||||
unsafe {
|
||||
let tracks = LKRoomAudioTrackPublicationsForRemoteParticipant(
|
||||
self.native_room,
|
||||
*self.native_room.lock(),
|
||||
CFString::new(participant_id).as_concrete_TypeRef(),
|
||||
);
|
||||
|
||||
|
@ -360,7 +391,8 @@ impl Room {
|
|||
tracks
|
||||
.into_iter()
|
||||
.map(|native_track_publication| {
|
||||
let native_track_publication = *native_track_publication;
|
||||
let native_track_publication =
|
||||
swift::RemoteTrackPublication(*native_track_publication);
|
||||
Arc::new(RemoteTrackPublication::new(native_track_publication))
|
||||
})
|
||||
.collect()
|
||||
|
@ -467,28 +499,32 @@ impl Room {
|
|||
rx,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn set_display_sources(&self, _: Vec<MacOSDisplay>) {
|
||||
unreachable!("This is a test-only function")
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Room {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
LKRoomDisconnect(self.native_room);
|
||||
CFRelease(self.native_room);
|
||||
let native_room = &*self.native_room.lock();
|
||||
LKRoomDisconnect(*native_room);
|
||||
CFRelease(native_room.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RoomDelegate {
|
||||
native_delegate: *const c_void,
|
||||
weak_room: *const Room,
|
||||
native_delegate: swift::RoomDelegate,
|
||||
_weak_room: Weak<Room>,
|
||||
}
|
||||
|
||||
impl RoomDelegate {
|
||||
fn new(weak_room: Weak<Room>) -> Self {
|
||||
let weak_room = Weak::into_raw(weak_room);
|
||||
let native_delegate = unsafe {
|
||||
LKRoomDelegateCreate(
|
||||
weak_room as *mut c_void,
|
||||
weak_room.as_ptr() as *mut c_void,
|
||||
Self::on_did_disconnect,
|
||||
Self::on_did_subscribe_to_remote_audio_track,
|
||||
Self::on_did_unsubscribe_from_remote_audio_track,
|
||||
|
@ -500,7 +536,7 @@ impl RoomDelegate {
|
|||
};
|
||||
Self {
|
||||
native_delegate,
|
||||
weak_room,
|
||||
_weak_room: weak_room,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,8 +552,8 @@ impl RoomDelegate {
|
|||
room: *mut c_void,
|
||||
publisher_id: CFStringRef,
|
||||
track_id: CFStringRef,
|
||||
track: *const c_void,
|
||||
publication: *const c_void,
|
||||
track: swift::RemoteAudioTrack,
|
||||
publication: swift::RemoteTrackPublication,
|
||||
) {
|
||||
let room = unsafe { Weak::from_raw(room as *mut Room) };
|
||||
let publisher_id = unsafe { CFString::wrap_under_get_rule(publisher_id).to_string() };
|
||||
|
@ -584,7 +620,7 @@ impl RoomDelegate {
|
|||
room: *mut c_void,
|
||||
publisher_id: CFStringRef,
|
||||
track_id: CFStringRef,
|
||||
track: *const c_void,
|
||||
track: swift::RemoteVideoTrack,
|
||||
) {
|
||||
let room = unsafe { Weak::from_raw(room as *mut Room) };
|
||||
let publisher_id = unsafe { CFString::wrap_under_get_rule(publisher_id).to_string() };
|
||||
|
@ -614,14 +650,12 @@ impl RoomDelegate {
|
|||
impl Drop for RoomDelegate {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
CFRelease(self.native_delegate);
|
||||
let _ = Weak::from_raw(self.weak_room);
|
||||
CFRelease(self.native_delegate.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LocalAudioTrack(*const c_void);
|
||||
unsafe impl Send for LocalAudioTrack {}
|
||||
pub struct LocalAudioTrack(swift::LocalAudioTrack);
|
||||
|
||||
impl LocalAudioTrack {
|
||||
pub fn create() -> Self {
|
||||
|
@ -631,12 +665,11 @@ impl LocalAudioTrack {
|
|||
|
||||
impl Drop for LocalAudioTrack {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CFRelease(self.0) }
|
||||
unsafe { CFRelease(self.0 .0) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LocalVideoTrack(*const c_void);
|
||||
unsafe impl Send for LocalVideoTrack {}
|
||||
pub struct LocalVideoTrack(swift::LocalVideoTrack);
|
||||
|
||||
impl LocalVideoTrack {
|
||||
pub fn screen_share_for_display(display: &MacOSDisplay) -> Self {
|
||||
|
@ -646,17 +679,16 @@ impl LocalVideoTrack {
|
|||
|
||||
impl Drop for LocalVideoTrack {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CFRelease(self.0) }
|
||||
unsafe { CFRelease(self.0 .0) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LocalTrackPublication(*const c_void);
|
||||
unsafe impl Send for LocalTrackPublication {}
|
||||
pub struct LocalTrackPublication(swift::LocalTrackPublication);
|
||||
|
||||
impl LocalTrackPublication {
|
||||
pub fn new(native_track_publication: *const c_void) -> Self {
|
||||
pub fn new(native_track_publication: swift::LocalTrackPublication) -> Self {
|
||||
unsafe {
|
||||
CFRetain(native_track_publication);
|
||||
CFRetain(native_track_publication.0);
|
||||
}
|
||||
Self(native_track_publication)
|
||||
}
|
||||
|
@ -689,28 +721,35 @@ impl LocalTrackPublication {
|
|||
|
||||
impl Drop for LocalTrackPublication {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CFRelease(self.0) }
|
||||
unsafe { CFRelease(self.0 .0) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RemoteTrackPublication(*const c_void);
|
||||
|
||||
unsafe impl Send for RemoteTrackPublication {}
|
||||
pub struct RemoteTrackPublication {
|
||||
native_publication: Mutex<swift::RemoteTrackPublication>,
|
||||
}
|
||||
|
||||
impl RemoteTrackPublication {
|
||||
pub fn new(native_track_publication: *const c_void) -> Self {
|
||||
pub fn new(native_track_publication: swift::RemoteTrackPublication) -> Self {
|
||||
unsafe {
|
||||
CFRetain(native_track_publication);
|
||||
CFRetain(native_track_publication.0);
|
||||
}
|
||||
Self {
|
||||
native_publication: Mutex::new(native_track_publication),
|
||||
}
|
||||
Self(native_track_publication)
|
||||
}
|
||||
|
||||
pub fn sid(&self) -> String {
|
||||
unsafe { CFString::wrap_under_get_rule(LKRemoteTrackPublicationGetSid(self.0)).to_string() }
|
||||
unsafe {
|
||||
CFString::wrap_under_get_rule(LKRemoteTrackPublicationGetSid(
|
||||
*self.native_publication.lock(),
|
||||
))
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_muted(&self) -> bool {
|
||||
unsafe { LKRemoteTrackPublicationIsMuted(self.0) }
|
||||
unsafe { LKRemoteTrackPublicationIsMuted(*self.native_publication.lock()) }
|
||||
}
|
||||
|
||||
pub fn set_enabled(&self, enabled: bool) -> impl Future<Output = Result<()>> {
|
||||
|
@ -728,7 +767,7 @@ impl RemoteTrackPublication {
|
|||
|
||||
unsafe {
|
||||
LKRemoteTrackPublicationSetEnabled(
|
||||
self.0,
|
||||
*self.native_publication.lock(),
|
||||
enabled,
|
||||
complete_callback,
|
||||
Box::into_raw(Box::new(tx)) as *mut c_void,
|
||||
|
@ -741,26 +780,24 @@ impl RemoteTrackPublication {
|
|||
|
||||
impl Drop for RemoteTrackPublication {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CFRelease(self.0) }
|
||||
unsafe { CFRelease((*self.native_publication.lock()).0) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RemoteAudioTrack {
|
||||
_native_track: *const c_void,
|
||||
native_track: Mutex<swift::RemoteAudioTrack>,
|
||||
sid: Sid,
|
||||
publisher_id: String,
|
||||
}
|
||||
|
||||
unsafe impl Send for RemoteAudioTrack {}
|
||||
|
||||
impl RemoteAudioTrack {
|
||||
fn new(native_track: *const c_void, sid: Sid, publisher_id: String) -> Self {
|
||||
fn new(native_track: swift::RemoteAudioTrack, sid: Sid, publisher_id: String) -> Self {
|
||||
unsafe {
|
||||
CFRetain(native_track);
|
||||
CFRetain(native_track.0);
|
||||
}
|
||||
Self {
|
||||
_native_track: native_track,
|
||||
native_track: Mutex::new(native_track),
|
||||
sid,
|
||||
publisher_id,
|
||||
}
|
||||
|
@ -783,22 +820,26 @@ impl RemoteAudioTrack {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for RemoteAudioTrack {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CFRelease(self.native_track.lock().0) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RemoteVideoTrack {
|
||||
native_track: *const c_void,
|
||||
native_track: Mutex<swift::RemoteVideoTrack>,
|
||||
sid: Sid,
|
||||
publisher_id: String,
|
||||
}
|
||||
|
||||
unsafe impl Send for RemoteVideoTrack {}
|
||||
|
||||
impl RemoteVideoTrack {
|
||||
fn new(native_track: *const c_void, sid: Sid, publisher_id: String) -> Self {
|
||||
fn new(native_track: swift::RemoteVideoTrack, sid: Sid, publisher_id: String) -> Self {
|
||||
unsafe {
|
||||
CFRetain(native_track);
|
||||
CFRetain(native_track.0);
|
||||
}
|
||||
Self {
|
||||
native_track,
|
||||
native_track: Mutex::new(native_track),
|
||||
sid,
|
||||
publisher_id,
|
||||
}
|
||||
|
@ -847,7 +888,7 @@ impl RemoteVideoTrack {
|
|||
on_frame,
|
||||
on_drop,
|
||||
);
|
||||
LKVideoTrackAddRenderer(self.native_track, renderer);
|
||||
LKVideoTrackAddRenderer(*self.native_track.lock(), renderer);
|
||||
rx
|
||||
}
|
||||
}
|
||||
|
@ -855,7 +896,7 @@ impl RemoteVideoTrack {
|
|||
|
||||
impl Drop for RemoteVideoTrack {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CFRelease(self.native_track) }
|
||||
unsafe { CFRelease(self.native_track.lock().0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -871,14 +912,12 @@ pub enum RemoteAudioTrackUpdate {
|
|||
Unsubscribed { publisher_id: Sid, track_id: Sid },
|
||||
}
|
||||
|
||||
pub struct MacOSDisplay(*const c_void);
|
||||
|
||||
unsafe impl Send for MacOSDisplay {}
|
||||
pub struct MacOSDisplay(swift::MacOSDisplay);
|
||||
|
||||
impl MacOSDisplay {
|
||||
fn new(ptr: *const c_void) -> Self {
|
||||
fn new(ptr: swift::MacOSDisplay) -> Self {
|
||||
unsafe {
|
||||
CFRetain(ptr);
|
||||
CFRetain(ptr.0);
|
||||
}
|
||||
Self(ptr)
|
||||
}
|
||||
|
@ -886,7 +925,7 @@ impl MacOSDisplay {
|
|||
|
||||
impl Drop for MacOSDisplay {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CFRelease(self.0) }
|
||||
unsafe { CFRelease(self.0 .0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_trait::async_trait;
|
||||
use collections::{BTreeMap, HashMap};
|
||||
use futures::Stream;
|
||||
use gpui::executor::Background;
|
||||
use gpui::BackgroundExecutor;
|
||||
use live_kit_server::token;
|
||||
use media::core_video::CVImageBuffer;
|
||||
use parking_lot::Mutex;
|
||||
|
@ -16,7 +16,7 @@ pub struct TestServer {
|
|||
pub api_key: String,
|
||||
pub secret_key: String,
|
||||
rooms: Mutex<HashMap<String, TestServerRoom>>,
|
||||
background: Arc<Background>,
|
||||
executor: BackgroundExecutor,
|
||||
}
|
||||
|
||||
impl TestServer {
|
||||
|
@ -24,7 +24,7 @@ impl TestServer {
|
|||
url: String,
|
||||
api_key: String,
|
||||
secret_key: String,
|
||||
background: Arc<Background>,
|
||||
executor: BackgroundExecutor,
|
||||
) -> Result<Arc<TestServer>> {
|
||||
let mut servers = SERVERS.lock();
|
||||
if servers.contains_key(&url) {
|
||||
|
@ -35,7 +35,7 @@ impl TestServer {
|
|||
api_key,
|
||||
secret_key,
|
||||
rooms: Default::default(),
|
||||
background,
|
||||
executor,
|
||||
});
|
||||
servers.insert(url, server.clone());
|
||||
Ok(server)
|
||||
|
@ -65,7 +65,7 @@ impl TestServer {
|
|||
}
|
||||
|
||||
pub async fn create_room(&self, room: String) -> Result<()> {
|
||||
self.background.simulate_random_delay().await;
|
||||
self.executor.simulate_random_delay().await;
|
||||
let mut server_rooms = self.rooms.lock();
|
||||
if server_rooms.contains_key(&room) {
|
||||
Err(anyhow!("room {:?} already exists", room))
|
||||
|
@ -77,7 +77,7 @@ impl TestServer {
|
|||
|
||||
async fn delete_room(&self, room: String) -> Result<()> {
|
||||
// TODO: clear state associated with all `Room`s.
|
||||
self.background.simulate_random_delay().await;
|
||||
self.executor.simulate_random_delay().await;
|
||||
let mut server_rooms = self.rooms.lock();
|
||||
server_rooms
|
||||
.remove(&room)
|
||||
|
@ -86,7 +86,7 @@ impl TestServer {
|
|||
}
|
||||
|
||||
async fn join_room(&self, token: String, client_room: Arc<Room>) -> Result<()> {
|
||||
self.background.simulate_random_delay().await;
|
||||
self.executor.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();
|
||||
|
@ -115,7 +115,7 @@ impl TestServer {
|
|||
}
|
||||
|
||||
async fn leave_room(&self, token: String) -> Result<()> {
|
||||
self.background.simulate_random_delay().await;
|
||||
self.executor.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();
|
||||
|
@ -136,7 +136,7 @@ impl TestServer {
|
|||
async fn remove_participant(&self, room_name: String, identity: String) -> Result<()> {
|
||||
// TODO: clear state associated with the `Room`.
|
||||
|
||||
self.background.simulate_random_delay().await;
|
||||
self.executor.simulate_random_delay().await;
|
||||
let mut server_rooms = self.rooms.lock();
|
||||
let room = server_rooms
|
||||
.get_mut(&room_name)
|
||||
|
@ -152,7 +152,7 @@ impl TestServer {
|
|||
}
|
||||
|
||||
pub async fn disconnect_client(&self, client_identity: String) {
|
||||
self.background.simulate_random_delay().await;
|
||||
self.executor.simulate_random_delay().await;
|
||||
let mut server_rooms = self.rooms.lock();
|
||||
for room in server_rooms.values_mut() {
|
||||
if let Some(room) = room.client_rooms.remove(&client_identity) {
|
||||
|
@ -162,7 +162,7 @@ impl TestServer {
|
|||
}
|
||||
|
||||
async fn publish_video_track(&self, token: String, local_track: LocalVideoTrack) -> Result<()> {
|
||||
self.background.simulate_random_delay().await;
|
||||
self.executor.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();
|
||||
|
@ -200,7 +200,7 @@ impl TestServer {
|
|||
token: String,
|
||||
_local_track: &LocalAudioTrack,
|
||||
) -> Result<()> {
|
||||
self.background.simulate_random_delay().await;
|
||||
self.executor.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();
|
||||
|
@ -364,7 +364,10 @@ impl Room {
|
|||
let token = token.to_string();
|
||||
async move {
|
||||
let server = TestServer::get(&url)?;
|
||||
server.join_room(token.clone(), this.clone()).await?;
|
||||
server
|
||||
.join_room(token.clone(), this.clone())
|
||||
.await
|
||||
.context("room join")?;
|
||||
*this.0.lock().connection.0.borrow_mut() = ConnectionState::Connected { url, token };
|
||||
Ok(())
|
||||
}
|
||||
|
@ -374,7 +377,7 @@ impl Room {
|
|||
let this = self.clone();
|
||||
async move {
|
||||
let server = this.test_server();
|
||||
server.background.simulate_random_delay().await;
|
||||
server.executor.simulate_random_delay().await;
|
||||
Ok(this.0.lock().display_sources.clone())
|
||||
}
|
||||
}
|
||||
|
@ -492,8 +495,8 @@ impl Drop for Room {
|
|||
ConnectionState::Disconnected,
|
||||
) {
|
||||
if let Ok(server) = TestServer::get(&token) {
|
||||
let background = server.background.clone();
|
||||
background
|
||||
let executor = server.executor.clone();
|
||||
executor
|
||||
.spawn(async move { server.leave_room(token).await.unwrap() })
|
||||
.detach();
|
||||
}
|
||||
|
@ -547,6 +550,7 @@ impl LocalAudioTrack {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RemoteVideoTrack {
|
||||
sid: Sid,
|
||||
publisher_id: Sid,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue