mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
livekit_client: Screensharing on Niri + NixOS (#52017)
Release Notes: - Fixed a weird niche interaction between niri and nixos that broke screensharing --------- Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
This commit is contained in:
parent
b99200fbaf
commit
17e4b492c6
6 changed files with 28 additions and 7 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -10004,6 +10004,7 @@ dependencies = [
|
|||
"tokio",
|
||||
"ui",
|
||||
"util",
|
||||
"webrtc-sys",
|
||||
"zed-scap",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -779,6 +779,7 @@ wax = "0.7"
|
|||
which = "6.0.0"
|
||||
wasm-bindgen = "0.2.113"
|
||||
web-time = "1.1.0"
|
||||
webrtc-sys = "0.3.23"
|
||||
wgpu = { git = "https://github.com/zed-industries/wgpu.git", branch = "v29" }
|
||||
windows-core = "0.61"
|
||||
yawc = "0.2.5"
|
||||
|
|
@ -849,6 +850,7 @@ windows-capture = { git = "https://github.com/zed-industries/windows-capture.git
|
|||
calloop = { git = "https://github.com/zed-industries/calloop" }
|
||||
livekit = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "c1209aa155cbf4543383774f884a46ae7e53ee2e" }
|
||||
libwebrtc = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "c1209aa155cbf4543383774f884a46ae7e53ee2e" }
|
||||
webrtc-sys = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "c1209aa155cbf4543383774f884a46ae7e53ee2e" }
|
||||
|
||||
[profile.dev]
|
||||
split-debuginfo = "unpacked"
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ livekit.workspace = true
|
|||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
tokio = { workspace = true, features = ["time"] }
|
||||
webrtc-sys.workspace = true
|
||||
|
||||
[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "windows"))'.dependencies]
|
||||
scap.workspace = true
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use std::sync::{
|
|||
};
|
||||
|
||||
static NEXT_WAYLAND_SHARE_ID: AtomicU64 = AtomicU64::new(1);
|
||||
const PIPEWIRE_TIMEOUT_S: u64 = 30;
|
||||
|
||||
pub struct WaylandScreenCaptureStream {
|
||||
id: u64,
|
||||
|
|
@ -64,6 +65,17 @@ pub(crate) async fn start_wayland_desktop_capture(
|
|||
};
|
||||
use libwebrtc::native::yuv_helper::argb_to_nv12;
|
||||
use std::time::Duration;
|
||||
use webrtc_sys::webrtc::ffi as webrtc_ffi;
|
||||
|
||||
fn webrtc_log_callback(message: String, severity: webrtc_ffi::LoggingSeverity) {
|
||||
match severity {
|
||||
webrtc_ffi::LoggingSeverity::Error => log::error!("[webrtc] {}", message.trim()),
|
||||
_ => log::debug!("[webrtc] {}", message.trim()),
|
||||
}
|
||||
}
|
||||
|
||||
let _webrtc_log_sink = webrtc_ffi::new_log_sink(webrtc_log_callback);
|
||||
log::debug!("Wayland desktop capture: WebRTC internal logging enabled");
|
||||
|
||||
let stop_flag = Arc::new(AtomicBool::new(false));
|
||||
let (mut video_source_tx, mut video_source_rx) = mpsc::channel::<NativeVideoSource>(1);
|
||||
|
|
@ -79,7 +91,6 @@ pub(crate) async fn start_wayland_desktop_capture(
|
|||
})?;
|
||||
|
||||
let permanent_error = Arc::new(AtomicBool::new(false));
|
||||
|
||||
let stop_cb = stop_flag.clone();
|
||||
let permanent_error_cb = permanent_error.clone();
|
||||
capturer.start_capture(None, {
|
||||
|
|
@ -136,6 +147,8 @@ pub(crate) async fn start_wayland_desktop_capture(
|
|||
}
|
||||
});
|
||||
|
||||
log::info!("Wayland desktop capture: starting capture loop");
|
||||
|
||||
let stop = stop_flag.clone();
|
||||
let tokio_task = gpui_tokio::Tokio::spawn(cx, async move {
|
||||
loop {
|
||||
|
|
@ -162,10 +175,11 @@ pub(crate) async fn start_wayland_desktop_capture(
|
|||
let executor = cx.background_executor().clone();
|
||||
let video_source = video_source_rx
|
||||
.next()
|
||||
.with_timeout(Duration::from_secs(15), &executor)
|
||||
.with_timeout(Duration::from_secs(PIPEWIRE_TIMEOUT_S), &executor)
|
||||
.await
|
||||
.map_err(|_| {
|
||||
stop_flag.store(true, Ordering::Relaxed);
|
||||
log::error!("Wayland desktop capture timed out.");
|
||||
anyhow::anyhow!(
|
||||
"Screen sharing timed out waiting for the first frame. \
|
||||
Check that xdg-desktop-portal and PipeWire are running, \
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ fn main() {
|
|||
// Add rpaths for libraries that webrtc-sys dlopens at runtime.
|
||||
// This is mostly required for hosts with non-standard SO installation
|
||||
// locations such as NixOS.
|
||||
let dlopened_libs = ["libva", "libva-drm"];
|
||||
let dlopened_libs = ["libva", "libva-drm", "egl"];
|
||||
|
||||
let mut rpath_dirs = std::collections::BTreeSet::new();
|
||||
for lib in &dlopened_libs {
|
||||
if let Some(libdir) = pkg_config::get_variable(lib, "libdir").ok() {
|
||||
rpath_dirs.insert(libdir);
|
||||
} else {
|
||||
eprintln!("zed build.rs: {lib} not found in pkg-config's path");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ let
|
|||
builtins.elem firstComp topLevelIncludes;
|
||||
|
||||
craneLib = crane.overrideToolchain rustToolchain;
|
||||
gpu-lib = if withGLES then libglvnd else vulkan-loader;
|
||||
commonArgs =
|
||||
let
|
||||
zedCargoLock = builtins.fromTOML (builtins.readFile ../crates/zed/Cargo.toml);
|
||||
|
|
@ -179,7 +178,8 @@ let
|
|||
libva
|
||||
libxkbcommon
|
||||
wayland
|
||||
gpu-lib
|
||||
libglvnd
|
||||
vulkan-loader
|
||||
xorg.libX11
|
||||
xorg.libxcb
|
||||
libdrm
|
||||
|
|
@ -236,7 +236,8 @@ let
|
|||
# about them that's special is that they're manually dlopened at runtime
|
||||
NIX_LDFLAGS = lib.optionalString stdenv'.hostPlatform.isLinux "-rpath ${
|
||||
lib.makeLibraryPath [
|
||||
gpu-lib
|
||||
libglvnd
|
||||
vulkan-loader
|
||||
wayland
|
||||
libva
|
||||
]
|
||||
|
|
@ -245,7 +246,7 @@ let
|
|||
NIX_OUTPATH_USED_AS_RANDOM_SEED = "norebuilds";
|
||||
};
|
||||
|
||||
# prevent nix from removing the "unused" wayland/gpu-lib rpaths
|
||||
# prevent nix from removing the "unused" wayland rpaths
|
||||
dontPatchELF = stdenv'.hostPlatform.isLinux;
|
||||
|
||||
# TODO: try craneLib.cargoNextest separate output
|
||||
|
|
|
|||
Loading…
Reference in a new issue