
See https://github.com/livekit/rust-sdks/pull/355 Todo: * [x] make `call` / `live_kit_client` crates use the livekit rust sdk * [x] create a fake version of livekit rust API for integration tests * [x] capture local audio * [x] play remote audio * [x] capture local video tracks * [x] play remote video tracks * [x] tests passing * bugs * [x] deafening does not work (https://github.com/livekit/rust-sdks/issues/359) * [x] mute and speaking status are not replicated properly: (https://github.com/livekit/rust-sdks/issues/358) * [x] **linux** - crash due to symbol conflict between WebRTC's BoringSSL and libcurl's openssl (https://github.com/livekit/rust-sdks/issues/89) * [x] **linux** - libwebrtc-sys adds undesired dependencies on `libGL` and `libXext` * [x] **windows** - linker error, maybe related to the C++ stdlib (https://github.com/livekit/rust-sdks/issues/364) ``` libwebrtc_sys-54978c6ad5066a35.rlib(video_frame.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MD_DynamicRelease' in libtree_sitter_yaml-df6b0adf8f009e8f.rlib(2e40c9e35e9506f4-scanner.o) ``` * [x] audio problems Release Notes: - Switch from Swift to Rust LiveKit SDK 🦀 --------- Co-authored-by: Mikayla Maki <mikayla@zed.dev> Co-authored-by: Conrad Irwin <conrad@zed.dev> Co-authored-by: Kirill Bulatov <kirill@zed.dev> Co-authored-by: Michael Sloan <michael@zed.dev>
161 lines
3.5 KiB
Rust
161 lines
3.5 KiB
Rust
//! Macos screen have a y axis that goings up from the bottom of the screen and
|
|
//! an origin at the bottom left of the main display.
|
|
mod dispatcher;
|
|
mod display;
|
|
mod display_link;
|
|
mod events;
|
|
mod screen_capture;
|
|
|
|
#[cfg(not(feature = "macos-blade"))]
|
|
mod metal_atlas;
|
|
#[cfg(not(feature = "macos-blade"))]
|
|
pub mod metal_renderer;
|
|
|
|
use media::core_video::CVImageBuffer;
|
|
#[cfg(not(feature = "macos-blade"))]
|
|
use metal_renderer as renderer;
|
|
|
|
#[cfg(feature = "macos-blade")]
|
|
use crate::platform::blade as renderer;
|
|
|
|
mod attributed_string;
|
|
|
|
#[cfg(feature = "font-kit")]
|
|
mod open_type;
|
|
|
|
#[cfg(feature = "font-kit")]
|
|
mod text_system;
|
|
|
|
mod platform;
|
|
mod window;
|
|
mod window_appearance;
|
|
|
|
use crate::{px, size, DevicePixels, Pixels, Size};
|
|
use cocoa::{
|
|
base::{id, nil},
|
|
foundation::{NSAutoreleasePool, NSNotFound, NSRect, NSSize, NSString, NSUInteger},
|
|
};
|
|
|
|
use objc::runtime::{BOOL, NO, YES};
|
|
use std::{
|
|
ffi::{c_char, CStr},
|
|
ops::Range,
|
|
};
|
|
|
|
pub(crate) use dispatcher::*;
|
|
pub(crate) use display::*;
|
|
pub(crate) use display_link::*;
|
|
pub(crate) use platform::*;
|
|
pub(crate) use window::*;
|
|
|
|
#[cfg(feature = "font-kit")]
|
|
pub(crate) use text_system::*;
|
|
|
|
/// A frame of video captured from a screen.
|
|
pub(crate) type PlatformScreenCaptureFrame = CVImageBuffer;
|
|
|
|
trait BoolExt {
|
|
fn to_objc(self) -> BOOL;
|
|
}
|
|
|
|
impl BoolExt for bool {
|
|
fn to_objc(self) -> BOOL {
|
|
if self {
|
|
YES
|
|
} else {
|
|
NO
|
|
}
|
|
}
|
|
}
|
|
|
|
trait NSStringExt {
|
|
unsafe fn to_str(&self) -> &str;
|
|
}
|
|
|
|
impl NSStringExt for id {
|
|
unsafe fn to_str(&self) -> &str {
|
|
let cstr = self.UTF8String();
|
|
if cstr.is_null() {
|
|
""
|
|
} else {
|
|
CStr::from_ptr(cstr as *mut c_char).to_str().unwrap()
|
|
}
|
|
}
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, Debug)]
|
|
struct NSRange {
|
|
pub location: NSUInteger,
|
|
pub length: NSUInteger,
|
|
}
|
|
|
|
impl NSRange {
|
|
fn invalid() -> Self {
|
|
Self {
|
|
location: NSNotFound as NSUInteger,
|
|
length: 0,
|
|
}
|
|
}
|
|
|
|
fn is_valid(&self) -> bool {
|
|
self.location != NSNotFound as NSUInteger
|
|
}
|
|
|
|
fn to_range(self) -> Option<Range<usize>> {
|
|
if self.is_valid() {
|
|
let start = self.location as usize;
|
|
let end = start + self.length as usize;
|
|
Some(start..end)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<Range<usize>> for NSRange {
|
|
fn from(range: Range<usize>) -> Self {
|
|
NSRange {
|
|
location: range.start as NSUInteger,
|
|
length: range.len() as NSUInteger,
|
|
}
|
|
}
|
|
}
|
|
|
|
unsafe impl objc::Encode for NSRange {
|
|
fn encode() -> objc::Encoding {
|
|
let encoding = format!(
|
|
"{{NSRange={}{}}}",
|
|
NSUInteger::encode().as_str(),
|
|
NSUInteger::encode().as_str()
|
|
);
|
|
unsafe { objc::Encoding::from_str(&encoding) }
|
|
}
|
|
}
|
|
|
|
unsafe fn ns_string(string: &str) -> id {
|
|
NSString::alloc(nil).init_str(string).autorelease()
|
|
}
|
|
|
|
impl From<NSSize> for Size<Pixels> {
|
|
fn from(value: NSSize) -> Self {
|
|
Size {
|
|
width: px(value.width as f32),
|
|
height: px(value.height as f32),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<NSRect> for Size<Pixels> {
|
|
fn from(rect: NSRect) -> Self {
|
|
let NSSize { width, height } = rect.size;
|
|
size(width.into(), height.into())
|
|
}
|
|
}
|
|
|
|
impl From<NSRect> for Size<DevicePixels> {
|
|
fn from(rect: NSRect) -> Self {
|
|
let NSSize { width, height } = rect.size;
|
|
size(DevicePixels(width as i32), DevicePixels(height as i32))
|
|
}
|
|
}
|