client: webcam fixes on v41 constants
This commit is contained in:
parent
3cdf5c0718
commit
b56789d081
@ -1,13 +1,11 @@
|
|||||||
// client/src/input/camera.rs
|
// client/src/input/camera.rs
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use gstreamer as gst;
|
use gstreamer as gst;
|
||||||
use gstreamer_app as gst_app;
|
use gstreamer_app as gst_app;
|
||||||
use gst::prelude::*;
|
use gst::prelude::*;
|
||||||
use lesavka_common::lesavka::VideoPacket;
|
use lesavka_common::lesavka::VideoPacket;
|
||||||
use v4l::capability::Capabilities;
|
|
||||||
|
|
||||||
pub struct CameraCapture {
|
pub struct CameraCapture {
|
||||||
pipeline: gst::Pipeline,
|
pipeline: gst::Pipeline,
|
||||||
@ -127,17 +125,18 @@ impl CameraCapture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_capture(dev: &str) -> bool {
|
fn is_capture(dev: &str) -> bool {
|
||||||
match v4l::Device::with_path(dev) {
|
const V4L2_CAP_VIDEO_CAPTURE: u32 = 0x0000_0001;
|
||||||
Ok(d) => d
|
const V4L2_CAP_VIDEO_CAPTURE_MPLANE: u32 = 0x0000_1000;
|
||||||
.query_caps()
|
|
||||||
.map(|caps| {
|
v4l::Device::with_path(dev)
|
||||||
let c = caps.capabilities;
|
.ok()
|
||||||
c.contains(Capabilities::VIDEO_CAPTURE)
|
.and_then(|d| d.query_caps().ok())
|
||||||
|| c.contains(Capabilities::VIDEO_CAPTURE_MPLANE)
|
.map(|caps| {
|
||||||
})
|
let bits = caps.capabilities.bits();
|
||||||
.unwrap_or(false),
|
(bits & V4L2_CAP_VIDEO_CAPTURE != 0)
|
||||||
Err(_) => false,
|
|| (bits & V4L2_CAP_VIDEO_CAPTURE_MPLANE != 0)
|
||||||
}
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cheap stub used when the web‑cam is disabled
|
/// Cheap stub used when the web‑cam is disabled
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use evdev::{Device, EventType, KeyCode, RelativeAxisCode};
|
use evdev::{Device, EventType, KeyCode, RelativeAxisCode};
|
||||||
use tokio::{sync::broadcast::Sender, time::{interval, Duration}};
|
use tokio::{sync::broadcast::Sender, time::{interval, Duration}};
|
||||||
use tracing::{debug, info, warn, trace};
|
use tracing::{debug, info, warn};
|
||||||
|
|
||||||
use lesavka_common::lesavka::{KeyboardReport, MouseReport};
|
use lesavka_common::lesavka::{KeyboardReport, MouseReport};
|
||||||
|
|
||||||
|
|||||||
@ -157,20 +157,16 @@ fn pick_sink_element() -> Result<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn list_pw_sinks() -> Vec<(String, String)> {
|
fn list_pw_sinks() -> Vec<(String, String)> {
|
||||||
let mut out = Vec::new();
|
// ── PulseAudio / pactl fallback ────────────────────────────────
|
||||||
if out.is_empty() {
|
if let Ok(info) = std::process::Command::new("pactl")
|
||||||
// ── PulseAudio / pactl fallback ────────────────────────────────
|
.args(["info"])
|
||||||
if let Ok(info) = std::process::Command::new("pactl")
|
.output()
|
||||||
.args(["info"])
|
.map(|o| String::from_utf8_lossy(&o.stdout).to_string())
|
||||||
.output()
|
{
|
||||||
.map(|o| String::from_utf8_lossy(&o.stdout).to_string())
|
if let Some(line) = info.lines().find(|l| l.starts_with("Default Sink:")) {
|
||||||
{
|
let def = line["Default Sink:".len()..].trim();
|
||||||
if let Some(line) = info.lines().find(|l| l.starts_with("Default Sink:")) {
|
return vec![(def.to_string(), "UNKNOWN".to_string())];
|
||||||
let def = line["Default Sink:".len()..].trim();
|
|
||||||
return vec![(def.to_string(), "UNKNOWN".to_string())];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Vec::new()
|
||||||
out
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,14 @@
|
|||||||
// client/src/output/video.rs
|
// client/src/output/video.rs
|
||||||
|
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::time::Duration;
|
|
||||||
use std::thread;
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use gstreamer as gst;
|
use gstreamer as gst;
|
||||||
|
use gst::glib::{Cast, ObjectExt};
|
||||||
use gstreamer_app as gst_app;
|
use gstreamer_app as gst_app;
|
||||||
use gstreamer_video::{prelude::*, VideoOverlay};
|
use gstreamer_video::VideoOverlay;
|
||||||
use gst::prelude::*;
|
use gstreamer_video::prelude::VideoOverlayExtManual;
|
||||||
use lesavka_common::lesavka::VideoPacket;
|
use lesavka_common::lesavka::VideoPacket;
|
||||||
use tracing::{error, info, warn, debug};
|
use tracing::{error, info, warn, debug};
|
||||||
use gstreamer_video as gst_video;
|
|
||||||
use gstreamer_video::glib::Type;
|
|
||||||
|
|
||||||
use crate::output::{display, layout};
|
use crate::output::{display, layout};
|
||||||
|
|
||||||
@ -63,7 +60,7 @@ impl MonitorWindow {
|
|||||||
/* -------- move/resize overlay ---------------------------------- */
|
/* -------- move/resize overlay ---------------------------------- */
|
||||||
if let Some(sink_elem) = pipeline.by_name("sink") {
|
if let Some(sink_elem) = pipeline.by_name("sink") {
|
||||||
// give the native window a predictable title for wmctrl/placement
|
// give the native window a predictable title for wmctrl/placement
|
||||||
sink_elem.set_property("window-title", &format!("Lesavka-eye-{id}")).ok();
|
let _ = sink_elem.set_property("window-title", &format!("Lesavka-eye-{id}"));
|
||||||
|
|
||||||
if let Ok(overlay) = sink_elem.dynamic_cast::<VideoOverlay>() {
|
if let Ok(overlay) = sink_elem.dynamic_cast::<VideoOverlay>() {
|
||||||
if let Some(r) = rects.get(id as usize) {
|
if let Some(r) = rects.get(id as usize) {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ ORIG_USER=${SUDO_USER:-$(id -un)}
|
|||||||
|
|
||||||
# 1. packages (Arch)
|
# 1. packages (Arch)
|
||||||
sudo pacman -Syq --needed --noconfirm \
|
sudo pacman -Syq --needed --noconfirm \
|
||||||
git rustup protobuf gcc evtest base-devel \
|
git rustup protobuf gcc clang evtest base-devel \
|
||||||
gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav \
|
gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav \
|
||||||
pipewire pipewire-pulse \
|
pipewire pipewire-pulse \
|
||||||
wmctrl qt6-tools
|
wmctrl qt6-tools
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user