验收1
This commit is contained in:
@@ -6,13 +6,19 @@ import sys
|
||||
import tempfile
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from app.logging_config import format_json_pretty
|
||||
from app.services.video_slice import get_video_duration, slice_video
|
||||
from app.settings import Settings
|
||||
from app.state import HealthSnapshot
|
||||
from app.subprocess_run import run_subprocess_with_log
|
||||
from loguru import logger
|
||||
|
||||
# 视频切片配置
|
||||
DEFAULT_SLICE_DURATION = 10.0 # 每10秒切一个片段
|
||||
DEFAULT_MIN_DURATION_FOR_SLICE = 15.0 # 视频超过15秒才切片
|
||||
|
||||
BEHAVIOR_EN_TO_ZH = {
|
||||
"feeding": "吃饵",
|
||||
"normal": "正常游行",
|
||||
@@ -100,8 +106,95 @@ def run_action_subprocess(mp4_path: Path, settings: Settings) -> str:
|
||||
Path(out_json).unlink(missing_ok=True)
|
||||
|
||||
|
||||
def run_full_action(mp4_path: Path, settings: Settings) -> HealthSnapshot:
|
||||
def run_full_action(mp4_path: Path, settings: Settings) -> tuple[HealthSnapshot, list[HealthSnapshot]]:
|
||||
"""运行 FishAction 健康检测。如果视频较长,会自动切片后分别检测。
|
||||
|
||||
每个切片被视为独立的视频,返回所有切片的结果列表。
|
||||
|
||||
Args:
|
||||
mp4_path: 输入视频路径
|
||||
settings: 应用配置
|
||||
|
||||
Returns:
|
||||
tuple[HealthSnapshot, list[HealthSnapshot]]: (第一个切片/完整视频的快照, 所有切片快照列表)
|
||||
- 如果视频被切片:返回 (第一个切片, 所有切片列表)
|
||||
- 如果视频未被切片:返回 (完整视频快照, [完整视频快照])
|
||||
"""
|
||||
logger.info("[FishAction] start mp4={}", mp4_path.resolve())
|
||||
|
||||
# 检查视频时长
|
||||
duration = get_video_duration(mp4_path)
|
||||
should_slice = duration > DEFAULT_MIN_DURATION_FOR_SLICE
|
||||
|
||||
if should_slice:
|
||||
# 视频较长,需要切片处理
|
||||
logger.info(
|
||||
"[FishAction] video duration {}s > {}s, slicing into {}s segments",
|
||||
duration,
|
||||
DEFAULT_MIN_DURATION_FOR_SLICE,
|
||||
DEFAULT_SLICE_DURATION,
|
||||
)
|
||||
|
||||
slice_files, slice_dir = slice_video(mp4_path, DEFAULT_SLICE_DURATION)
|
||||
|
||||
if len(slice_files) > 1:
|
||||
logger.info(
|
||||
"[FishAction] processing {} slices for {}",
|
||||
len(slice_files),
|
||||
mp4_path.name,
|
||||
)
|
||||
|
||||
# 处理每个切片
|
||||
all_snaps: list[HealthSnapshot] = []
|
||||
for i, slice_file in enumerate(slice_files):
|
||||
start_time = i * DEFAULT_SLICE_DURATION
|
||||
end_time = min(start_time + DEFAULT_SLICE_DURATION, duration)
|
||||
|
||||
try:
|
||||
pred_en = run_action_subprocess(slice_file, settings)
|
||||
zh = BEHAVIOR_EN_TO_ZH[pred_en]
|
||||
health = behavior_to_health(pred_en)
|
||||
|
||||
snap = HealthSnapshot(
|
||||
behavior_result=zh,
|
||||
health_result=health,
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
raw_class_en=pred_en,
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"[FishAction] slice {} ({}s-{}s): pred={} behavior={} health={}",
|
||||
i, start_time, end_time, pred_en, zh, health,
|
||||
)
|
||||
|
||||
all_snaps.append(snap)
|
||||
except Exception as e:
|
||||
logger.error("[FishAction] failed to process slice {}: {}", i, e)
|
||||
# 创建一个表示失败的快照
|
||||
error_snap = HealthSnapshot(
|
||||
behavior_result="处理失败",
|
||||
health_result="未知",
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
raw_class_en="error",
|
||||
error=str(e),
|
||||
)
|
||||
all_snaps.append(error_snap)
|
||||
|
||||
logger.info(
|
||||
"[FishAction] done mp4={} total_slices={}",
|
||||
mp4_path.name,
|
||||
len(slice_files),
|
||||
)
|
||||
|
||||
# 返回第一个切片的结果和所有切片列表
|
||||
first_snap = all_snaps[0] if all_snaps else HealthSnapshot(
|
||||
behavior_result="",
|
||||
health_result="",
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
)
|
||||
return first_snap, all_snaps
|
||||
|
||||
# 视频较短,直接处理(原有逻辑)
|
||||
pred_en = run_action_subprocess(mp4_path, settings)
|
||||
zh = BEHAVIOR_EN_TO_ZH[pred_en]
|
||||
health = behavior_to_health(pred_en)
|
||||
@@ -112,9 +205,10 @@ def run_full_action(mp4_path: Path, settings: Settings) -> HealthSnapshot:
|
||||
zh,
|
||||
health,
|
||||
)
|
||||
return HealthSnapshot(
|
||||
snap = HealthSnapshot(
|
||||
behavior_result=zh,
|
||||
health_result=health,
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
raw_class_en=pred_en,
|
||||
)
|
||||
return snap, [snap]
|
||||
|
||||
Reference in New Issue
Block a user