Files
clipbin-desktop/scripts/validate/linux-hardware.sh
T
harry 06377de707
Rust checks / windows-cross-check (push) Failing after 40s
Rust checks / linux (push) Failing after 5m38s
fix: fail on refused portal requests and catch black recordings
The portal reports refusals only in OBS's log; a denied, cancelled or failed
source selection now fails with an actionable reason instead of waiting
forever. check --expect-motion rejects black or frozen footage, and the
hardware script checks only runs that recorded, tests restore tokens in their
own step, and treats closing a window as informational: on Hyprland the
stream keeps its last frame, so sessions must end on game exit.
2026-10-08 15:01:25 +02:00

94 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Hardware sign-off for Linux: run from a real desktop session (Hyprland,
# another Wayland compositor, or X11) on the machine being validated.
#
# scripts/validate/linux-hardware.sh [output-dir]
#
# Records at 1440p60 with every usable hardware codec, checks the segments,
# confirms the portal restores its selection without asking again, and
# records a window. Writes report.txt in the output directory.
set -uo pipefail
repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
out="${1:-${TMPDIR:-/tmp}/clipbin-hardware}"
probe="${repo}/target/debug/clipbin-probe"
report="${out}/report.txt"
rm -rf "${out}" && mkdir -p "${out}"
format=(--width 2560 --height 1440 --fps 60 --bitrate 40000)
cargo build --locked -p clipbin-probe --manifest-path "${repo}/Cargo.toml" || exit 1
log() { echo "$*" | tee -a "${report}"; }
ask() {
local answer
read -r -p "$1 [y/n] " answer
log "answer: $1 -> ${answer}"
}
# record <name> <codec> [probe args...]: records 20 s, then checks the
# segments only if the probe reached Recording.
record() {
local name="$1" codec="$2" dir="${out}/$1"
shift 2
"${probe}" record --codec "${codec}" "$@" --seconds 20 "${format[@]}" --out "${dir}" \
> "${dir}.log" 2> "${dir}.obs.log"
local record_exit=$?
if grep -q '^recorded=true' "${dir}.log"; then
"${probe}" check --codec "${codec}" --expect-motion --out "${dir}" >> "${dir}.log" 2>&1
log "${name}: record_exit=${record_exit} check_exit=$? $(grep -E '^(encoder|check|motion)' "${dir}.log" | tr '\n' ' ')"
else
log "${name}: FAIL never reached Recording (record_exit=${record_exit})"
fi
log " $(grep -E 'status=' "${dir}.log" | tr '\n' ' ')"
}
log "Clipbin hardware validation $(date -Is)"
log "host: $(uname -r) session=${XDG_SESSION_TYPE:-?} desktop=${XDG_CURRENT_DESKTOP:-?}"
log "gpu: $(lspci 2>/dev/null | grep -iE 'vga|display' | cut -d: -f3- | xargs)"
"${probe}" encoders --verify "${format[@]}" --out "${out}/encoders" > "${out}/encoders.log" 2> "${out}/encoders.obs.log"
log "$(grep -E '^(obs_version|usable\.|verify\.)' "${out}/encoders.log")"
echo
echo "Each recording opens the screen-share picker: pick a monitor with motion on"
echo "it (a video or game). Tick \"Allow a restore token\" (Hyprland) or"
echo "\"Remember this selection\" when the picker offers it."
for codec in h264 hevc av1; do
if grep -q "^usable\.${codec}=none" "${out}/encoders.log"; then
log "SKIP ${codec}: no usable hardware encoder"
continue
fi
record "monitor-${codec}" "${codec}" --target monitor
done
# Restoring the last selection must not show the picker again.
token="$(sed -n 's/^restore_token=//p' "${out}"/monitor-*.log | tail -1)"
if [[ -n "${token}" ]]; then
echo
echo "Recording again with the saved selection. The picker should NOT appear."
record monitor-restored h264 --target monitor --restore-token "${token}"
ask "Did the recording start WITHOUT showing the picker?"
else
log "restore: FAIL no restore token was returned (was \"Allow a restore token\" ticked?)"
fi
echo
echo "Now recording a window for 20 seconds. Start a game (or any moving"
echo "window) first, then pick it in the picker."
read -r -p "Press Enter when ready. " _
record window-h264 h264 --target window
# On Wayland the portal may keep streaming a closed window's last frame, so
# this is informational: Clipbin ends sessions when the game process exits.
echo
echo "Last: record a window again and close it (quit the app) about 5 seconds in."
read -r -p "Press Enter when ready. " _
dir="${out}/window-closed"
"${probe}" record --target window --seconds 20 "${format[@]}" --out "${dir}" > "${dir}.log" 2> "${dir}.obs.log"
log "window-closed (informational): exit=$? $(grep -E 'status=' "${dir}.log" | tail -1)"
ask "Did you quit the captured app about 5 seconds in?"
echo
echo "Report: ${report}"
echo "Recordings and logs: ${out}"