flush configurable

This commit is contained in:
2026-04-03 12:05:29 -03:00
parent 074925c360
commit ade92069c0
3 changed files with 13 additions and 8 deletions

View File

@@ -16,6 +16,7 @@ RELAY_PORT = 4445 # UDP loopback relay for live display
# Frame extraction — scene-only, no interval fallback
SCENE_THRESHOLD = 0.10 # 0-1, lower = more sensitive; 0.1 catches slide/window changes
SCENE_FLUSH_FRAMES = 2 # extra frames after scene change to flush encoder/muxer buffer (0 to disable)
# Segment recording
SEGMENT_DURATION = 60 # seconds per .ts segment

View File

@@ -64,7 +64,7 @@ def receive_record_and_relay(stream_url, output_path, relay_url):
def receive_record_relay_and_detect(stream_url, output_path, relay_url,
scene_threshold=0.10):
scene_threshold=0.10, flush_frames=2):
"""Single process: receive TCP → record fMP4 + relay UDP + scene detect.
One ffmpeg process, three output branches from the same TCP input:
@@ -99,14 +99,16 @@ def receive_record_relay_and_detect(stream_url, output_path, relay_url,
# Scene detection: CUDA decode (GPU) → select filter (CPU, lightweight)
# → showinfo → MJPEG piped to stdout
#
# Flush trick: select the scene-change frame AND the next 2 frames.
# The pipeline has 2 levels of buffering (encoder + muxer), so we
# need 2 flush frames to push the real scene-change frame out.
# mod(selected_n,3) prevents chaining: after 2 flushes, selected_n
# hits a multiple of 3 and the chain stops.
scene_expr = f"gt(scene,{scene_threshold})"
flush_expr = "eq(n,prev_selected_n+1)*mod(selected_n,3)"
if flush_frames > 0:
# Flush trick: select extra frames after each scene change to push
# the real frame through the encoder+muxer buffer pipeline.
# mod(selected_n, 1+flush_frames) prevents chaining.
mod_val = 1 + flush_frames
flush_expr = f"eq(n,prev_selected_n+1)*mod(selected_n,{mod_val})"
select_expr = f"{scene_expr}+{flush_expr}"
else:
select_expr = scene_expr
scene_stream = stream.filter("select", select_expr).filter("showinfo")
scene_out = ffmpeg.output(
scene_stream, "pipe:1",

View File

@@ -19,6 +19,7 @@ from cht.config import (
STREAM_PORT,
RELAY_PORT,
SCENE_THRESHOLD,
SCENE_FLUSH_FRAMES,
SESSIONS_DIR,
AUDIO_EXTRACT_INTERVAL,
AUDIO_SAFETY_MARGIN,
@@ -197,6 +198,7 @@ class StreamManager:
node = ff.receive_record_relay_and_detect(
self.stream_url, self.recording_path, self.relay_url,
scene_threshold=self.scene_threshold,
flush_frames=SCENE_FLUSH_FRAMES,
)
proc = ff.run_async(node, pipe_stdout=True, pipe_stderr=True)
self._procs["recorder"] = proc