pipi cucu

This commit is contained in:
2026-04-02 00:14:43 -03:00
parent 73b824f6c3
commit 76ff720906
5 changed files with 217 additions and 27 deletions

View File

@@ -6,15 +6,15 @@
# Requires: sudo for kmsgrab, PulseAudio for audio capture
# Audio is non-blocking (monitor source = passive tap)
#
# Auto-restarts on stall: a watchdog checks ffmpeg's frame counter
# and kills/restarts if video freezes (DRM/VAAPI contention from
# other apps using the GPU, e.g. video calls).
# Auto-restarts on stall: watchdog checks output bytes + frame counter.
# Also restarts immediately on fatal kmsgrab errors (DRM plane format
# change from fullscreen / direct-scanout).
set -uo pipefail
RECEIVER_IP="${1:-mcrndeb}"
PORT="${2:-4444}"
STALL_TIMEOUT=10 # seconds with no frame progress before restart
STALL_TIMEOUT=10 # seconds with no progress before restart
# Let root access the user's PulseAudio session
REAL_UID="${SUDO_UID:-$(id -u)}"
@@ -33,7 +33,14 @@ echo "Streaming to: ${RECEIVER_IP}:${PORT}"
ulimit -n 65536
PROGRESS_FILE=$(mktemp)
trap 'rm -f "$PROGRESS_FILE"' EXIT
FFLOG=$(mktemp)
FFPID=""
cleanup() {
[ -n "$FFPID" ] && kill "$FFPID" 2>/dev/null && wait "$FFPID" 2>/dev/null
rm -f "$PROGRESS_FILE" "$FFLOG"
}
trap cleanup EXIT INT TERM
start_ffmpeg() {
local args=(
@@ -60,38 +67,57 @@ start_ffmpeg() {
-hide_banner -progress "$PROGRESS_FILE"
)
"${args[@]}" &
> "$FFLOG"
"${args[@]}" 2>"$FFLOG" &
echo $!
}
get_frame_count() {
# -progress file writes key=value pairs; frame= is the video frame counter
grep -oP '^frame=\K[0-9]+' "$PROGRESS_FILE" 2>/dev/null | tail -1
get_progress_val() {
grep -oP "^${1}=\K[0-9]+" "$PROGRESS_FILE" 2>/dev/null | tail -1
}
fatal_kmsgrab_error() {
grep -q "framebuffer format changed\|Error during demuxing" "$FFLOG" 2>/dev/null
}
while true; do
echo "--- Starting sender $(date) ---"
> "$PROGRESS_FILE" # reset
> "$PROGRESS_FILE"
FFPID=$(start_ffmpeg)
echo "ffmpeg started: pid=$FFPID"
last_bytes=0
last_frame=0
stall_since=$SECONDS
while kill -0 "$FFPID" 2>/dev/null; do
sleep 2
sleep 1
cur_frame=$(get_frame_count)
# Immediate restart on fatal kmsgrab errors (DRM plane format change)
if fatal_kmsgrab_error; then
echo "Fatal kmsgrab error — restarting immediately"
kill "$FFPID" 2>/dev/null
wait "$FFPID" 2>/dev/null
break
fi
cur_bytes=$(get_progress_val total_size)
cur_bytes=${cur_bytes:-0}
cur_frame=$(get_progress_val frame)
cur_frame=${cur_frame:-0}
if (( cur_frame > last_frame )); then
# Either metric advancing counts as healthy:
# total_size: catches TCP output stalls (muxer blocked)
# frame: catches kmsgrab/encoder stalls (audio keeps total_size ticking)
if (( cur_bytes > last_bytes || cur_frame > last_frame )); then
last_bytes=$cur_bytes
last_frame=$cur_frame
stall_since=$SECONDS
fi
if (( SECONDS - stall_since > STALL_TIMEOUT )); then
echo "Video stalled at frame $last_frame for ${STALL_TIMEOUT}s — killing ffmpeg"
echo "Stream stalled at frame ${last_frame} / ${last_bytes}B for ${STALL_TIMEOUT}s — killing ffmpeg"
kill "$FFPID" 2>/dev/null
wait "$FFPID" 2>/dev/null
break