From 4ad2b2d6dd233583d1212bcec59e152124254858 Mon Sep 17 00:00:00 2001 From: Valmo Trindade Date: Tue, 17 Jun 2025 05:21:11 -0300 Subject: [PATCH] Added video feed support for Linux clients --- src/video_stream.rs | 76 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/src/video_stream.rs b/src/video_stream.rs index a1c5c69..d26d04a 100644 --- a/src/video_stream.rs +++ b/src/video_stream.rs @@ -26,11 +26,77 @@ pub fn start_stream( ) -> &'static str { #[cfg(target_os = "linux")] { - _ = ctx.callback_null( - "VIDEO ERROR", - "Screen capture is only supported on Windows", - ); - return "screen capture unsupported"; + let (stop_tx, stop_rx): (Sender<()>, Receiver<()>) = mpsc::channel(); + let (status_tx, status_rx): (Sender>, Receiver>) = mpsc::channel(); + + let rtsp_url = if username.is_empty() || password.is_empty() { + format!("rtsp://{}:{}/{}", address, port, stream_path) + } else { + format!( + "rtsp://{}:{}@{}:{}/{}", + username, password, address, port, stream_path + ) + }; + + let rtsp_url_clone = rtsp_url.clone(); + + thread::spawn(move || { + let mut cmd = Command::new("ffmpeg"); + cmd.args(&[ + "-f", + "gdigrab", + "-i", + "desktop", + "-f", + "rtsp", + "-rtsp_transport", + "tcp", + &rtsp_url_clone, + ]); + + // Try to spawn ffmpeg process + let child_result = cmd.spawn(); + + match child_result { + Ok(mut child) => { + let _ = status_tx.send(Ok(())); + if stop_rx.recv().is_err() {} + let _ = child.kill(); + } + Err(e) => { + let _ = status_tx.send(Err(format!("Failed to start FFmpeg: {}", e))); + } + } + }); + + // Save the stop channel + match STREAM_CTRL.lock() { + Ok(mut lock) => *lock = Some(stop_tx), + Err(e) => { + let _ = ctx.callback_data( + "VIDEO ERROR", + "Failed to acquire lock for stream control", + e.to_string(), + ); + return "stream control lock error"; + } + } + + // Wait up to 2 seconds to see if ffmpeg started correctly + match status_rx.recv_timeout(Duration::from_secs(2)) { + Ok(Ok(())) => { + let _ = ctx.callback_null("VIDEO", "FFmpeg started successfully"); + "starting video stream" + } + Ok(Err(e)) => { + let _ = ctx.callback_data("VIDEO ERROR", "FFmpeg failed to start", e); + "ffmpeg failed to start" + } + Err(_) => { + let _ = ctx.callback_null("VIDEO ERROR", "FFmpeg did not respond in time"); + "ffmpeg did not respond" + } + } } #[cfg(target_os = "windows")]