diff --git a/src/camera/opencv.rs b/src/camera/opencv.rs index e30bc50..8e07f44 100644 --- a/src/camera/opencv.rs +++ b/src/camera/opencv.rs @@ -63,7 +63,13 @@ impl OpenCVCamera { // For Linux device files like /dev/video0 if let Some(num_str) = path_str.strip_prefix("/dev/video") { if let Ok(device_index) = num_str.parse::() { - return Ok(videoio::VideoCapture::new(device_index, videoio::CAP_ANY)?); + // 在Linux下使用GStreamer pipeline + let pipeline = format!( + "v4l2src device={} ! videoconvert ! video/x-raw,format=BGR ! appsink", + path_str + ); + info!("Using GStreamer pipeline: {}", pipeline); + return Ok(videoio::VideoCapture::from_file(&pipeline, videoio::CAP_GSTREAMER)?); } else { return Err(anyhow!("Invalid device number in path: {}", path_str)); } @@ -193,6 +199,30 @@ impl OpenCVCamera { return Err(anyhow!("Camera is not open")); } + #[cfg(target_os = "linux")] + { + // 在Linux下创建一个使用GStreamer的流 + if self.device.starts_with("/dev/video") { + let pipeline = format!( + "v4l2src device={} ! videoconvert ! video/x-raw,width={},height={},format=BGR,framerate={}/1 ! appsink", + self.device, self.width, self.height, 30 // 使用固定的30fps,或者从设置获取 + ); + info!("Starting stream with GStreamer pipeline: {}", pipeline); + let stream_capture = videoio::VideoCapture::from_file(&pipeline, videoio::CAP_GSTREAMER)?; + if !stream_capture.is_opened()? { + return Err(anyhow!("Failed to open GStreamer camera stream")); + } + + self.is_streaming = true; + info!("Started camera streaming with GStreamer"); + + return Ok(OpenCVCaptureStream { + capture: stream_capture, + }); + } + } + + // For non-Linux platforms or if GStreamer approach fails, use regular approach // Create a separate VideoCapture for the stream to avoid concurrent access issues let device = self.device.clone(); let mut stream_capture = Self::create_capture_from_path(&device)?;