asdfasdfawds
This commit is contained in:
@@ -18,6 +18,7 @@ from cht.config import (
|
||||
STREAM_HOST,
|
||||
STREAM_PORT,
|
||||
RELAY_PORT,
|
||||
SCENE_RELAY_PORT,
|
||||
SCENE_THRESHOLD,
|
||||
SESSIONS_DIR,
|
||||
AUDIO_EXTRACT_INTERVAL,
|
||||
@@ -155,6 +156,10 @@ class StreamManager:
|
||||
def relay_url(self):
|
||||
return f"udp://127.0.0.1:{RELAY_PORT}"
|
||||
|
||||
@property
|
||||
def scene_relay_url(self):
|
||||
return f"udp://127.0.0.1:{SCENE_RELAY_PORT}"
|
||||
|
||||
@property
|
||||
def recording_path(self):
|
||||
"""Current recording segment path."""
|
||||
@@ -193,7 +198,9 @@ class StreamManager:
|
||||
return proc is not None and proc.poll() is None
|
||||
|
||||
def _launch_recorder(self):
|
||||
node = ff.receive_record_and_relay(self.stream_url, self.recording_path, self.relay_url)
|
||||
node = ff.receive_record_and_relay(
|
||||
self.stream_url, self.recording_path, self.relay_url,
|
||||
)
|
||||
proc = ff.run_async(node, pipe_stderr=True)
|
||||
self._procs["recorder"] = proc
|
||||
log.info("Recorder: pid=%s → %s", proc.pid, self.recording_path)
|
||||
@@ -211,38 +218,38 @@ class StreamManager:
|
||||
|
||||
def _detect():
|
||||
processed_time = 0.0
|
||||
idle_cycles = 0
|
||||
current_segment = None
|
||||
last_threshold = self.scene_threshold
|
||||
|
||||
while "stop" not in self._stop_flags:
|
||||
# Adaptive sleep: faster at lower thresholds (more sensitive)
|
||||
# threshold 0.01→1s base, 0.10→1s, 0.50→2s
|
||||
base = max(1.0, min(2.0, self.scene_threshold * 10))
|
||||
sleep_secs = base if idle_cycles == 0 else min(base * 2, base * (2 ** idle_cycles))
|
||||
time.sleep(sleep_secs)
|
||||
time.sleep(1.0)
|
||||
|
||||
# Threshold changed — reset to re-process recent content
|
||||
if self.scene_threshold != last_threshold:
|
||||
log.info("Threshold changed %.2f → %.2f, resetting",
|
||||
last_threshold, self.scene_threshold)
|
||||
last_threshold = self.scene_threshold
|
||||
# Back up a bit to re-scan with new sensitivity
|
||||
processed_time = max(0.0, processed_time - 10)
|
||||
|
||||
seg = self.recording_path
|
||||
if not seg.exists():
|
||||
continue
|
||||
|
||||
# New segment started — reset per-segment progress
|
||||
if seg != current_segment:
|
||||
current_segment = seg
|
||||
processed_time = 0.0
|
||||
idle_cycles = 0
|
||||
log.info("Scene detector: switched to %s", seg.name)
|
||||
|
||||
size = seg.stat().st_size
|
||||
if size < 100_000:
|
||||
continue
|
||||
|
||||
# Probe current segment duration directly (not total across segments)
|
||||
safe_duration = self._estimate_safe_duration()
|
||||
if safe_duration is None or safe_duration <= 0:
|
||||
continue
|
||||
|
||||
# 2s safety margin for incomplete tail fragments
|
||||
process_to = safe_duration - 2
|
||||
process_to = safe_duration - 1
|
||||
if process_to <= processed_time + 0.5:
|
||||
continue
|
||||
|
||||
@@ -253,13 +260,10 @@ class StreamManager:
|
||||
)
|
||||
|
||||
if new_frames:
|
||||
idle_cycles = 0
|
||||
log.info("Found %d new scene frames (total: %d)",
|
||||
len(new_frames), self._next_frame_number() - 1)
|
||||
if self._on_new_frames:
|
||||
self._on_new_frames(new_frames)
|
||||
else:
|
||||
idle_cycles += 1
|
||||
|
||||
processed_time = process_to
|
||||
|
||||
@@ -338,8 +342,7 @@ class StreamManager:
|
||||
continue
|
||||
pts_match = re.search(r"pts_time:\s*([\d.]+)", line)
|
||||
if pts_match:
|
||||
# pts_time is relative to -ss seek point, add start_time for local offset
|
||||
pts_time = float(pts_match.group(1)) + start_time
|
||||
pts_time = float(pts_match.group(1))
|
||||
frame_id = f"F{frame_num:04d}"
|
||||
frame_path = self.frames_dir / f"{frame_id}.jpg"
|
||||
if frame_path.exists():
|
||||
|
||||
Reference in New Issue
Block a user