Add camera module: drive UVC webcam controls via cameractrls
New `camera` module in modules.example.yaml (and the embedded copy) with four functions: `set` (any control=value list, incl. preset/colour buttons), `toggle` (flip between two values), `adjust` (step a numeric control by a delta, clamped to the min/max parsed from `cameractrls -l`, with optional `extra` controls applied first), and `is` (poll helper, exit 0 on match). Device comes from CAMERA_DEVICE in .env (default /dev/video0) or a per-key `device` param. cameractrls exits 0 for unknown controls, so polls must use `is`; stderr is discarded to drop Python deprecation warnings. README: Camera module section with setup, function table, a folder example, and the oksvg viewBox-offset centring gotcha for SVG icons. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017iodiNMYL9iuT7f6WCe5iv
This commit is contained in:
@@ -206,3 +206,67 @@ modules:
|
||||
{{envDefault "OBS_CMD" "/usr/local/bin/obs-cmd"}} --websocket obsws://{{envDefault "OBS_HOST" "localhost"}}:{{envDefault "OBS_PORT" "4455"}}/{{env "OBS_WEBSOCKET_PASSWORD"}} scene transition-set "{{.transition}}" && \
|
||||
{{envDefault "OBS_CMD" "/usr/local/bin/obs-cmd"}} --websocket obsws://{{envDefault "OBS_HOST" "localhost"}}:{{envDefault "OBS_PORT" "4455"}}/{{env "OBS_WEBSOCKET_PASSWORD"}} scene transition-duration {{.duration}} && \
|
||||
{{envDefault "OBS_CMD" "/usr/local/bin/obs-cmd"}} --websocket obsws://{{envDefault "OBS_HOST" "localhost"}}:{{envDefault "OBS_PORT" "4455"}}/{{env "OBS_WEBSOCKET_PASSWORD"}} scene switch "{{.scene}}"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Camera — cameractrls (https://github.com/soyersoyer/cameractrls), Linux only.
|
||||
#
|
||||
# Drives any UVC webcam's V4L2 controls (zoom, pan/tilt, focus, exposure, white
|
||||
# balance, brightness/contrast/...). Install: pacman -S cameractrls / pip.
|
||||
#
|
||||
# Device: set CAMERA_DEVICE in ~/.config/streamdeck-go/.env to the stable path, e.g.
|
||||
# CAMERA_DEVICE=/dev/v4l/by-id/usb-046d_Logitech_BRIO_XXXX-video-index0
|
||||
# (defaults to /dev/video0; any function also takes a per-key `device` param).
|
||||
#
|
||||
# Discover control names/ranges: cameractrls -d /dev/video0 -l
|
||||
# Note: cameractrls exits 0 even for unknown controls, so poll blocks must use
|
||||
# the `is` function (which greps `-l` output) rather than exit codes.
|
||||
camera:
|
||||
# Set one or more controls, comma-separated (eg. "zoom_absolute=150,contrast=140").
|
||||
# Buttons work too: "preset=save_1", "preset=load_1", "color_preset=vivid".
|
||||
set:
|
||||
params:
|
||||
device: ""
|
||||
controls: "zoom_absolute=100"
|
||||
exec: /usr/bin/cameractrls -d {{if .device}}{{.device}}{{else}}{{envDefault "CAMERA_DEVICE" "/dev/video0"}}{{end}} -c "{{.controls}}" 2>/dev/null
|
||||
|
||||
# Flip a control between two values (a <-> b). Works for 0/1 and menu controls.
|
||||
toggle:
|
||||
params:
|
||||
device: ""
|
||||
control: auto_exposure
|
||||
a: aperture_priority_mode
|
||||
b: manual_mode
|
||||
exec: |
|
||||
cur=$(/usr/bin/cameractrls -d {{if .device}}{{.device}}{{else}}{{envDefault "CAMERA_DEVICE" "/dev/video0"}}{{end}} -l 2>/dev/null | sed -n 's/^ {{.control}} = \([^[:space:]]*\).*/\1/p')
|
||||
if [ "$cur" = "{{.a}}" ]; then v="{{.b}}"; else v="{{.a}}"; fi
|
||||
/usr/bin/cameractrls -d {{if .device}}{{.device}}{{else}}{{envDefault "CAMERA_DEVICE" "/dev/video0"}}{{end}} -c "{{.control}}=$v" 2>/dev/null
|
||||
|
||||
# Step a numeric control by delta (negative to decrease), clamped to its min/max.
|
||||
# `extra` is applied first on the same call — eg. "auto_exposure=manual_mode"
|
||||
# so stepping exposure also takes the camera out of auto.
|
||||
adjust:
|
||||
params:
|
||||
device: ""
|
||||
control: contrast
|
||||
delta: "16"
|
||||
extra: ""
|
||||
exec: |
|
||||
line=$(/usr/bin/cameractrls -d {{if .device}}{{.device}}{{else}}{{envDefault "CAMERA_DEVICE" "/dev/video0"}}{{end}} -l 2>/dev/null | grep '^ {{.control}} = ')
|
||||
cur=$(printf '%s\n' "$line" | sed -n 's/^ [a-z0-9_]* = \([-0-9]*\).*/\1/p')
|
||||
min=$(printf '%s\n' "$line" | sed -n 's/.*min: \([-0-9]*\).*/\1/p')
|
||||
max=$(printf '%s\n' "$line" | sed -n 's/.*max: \([-0-9]*\).*/\1/p')
|
||||
[ -n "$cur" ] || exit 1
|
||||
v=$((cur + {{.delta}}))
|
||||
[ -n "$min" ] && [ "$v" -lt "$min" ] && v=$min
|
||||
[ -n "$max" ] && [ "$v" -gt "$max" ] && v=$max
|
||||
ctl="{{.control}}=$v"
|
||||
[ -n "{{.extra}}" ] && ctl="{{.extra}},$ctl"
|
||||
/usr/bin/cameractrls -d {{if .device}}{{.device}}{{else}}{{envDefault "CAMERA_DEVICE" "/dev/video0"}}{{end}} -c "$ctl" 2>/dev/null
|
||||
|
||||
# Poll helper for toggle keys: exit 0 when control == value.
|
||||
is:
|
||||
params:
|
||||
device: ""
|
||||
control: auto_exposure
|
||||
value: aperture_priority_mode
|
||||
exec: /usr/bin/cameractrls -d {{if .device}}{{.device}}{{else}}{{envDefault "CAMERA_DEVICE" "/dev/video0"}}{{end}} -l 2>/dev/null | grep -q '^ {{.control}} = {{.value}}[[:space:]]'
|
||||
|
||||
Reference in New Issue
Block a user