one behind duplicated, and the correct
This commit is contained in:
@@ -98,7 +98,15 @@ def receive_record_relay_and_detect(stream_url, output_path, relay_url,
|
|||||||
|
|
||||||
# Scene detection: CUDA decode (GPU) → select filter (CPU, lightweight)
|
# Scene detection: CUDA decode (GPU) → select filter (CPU, lightweight)
|
||||||
# → showinfo → MJPEG piped to stdout
|
# → showinfo → MJPEG piped to stdout
|
||||||
select_expr = f"gt(scene,{scene_threshold})"
|
#
|
||||||
|
# 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)"
|
||||||
|
select_expr = f"{scene_expr}+{flush_expr}"
|
||||||
scene_stream = stream.filter("select", select_expr).filter("showinfo")
|
scene_stream = stream.filter("select", select_expr).filter("showinfo")
|
||||||
scene_out = ffmpeg.output(
|
scene_out = ffmpeg.output(
|
||||||
scene_stream, "pipe:1",
|
scene_stream, "pipe:1",
|
||||||
|
|||||||
@@ -263,6 +263,7 @@ class StreamManager:
|
|||||||
def _read_stdout():
|
def _read_stdout():
|
||||||
frame_num = start_number
|
frame_num = start_number
|
||||||
offset = self.current_global_offset
|
offset = self.current_global_offset
|
||||||
|
last_pts = -1.0
|
||||||
buf = b""
|
buf = b""
|
||||||
raw_fd = proc.stdout.fileno()
|
raw_fd = proc.stdout.fileno()
|
||||||
while True:
|
while True:
|
||||||
@@ -288,6 +289,12 @@ class StreamManager:
|
|||||||
log.warning("No timestamp for scene frame %d", frame_num)
|
log.warning("No timestamp for scene frame %d", frame_num)
|
||||||
pts_time = 0.0
|
pts_time = 0.0
|
||||||
|
|
||||||
|
# Skip flush frames (within 100ms of previous = duplicate)
|
||||||
|
if pts_time - last_pts < 0.1:
|
||||||
|
log.debug("Skipping flush frame at pts=%.3f", pts_time)
|
||||||
|
continue
|
||||||
|
last_pts = pts_time
|
||||||
|
|
||||||
frame_id = f"F{frame_num:04d}"
|
frame_id = f"F{frame_num:04d}"
|
||||||
frame_path = self.frames_dir / f"{frame_id}.jpg"
|
frame_path = self.frames_dir / f"{frame_id}.jpg"
|
||||||
frame_path.write_bytes(jpeg_data)
|
frame_path.write_bytes(jpeg_data)
|
||||||
|
|||||||
Reference in New Issue
Block a user