auto-save 2026-05-12 17:23 (~2)
This commit is contained in:
@@ -125,6 +125,13 @@
|
|||||||
"message": "auto-save 2026-05-12 17:12 (~3)",
|
"message": "auto-save 2026-05-12 17:12 (~3)",
|
||||||
"hash": "e1bc89a",
|
"hash": "e1bc89a",
|
||||||
"files_changed": 3
|
"files_changed": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-12T17:17:49+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-12 17:17 (~1)",
|
||||||
|
"hash": "4fd43e8",
|
||||||
|
"files_changed": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
37
api/main.py
37
api/main.py
@@ -194,39 +194,28 @@ async def pipeline_analyze(job_id: str, frame_count: int = KEYFRAME_COUNT) -> No
|
|||||||
])
|
])
|
||||||
|
|
||||||
n = max(1, min(int(frame_count), 20))
|
n = max(1, min(int(frame_count), 20))
|
||||||
update(job, message=f"抽取 {n} 张关键帧…", progress=50)
|
update(job, message=f"抽取 {n} 张关键帧(均匀采样)…", progress=50)
|
||||||
frames_dir = d / "frames"
|
frames_dir = d / "frames"
|
||||||
if frames_dir.exists():
|
if frames_dir.exists():
|
||||||
shutil.rmtree(frames_dir)
|
shutil.rmtree(frames_dir)
|
||||||
frames_dir.mkdir(parents=True)
|
frames_dir.mkdir(parents=True)
|
||||||
|
|
||||||
try:
|
# 均匀采样:在 duration / (n+1) 的等距时间点各抽 1 帧
|
||||||
|
# 用 -ss 在 -i 前 = fast seek,每张 < 0.5s
|
||||||
|
duration = max(float(job.duration or 1.0), 0.1)
|
||||||
|
step = duration / (n + 1)
|
||||||
|
for i in range(n):
|
||||||
|
t = step * (i + 1)
|
||||||
|
out = frames_dir / f"sample_{i:03d}.jpg"
|
||||||
run([
|
run([
|
||||||
"ffmpeg", "-y", "-i", str(mp4),
|
"ffmpeg", "-y",
|
||||||
"-vf", "select='gt(scene,0.4)'",
|
"-ss", str(t),
|
||||||
"-fps_mode", "vfr",
|
"-i", str(mp4),
|
||||||
"-frames:v", str(n * 3),
|
"-frames:v", "1",
|
||||||
"-pix_fmt", "yuvj420p",
|
"-pix_fmt", "yuvj420p",
|
||||||
"-q:v", "3",
|
"-q:v", "3",
|
||||||
str(frames_dir / "scene_%03d.jpg"),
|
str(out),
|
||||||
])
|
])
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
scene_frames = sorted(frames_dir.glob("scene_*.jpg"))
|
|
||||||
|
|
||||||
if len(scene_frames) < n:
|
|
||||||
sample_count = n - len(scene_frames)
|
|
||||||
duration = job.duration or 1.0
|
|
||||||
step = duration / (sample_count + 1)
|
|
||||||
for i in range(sample_count):
|
|
||||||
t = step * (i + 1)
|
|
||||||
out = frames_dir / f"sample_{i:03d}.jpg"
|
|
||||||
run([
|
|
||||||
"ffmpeg", "-y", "-ss", str(t), "-i", str(mp4),
|
|
||||||
"-frames:v", "1",
|
|
||||||
"-pix_fmt", "yuvj420p",
|
|
||||||
"-q:v", "3", str(out),
|
|
||||||
])
|
|
||||||
|
|
||||||
all_frames = sorted(frames_dir.glob("*.jpg"))[:n]
|
all_frames = sorted(frames_dir.glob("*.jpg"))[:n]
|
||||||
renamed: list[KeyFrame] = []
|
renamed: list[KeyFrame] = []
|
||||||
|
|||||||
Reference in New Issue
Block a user