Skip to content

Commit 8a1e113

Browse files
committed
Fix crash recovery limit logic: default unlimited, non-cumulative
BREAKING CHANGE: Crash recovery limit now defaults to unlimited (0). - Removed cumulative CRASH_COUNT behavior that caused permanent disables - Limit now applies per crash event only, not across sessions - Optional per-crash limit via OBS_SAFE_LAUNCH_CRASH_LIMIT env var (0=unlimited) - Added input validation for crash limit environment variable - Updated documentation to reflect unlimited-by-default behavior - Fixed typo in loopback compatibility section This fixes the counterproductive reconnect counter that would lock out recovery after 3 unrelated crashes in the same session or across reboots.
1 parent 0678f7c commit 8a1e113

2 files changed

Lines changed: 20 additions & 14 deletions

File tree

docs/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Stabilise high-throughput USB capture devices for OBS on Linux. Provides auto-re
44

55
## Features
66

7-
- **Automatic crash recovery** — OBS restarts automatically on USB device failure (3 retry limit)
7+
- **Automatic crash recovery** — OBS restarts automatically on USB device failure (unlimited by default)
88
- **Stream resumption** — Monitors logs to detect active streams, auto-resumes if one was broadcasting
99
- **v4l2loopback isolation** — FFmpeg feeds capture to `/dev/video10`, preventing OBS crashes from driver issues
1010
- **Auto-reconnect** — Monitors device and restarts feed on disconnect
@@ -187,11 +187,12 @@ lsusb | grep -i "your-device"
187187

188188
**Safety launcher features:**
189189
- ✅ Monitors USB device health
190-
- ✅ Auto-restarts OBS on crash (max 3 attempts, 3s recovery timeout)
190+
- ✅ Auto-restarts OBS on crash (unlimited by default, 3s recovery timeout)
191191
- ✅ Detects if streaming was active before crash
192192
- ✅ Auto-resumes stream if it was broadcasting (enabled by default)
193193
- ✅ Captures full OBS output to log file for diagnostics
194194
- ✅ Logs to `~/.cache/obs-safe-launch/`
195+
- ✅ Optional per-crash limit via `OBS_SAFE_LAUNCH_CRASH_LIMIT` (`0` = unlimited)
195196

196197
**Safety launcher flags:**
197198
| Flag | Purpose |
@@ -209,7 +210,7 @@ lsusb | grep -i "your-device"
209210
2. Wrapper waits 3 seconds for device/system to stabilize
210211
3. Checks OBS logs for active stream indication
211212
4. Restarts OBS with `--startstreaming` flag if stream was active
212-
5. If OBS crashes 3 times, requires human intervention
213+
5. Repeats this flow on future crashes (no cumulative cap unless `OBS_SAFE_LAUNCH_CRASH_LIMIT` is set)
213214

214215
**Note:** Auto-reconnect requires sudo for USB hardware recovery (device resets, driver rebind). To avoid password prompts during long-running crash recovery, install the sudoers rule:
215216
```bash

scripts/obs-safe-launch.sh

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ FEED_PID_FILE="/tmp/obs-safe-launch-feed.pid"
2222
STREAM_STATE_FILE="/tmp/obs-safe-launch-streaming.state"
2323
MONITOR_INTERVAL=5
2424
RECOVERY_TIMEOUT=3
25-
CRASH_THRESHOLD=3 # Max consecutive crashes before requiring user intervention
26-
CRASH_COUNT=0
25+
CRASH_THRESHOLD="${OBS_SAFE_LAUNCH_CRASH_LIMIT:-0}" # 0 = unlimited; non-zero applies per crash event only
2726
WAS_STREAMING=0
2827
AUTO_RESUME_ENABLED=1 # Enable auto-resume by default
2928

@@ -415,6 +414,7 @@ detect_streaming_state() {
415414
handle_obs_exit() {
416415
set +e # Disable error exit for this function
417416
local exit_code="$1"
417+
local crash_attempt=1
418418

419419
# Detect if OBS was streaming before crash
420420
detect_streaming_state && WAS_STREAMING=1
@@ -423,16 +423,17 @@ handle_obs_exit() {
423423

424424
# Check if this was a crash (non-zero exit or signal)
425425
if [ "$exit_code" -ne 0 ]; then
426-
CRASH_COUNT=$((CRASH_COUNT + 1))
427-
log_info "CRASH_COUNT incremented to: $CRASH_COUNT"
428-
429-
if [ $CRASH_COUNT -gt $CRASH_THRESHOLD ]; then
430-
log_error "OBS crashed $CRASH_COUNT times (threshold: $CRASH_THRESHOLD). Requiring user intervention."
426+
if [ "$CRASH_THRESHOLD" -gt 0 ] && [ "$crash_attempt" -gt "$CRASH_THRESHOLD" ]; then
427+
log_error "Crash recovery blocked by OBS_SAFE_LAUNCH_CRASH_LIMIT=$CRASH_THRESHOLD"
431428
set -e
432429
return 1
433430
fi
434431

435-
log_recovery "Attempting recovery (crash $CRASH_COUNT/$CRASH_THRESHOLD)"
432+
if [ "$CRASH_THRESHOLD" -gt 0 ]; then
433+
log_recovery "Attempting recovery (event attempt $crash_attempt/$CRASH_THRESHOLD)"
434+
else
435+
log_recovery "Attempting recovery (unlimited mode)"
436+
fi
436437
log_recovery "Waiting ${RECOVERY_TIMEOUT}s before restart..."
437438
sleep $RECOVERY_TIMEOUT
438439

@@ -456,8 +457,7 @@ handle_obs_exit() {
456457
set -e
457458
return 0
458459
else
459-
CRASH_COUNT=0
460-
log_info "Clean exit, resetting crash count"
460+
log_info "Clean exit"
461461
set -e
462462
return 0
463463
fi
@@ -476,6 +476,12 @@ main() {
476476
log_info "DEVICE_CHECK: $([ "$SKIP_DEVICE_CHECK" -eq 1 ] && echo "disabled" || echo "enabled")"
477477
log_info "OBS_ARGS: ${OBS_ARGS:-none}"
478478

479+
if ! [[ "$CRASH_THRESHOLD" =~ ^[0-9]+$ ]]; then
480+
log_warn "Invalid OBS_SAFE_LAUNCH_CRASH_LIMIT='$CRASH_THRESHOLD' (expected integer). Falling back to 0 (unlimited)."
481+
CRASH_THRESHOLD=0
482+
fi
483+
log_info "CRASH_LIMIT: $CRASH_THRESHOLD (0=unlimited, per crash event)"
484+
479485
pre_flight_checks
480486
load_driver_optimizations
481487

@@ -522,7 +528,6 @@ main() {
522528

523529
if [ $EXIT_CODE -eq 0 ]; then
524530
log_info "OBS exited normally"
525-
CRASH_COUNT=0
526531
break
527532
else
528533
log_info "Calling handle_obs_exit with exit code: $EXIT_CODE"

0 commit comments

Comments
 (0)