forked from dsutanto/zenai-kpc-python
cap written stream error
This commit is contained in:
1 parent
b52e876eed
commit
706f9261fb
3 files changed
+57
-3
No files matched your search
@@ -207,6 +207,10 @@ WARMUP_FRAMES=30
|
||||
RECONNECT_DELAY_SEC=3
|
||||
# Maximum reconnection attempts (0 = infinite)
|
||||
MAX_RECONNECT_ATTEMPTS=0
|
||||
# Max stream-error log lines per outage (Cannot open / Stream dropped).
|
||||
# After this, further errors are silent until the stream recovers; then the
|
||||
# budget resets for the next outage. 0 = unlimited.
|
||||
STREAM_ERROR_LOG_MAX=3
|
||||
# Seconds after which a tracked but unseen object is pruned from the active set
|
||||
TRACKED_PRUNE_SEC=300
|
||||
|
||||
|
||||
+51
-3
@@ -96,6 +96,10 @@ RATE_WINDOW_SEC = int(os.getenv("RATE_WINDOW_SEC", "60"))
|
||||
WARMUP_FRAMES = int(os.getenv("WARMUP_FRAMES", "30"))
|
||||
RECONNECT_DELAY_SEC = int(os.getenv("RECONNECT_DELAY_SEC", "3"))
|
||||
MAX_RECONNECT_ATTEMPTS = int(os.getenv("MAX_RECONNECT_ATTEMPTS", "0"))
|
||||
# Max stream-error prints per outage (Cannot open / Stream dropped). After this,
|
||||
# further errors are silent until the stream recovers, then the budget resets.
|
||||
# 0 = unlimited (old behavior).
|
||||
STREAM_ERROR_LOG_MAX = int(os.getenv("STREAM_ERROR_LOG_MAX", "3"))
|
||||
TRACKED_PRUNE_SEC = int(os.getenv("TRACKED_PRUNE_SEC", "300"))
|
||||
RECORD_VIDEO = os.getenv("RECORD_VIDEO", "false").lower() == "true"
|
||||
VIDEO_SEGMENT_SEC = int(os.getenv("VIDEO_SEGMENT_SEC", "3600")) # legacy segment mode only
|
||||
@@ -1168,6 +1172,46 @@ def draw_popups(img, popups, frame_idx):
|
||||
return alive
|
||||
|
||||
|
||||
class StreamErrorLog:
|
||||
"""Rate-limit stream error prints to STREAM_ERROR_LOG_MAX per outage.
|
||||
|
||||
After the cap, messages are suppressed until note_up() when the stream
|
||||
is healthy again; the next drop starts a fresh budget.
|
||||
"""
|
||||
|
||||
def __init__(self, max_logs=STREAM_ERROR_LOG_MAX):
|
||||
self.max_logs = int(max_logs)
|
||||
self._emitted = 0
|
||||
self._suppressed = 0
|
||||
|
||||
def emit(self, msg: str) -> None:
|
||||
if self.max_logs <= 0:
|
||||
print(msg)
|
||||
return
|
||||
if self._emitted < self.max_logs:
|
||||
self._emitted += 1
|
||||
print(msg)
|
||||
if self._emitted >= self.max_logs:
|
||||
print(
|
||||
f"[{now_str()}] Stream errors capped at {self.max_logs} "
|
||||
f"this outage — further messages suppressed until stream recovers"
|
||||
)
|
||||
else:
|
||||
self._suppressed += 1
|
||||
|
||||
def note_up(self) -> None:
|
||||
if self._suppressed > 0:
|
||||
print(
|
||||
f"[{now_str()}] Stream recovered "
|
||||
f"(suppressed {self._suppressed} error log(s) during outage)"
|
||||
)
|
||||
self._emitted = 0
|
||||
self._suppressed = 0
|
||||
|
||||
|
||||
stream_error_log = StreamErrorLog()
|
||||
|
||||
|
||||
def connect_stream(source, warmup=WARMUP_FRAMES):
|
||||
attempts = 0
|
||||
while not shutdown_requested:
|
||||
@@ -1178,7 +1222,9 @@ def connect_stream(source, warmup=WARMUP_FRAMES):
|
||||
raise RuntimeError(
|
||||
f"Cannot open source after {attempts} attempts: {source}"
|
||||
)
|
||||
print(f"Cannot open source, retry in {RECONNECT_DELAY_SEC}s...")
|
||||
stream_error_log.emit(
|
||||
f"Cannot open source, retry in {RECONNECT_DELAY_SEC}s..."
|
||||
)
|
||||
time.sleep(RECONNECT_DELAY_SEC)
|
||||
continue
|
||||
if warmup > 0 and source.lower().startswith(("rtsp://", "http://")):
|
||||
@@ -1188,6 +1234,7 @@ def connect_stream(source, warmup=WARMUP_FRAMES):
|
||||
fps = cap.get(cv2.CAP_PROP_FPS)
|
||||
if not fps or fps <= 1:
|
||||
fps = OUTPUT_FPS
|
||||
stream_error_log.note_up()
|
||||
return cap, w, h, fps
|
||||
return None, 0, 0, OUTPUT_FPS
|
||||
|
||||
@@ -1349,8 +1396,9 @@ def run():
|
||||
if not IS_LIVE:
|
||||
break
|
||||
reconnect_count += 1
|
||||
print(
|
||||
f"Stream dropped (attempt {reconnect_count}), reconnecting in {RECONNECT_DELAY_SEC}s..."
|
||||
stream_error_log.emit(
|
||||
f"Stream dropped (attempt {reconnect_count}), "
|
||||
f"reconnecting in {RECONNECT_DELAY_SEC}s..."
|
||||
)
|
||||
cap.release()
|
||||
time.sleep(RECONNECT_DELAY_SEC)
|
||||
|
||||
@@ -131,6 +131,8 @@ RATE_WINDOW_SEC=60
|
||||
WARMUP_FRAMES=30
|
||||
RECONNECT_DELAY_SEC=3
|
||||
MAX_RECONNECT_ATTEMPTS=0
|
||||
# Max stream-error logs per outage; resets when stream recovers. 0 = unlimited.
|
||||
STREAM_ERROR_LOG_MAX=3
|
||||
TRACKED_PRUNE_SEC=300
|
||||
|
||||
# --- Live stream snapshot ---
|
||||
|
||||
Reference in new issue
Block a user