From 6ecbf0d55695335f52d6fcf2b6a22ed45f5e4d99 Mon Sep 17 00:00:00 2001 From: dyknon Date: Mon, 24 Feb 2025 18:58:32 +0900 Subject: Remote camera capability. --- src/bin/sshcamera.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/bin/sshcamera.rs (limited to 'src/bin') diff --git a/src/bin/sshcamera.rs b/src/bin/sshcamera.rs new file mode 100644 index 0000000..02c8778 --- /dev/null +++ b/src/bin/sshcamera.rs @@ -0,0 +1,59 @@ +use anyhow::{anyhow, Result}; +use sshcamera::v4l2::{Device as V4l2, Field}; +use sshcamera::v4l2cairo::V4l2Cairo; +use sshcamera::gtk; +use sshcamera::v4l2abst::{CaptStream, RemoteCam}; +use sshcamera::io::RWBundle; +use gtk4::glib::ExitCode; +use std::env; +use std::io::{self, Read as _, Write as _}; +use std::process::{Command, Stdio}; + +fn main() -> Result{ + let mut args = env::args(); + if args.next() == None{ + return Err(anyhow!("arg0 is not present??")); + } + let Some(arg1) = args.next() else{ + return Err(anyhow!("Give me args")); + }; + if arg1.contains('/'){ + if args.next() != None{ + return Err(anyhow!("too many args")); + } + + let v = V4l2::open(arg1)?; + + // TODO: It should be better. + let mut c = v.captstream_builder()? + .set_pixelformat("MJPG".into()) + //.set_pixelformat("YUYV".into()) + .set_field(Field::None) + .build()?; + assert!(["YUYV", "MJPG"].contains(&c.pixelformat().as_str())); + assert!(c.field() == Field::None); + + let mut io = RWBundle(io::stdin(), io::stdout()); + loop{ + CaptStream::next(&mut c, |frame|{ + frame.serialize(&mut io)?; + io.flush()?; + let mut rb = [0]; + io.read_exact(&mut rb)?; + if rb[0] != 0x2e{ + return Err(anyhow!("protocol error")); + } + Ok(()) + })??; + } + }else{ + let child = Command::new(arg1) + .args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn()?; + let io = RWBundle(child.stdout.unwrap(), child.stdin.unwrap()); + let v2c = V4l2Cairo::new(RemoteCam::new(io)); + gtk::main(v2c) + } +} -- cgit v1.2.3