2026-05-18-20-18-20 对齐结果视频时长
This commit is contained in:
@@ -181,6 +181,21 @@ def _selected_frame(index: int, stride: int, selected_count: int, max_frames: in
|
||||
return index % max(1, stride) == 0 and selected_count < max_frames
|
||||
|
||||
|
||||
def _selected_frame_indices(frame_count: int, stride: int, max_frames: int) -> set[int]:
|
||||
if frame_count <= 0:
|
||||
return set()
|
||||
candidates = list(range(0, frame_count, max(1, stride)))
|
||||
if len(candidates) <= max_frames:
|
||||
return set(candidates)
|
||||
if max_frames <= 1:
|
||||
return {candidates[0]}
|
||||
last = len(candidates) - 1
|
||||
return {
|
||||
candidates[round(position * last / (max_frames - 1))]
|
||||
for position in range(max_frames)
|
||||
}
|
||||
|
||||
|
||||
def _process_video(
|
||||
job_path: Path,
|
||||
source: Path,
|
||||
@@ -197,27 +212,30 @@ def _process_video(
|
||||
previous = None
|
||||
frame_index = 0
|
||||
selected_count = 0
|
||||
written_count = 0
|
||||
writer = None
|
||||
result_fps = 8.0
|
||||
raw_video_path = job_path / f"{method}_overlay.raw.mp4"
|
||||
video_path = job_path / f"{method}_overlay.mp4"
|
||||
source_fps = float(capture.get(cv2.CAP_PROP_FPS) or 0.0)
|
||||
if source_fps <= 0:
|
||||
source_fps = 12.0
|
||||
result_fps = source_fps
|
||||
frame_count = int(capture.get(cv2.CAP_PROP_FRAME_COUNT) or 0)
|
||||
duration = round(frame_count / source_fps, 4) if frame_count else 0.0
|
||||
selected_indices = _selected_frame_indices(frame_count, frame_stride, max_frames)
|
||||
|
||||
try:
|
||||
while True:
|
||||
ok, frame = capture.read()
|
||||
if not ok:
|
||||
break
|
||||
if not _selected_frame(frame_index, frame_stride, selected_count, max_frames):
|
||||
previous = frame
|
||||
frame_index += 1
|
||||
continue
|
||||
should_process = (
|
||||
frame_index in selected_indices
|
||||
if selected_indices
|
||||
else _selected_frame(frame_index, frame_stride, selected_count, max_frames)
|
||||
)
|
||||
video_frame = frame
|
||||
|
||||
if method == "compare":
|
||||
if should_process and method == "compare":
|
||||
outputs = compare_frame(frame, previous, sensitivity)
|
||||
for output in outputs:
|
||||
frames.append(
|
||||
@@ -228,12 +246,14 @@ def _process_video(
|
||||
frame,
|
||||
output,
|
||||
frame_index / source_fps,
|
||||
selected_count / result_fps,
|
||||
selected_count,
|
||||
frame_index / source_fps,
|
||||
frame_index,
|
||||
)
|
||||
)
|
||||
video_output = next(item for item in outputs if item.method == "fusion")
|
||||
else:
|
||||
video_frame = video_output.overlay
|
||||
selected_count += 1
|
||||
elif should_process:
|
||||
video_output = segment_frame(frame, method, previous, sensitivity)
|
||||
frames.append(
|
||||
_save_frame_outputs(
|
||||
@@ -243,18 +263,20 @@ def _process_video(
|
||||
frame,
|
||||
video_output,
|
||||
frame_index / source_fps,
|
||||
selected_count / result_fps,
|
||||
selected_count,
|
||||
frame_index / source_fps,
|
||||
frame_index,
|
||||
)
|
||||
)
|
||||
video_frame = video_output.overlay
|
||||
selected_count += 1
|
||||
|
||||
if writer is None:
|
||||
height, width = video_output.overlay.shape[:2]
|
||||
height, width = frame.shape[:2]
|
||||
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
|
||||
writer = cv2.VideoWriter(str(raw_video_path), fourcc, result_fps, (width, height))
|
||||
writer.write(video_output.overlay)
|
||||
writer.write(video_frame)
|
||||
written_count += 1
|
||||
|
||||
selected_count += 1
|
||||
previous = frame
|
||||
frame_index += 1
|
||||
finally:
|
||||
@@ -266,14 +288,15 @@ def _process_video(
|
||||
raise HTTPException(status_code=400, detail="视频没有可处理帧")
|
||||
if raw_video_path.exists():
|
||||
_browser_video(raw_video_path, video_path)
|
||||
duration = round(written_count / source_fps, 4) if written_count else 0.0
|
||||
return {
|
||||
"kind": "video",
|
||||
"frames": frames,
|
||||
"video_url": _public(video_path) if video_path.exists() else None,
|
||||
"source_fps": round(source_fps, 4),
|
||||
"result_fps": result_fps,
|
||||
"result_fps": round(result_fps, 4),
|
||||
"duration": duration,
|
||||
"result_duration": round(len({frame["result_index"] for frame in frames}) / result_fps, 4) if frames else 0.0,
|
||||
"result_duration": duration,
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user