diff --git a/scripts/install/server.sh b/scripts/install/server.sh index 3e61fe6..cf769ca 100755 --- a/scripts/install/server.sh +++ b/scripts/install/server.sh @@ -109,7 +109,7 @@ Environment=RUST_LOG=lesavka_server::video=trace,lesavka_server::usb_gadget=debu Environment=RUST_BACKTRACE=1 Restart=always RestartSec=5 -StandardError=append:/tmp/lesavka-server.log +StandardError=append:/tmp/lesavka-server.stderr StartLimitIntervalSec=30 StartLimitBurst=10 User=root diff --git a/server/src/main.rs b/server/src/main.rs index d54a227..420190d 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -119,7 +119,7 @@ impl Relay for Handler { /* existing streams ─ unchanged, except: no more auto-reset */ type StreamKeyboardStream = ReceiverStream>; type StreamMouseStream = ReceiverStream>; - type CaptureVideoStream = Pin> + Send + Sync>>; + type CaptureVideoStream = Pin> + Send>>; async fn stream_keyboard( &self, diff --git a/server/src/video.rs b/server/src/video.rs index 7b3c3d1..66d9369 100644 --- a/server/src/video.rs +++ b/server/src/video.rs @@ -9,15 +9,38 @@ use lesavka_common::lesavka::VideoPacket; use tokio_stream::wrappers::ReceiverStream; use tonic::Status; use tracing::{debug, enabled, trace, Level}; +use futures_util::Stream; const EYE_ID: [&str; 2] = ["l", "r"]; static START: std::sync::OnceLock = std::sync::OnceLock::new(); +pub struct VideoStream { + _pipeline: gst::Pipeline, + inner: ReceiverStream>, +} + +impl Stream for VideoStream { + type Item = Result; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + Stream::poll_next(std::pin::Pin::new(&mut self.inner), cx) + } +} + +impl Drop for VideoStream { + fn drop(&mut self) { + // shut down nicely – avoids the “dispose element … READY/PLAYING …” spam + let _ = self._pipeline.set_state(gst::State::Null); + } +} + pub async fn eye_ball( dev: &str, id: u32, _max_bitrate_kbit: u32, -) -> anyhow::Result>> { +) -> anyhow::Result { let eye = EYE_ID[id as usize]; gst::init().context("gst init")?; @@ -118,5 +141,5 @@ pub async fn eye_ball( None => continue, } } - Ok(ReceiverStream::new(rx)) + Ok(VideoStream { _pipeline: pipeline, inner: ReceiverStream::new(rx) }) }