fix(sync): fail loud when tethys lacks gadget

This commit is contained in:
Brad Stein 2026-04-28 04:03:06 -03:00
parent cf210d7cf9
commit 7002ba514a
2 changed files with 64 additions and 10 deletions

View File

@ -43,6 +43,7 @@ FETCH_CAPTURE=${FETCH_CAPTURE:-0}
REMOTE_SERVER_PREFLIGHT=${REMOTE_SERVER_PREFLIGHT:-1}
REMOTE_EXPECT_CAM_OUTPUT=${REMOTE_EXPECT_CAM_OUTPUT:-uvc}
REMOTE_EXPECT_UVC_CODEC=${REMOTE_EXPECT_UVC_CODEC:-mjpeg}
CAPTURE_READY_MARKER="__LESAVKA_CAPTURE_READY__"
mkdir -p "${LOCAL_OUTPUT_DIR}"
STAMP="$(date +%Y%m%d-%H%M%S)"
@ -286,7 +287,8 @@ resolve_video_device() {
fi
fi
printf '/dev/video0\n'
printf 'Lesavka UVC video device not found on Tethys; refusing to fall back to an unrelated webcam/capture card.\n' >&2
exit 64
}
resolve_pulse_source() {
@ -305,6 +307,31 @@ resolve_pulse_source() {
'
}
resolve_alsa_audio_device() {
if ! command -v arecord >/dev/null 2>&1; then
return 1
fi
arecord -l 2>/dev/null | awk '
/^card [0-9]+:/ && ($0 ~ /Lesavka|UAC2_Gadget|UAC2Gadget|Composite/) {
card=$2
sub(":", "", card)
for (i = 1; i <= NF; i++) {
if ($i == "device") {
dev=$(i + 1)
sub(":", "", dev)
printf "hw:%s,%s\n", card, dev
found=1
exit 0
}
}
}
END {
if (!found) exit 1
}
'
}
gst_video_source_caps() {
case "${video_format}" in
""|mjpeg|MJPG)
@ -478,12 +505,16 @@ case "${remote_capture_stack}" in
if [[ "${remote_audio_source}" == "auto" ]]; then
if pulse_source="$(resolve_pulse_source)"; then
capture_mode="pulse"
elif alsa_audio_dev="$(resolve_alsa_audio_device)"; then
capture_mode="alsa"
printf 'PipeWire Lesavka source not found; falling back to ALSA device %s\n' "${alsa_audio_dev}" >&2
elif command -v pw-record >/dev/null 2>&1 \
&& command -v pw-v4l2 >/dev/null 2>&1 \
&& pw_audio_target="$(resolve_pw_audio_target)"; then
capture_mode="pwpipe"
else
printf 'PipeWire Lesavka source not found; falling back to hw:3,0\n' >&2
printf 'Lesavka audio source not found in PipeWire or ALSA; capture host does not currently expose the gadget microphone.\n' >&2
exit 64
fi
elif [[ "${remote_audio_source}" == pulse:* ]]; then
capture_mode="pulse"
@ -538,6 +569,7 @@ resolved_video_size="$(resolve_video_size "${video_size}")"
resolved_video_fps="$(resolve_video_fps "${video_fps}")"
printf 'using video device: %s\n' "${resolved_video_device}" >&2
printf 'using video mode: %s @ %s fps (%s)\n' "${resolved_video_size}" "${resolved_video_fps}" "${video_format:-driver-default}" >&2
printf '%s\n' "__LESAVKA_CAPTURE_READY__"
video_args=(-f video4linux2 -framerate "${resolved_video_fps}" -video_size "${resolved_video_size}")
if [[ -n "${video_format}" ]]; then
video_args+=(-input_format "${video_format}")
@ -699,13 +731,28 @@ fi
REMOTE_CAPTURE_SCRIPT
capture_pid=$!
sleep 1
if ! kill -0 "${capture_pid}" >/dev/null 2>&1; then
capture_status=0
wait "${capture_pid}" || capture_status=$?
echo "Tethys capture failed before the sync probe could start; see ${LOCAL_CAPTURE_LOG} for details." >&2
exit "${capture_status}"
fi
wait_for_capture_ready() {
local tries=100
local i=0
while (( i < tries )); do
if [[ -f "${LOCAL_CAPTURE_LOG}" ]] && grep -q "${CAPTURE_READY_MARKER}" "${LOCAL_CAPTURE_LOG}"; then
return 0
fi
if ! kill -0 "${capture_pid}" >/dev/null 2>&1; then
capture_status=0
wait "${capture_pid}" || capture_status=$?
echo "Tethys capture failed before the sync probe could start; see ${LOCAL_CAPTURE_LOG} for details." >&2
exit "${capture_status}"
fi
sleep 0.1
((i += 1))
done
echo "Timed out waiting for Tethys capture to become ready; see ${LOCAL_CAPTURE_LOG} for details." >&2
exit 90
}
wait_for_capture_ready
sleep "${LEAD_IN_SECONDS}"

View File

@ -18,8 +18,15 @@ fn upstream_sync_script_tunnels_auto_server_addr_through_ssh() {
"127.0.0.1:${local_port}:127.0.0.1:${remote_port}",
"RESOLVED_LESAVKA_SERVER_ADDR=\"http://127.0.0.1:${SERVER_TUNNEL_LOCAL_PORT}\"",
"tunneled to ${LESAVKA_SERVER_HOST}:127.0.0.1:${SERVER_TUNNEL_REMOTE_PORT}",
"CAPTURE_READY_MARKER=\"__LESAVKA_CAPTURE_READY__\"",
"Tethys capture failed before the sync probe could start",
"kill -0 \"${capture_pid}\"",
"wait_for_capture_ready",
"Timed out waiting for Tethys capture to become ready",
"grep -q \"${CAPTURE_READY_MARKER}\"",
"Lesavka UVC video device not found on Tethys; refusing to fall back to an unrelated webcam/capture card.",
"resolve_alsa_audio_device",
"PipeWire Lesavka source not found; falling back to ALSA device",
"Lesavka audio source not found in PipeWire or ALSA; capture host does not currently expose the gadget microphone.",
] {
assert!(
SYNC_SCRIPT.contains(expected),