99 lines
3.8 KiB
Python
99 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Scene Detection CLI - Refactored
|
|
场景检测命令行工具 - 重构版
|
|
|
|
使用重构后的场景检测模块,代码更简洁、模块化更好。
|
|
"""
|
|
|
|
import typer
|
|
from pathlib import Path
|
|
from typing import Optional, List
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
|
|
from python_core.scene_detection import (
|
|
SceneDetector,
|
|
DetectorType,
|
|
OutputFormat
|
|
)
|
|
from python_core.utils.logger import logger
|
|
|
|
scene_detect = typer.Typer(help="场景检测工具 - 重构版")
|
|
console = Console()
|
|
|
|
@scene_detect.command("detect")
|
|
def detect(
|
|
video_path: Path = typer.Argument(..., help="视频文件路径"),
|
|
detector_type: DetectorType = typer.Option(DetectorType.CONTENT, "--detector", "-d", help="检测器类型"),
|
|
threshold: float = typer.Option(30.0, "--threshold", "-t", help="检测阈值"),
|
|
min_scene_length: float = typer.Option(1.0, "--min-length", "-m", help="最小场景长度(秒)"),
|
|
output: Optional[Path] = typer.Option(None, "--output", "-o", help="输出文件路径"),
|
|
output_format: OutputFormat = typer.Option(OutputFormat.JSON, "--format", "-f", help="输出格式"),
|
|
ai_analysis: bool = typer.Option(True, "--ai/--no-ai", help="启用/禁用AI分析"),
|
|
verbose: bool = typer.Option(False, "--verbose", "-v", help="详细输出")
|
|
):
|
|
"""使用LangGraph工作流进行场景检测"""
|
|
console.print(f"🔄 使用工作流检测视频: [bold blue]{video_path}[/bold blue]")
|
|
|
|
try:
|
|
# 创建检测器
|
|
detector = SceneDetector()
|
|
|
|
# 执行工作流检测
|
|
result = detector.detect_with_workflow(
|
|
video_path, detector_type, threshold, min_scene_length,
|
|
output, output_format, ai_analysis
|
|
)
|
|
|
|
# 显示结果
|
|
if result.get("workflow_state") == "completed":
|
|
detection_result = result.get("detection_result")
|
|
if detection_result and detection_result.success:
|
|
console.print(f"✅ 工作流完成: [bold green]{detection_result.total_scenes}[/bold green] 个场景")
|
|
console.print(f"📊 检测时间: {detection_result.detection_time:.2f}秒")
|
|
|
|
# 显示AI分析结果
|
|
ai_analysis_result = result.get("ai_analysis")
|
|
if ai_analysis_result and ai_analysis_result != "AI分析已禁用":
|
|
console.print("\n🧠 AI分析结果:")
|
|
console.print(ai_analysis_result[:500] + "..." if len(ai_analysis_result) > 500 else ai_analysis_result)
|
|
|
|
# 显示场景列表
|
|
if verbose:
|
|
_display_scenes_table(detection_result.scenes)
|
|
else:
|
|
console.print(f"❌ 检测失败: [bold red]{detection_result.error if detection_result else '未知错误'}[/bold red]")
|
|
raise typer.Exit(1)
|
|
else:
|
|
errors = result.get("errors", [])
|
|
error_msg = "; ".join(errors) if errors else "工作流执行失败"
|
|
console.print(f"❌ 工作流失败: [bold red]{error_msg}[/bold red]")
|
|
raise typer.Exit(1)
|
|
|
|
except Exception as e:
|
|
console.print(f"❌ 执行失败: [bold red]{str(e)}[/bold red]")
|
|
raise typer.Exit(1)
|
|
|
|
|
|
def _display_scenes_table(scenes):
|
|
"""显示场景表格"""
|
|
table = Table(title="检测到的场景")
|
|
table.add_column("场景", style="cyan")
|
|
table.add_column("开始时间", style="green")
|
|
table.add_column("结束时间", style="green")
|
|
table.add_column("时长", style="yellow")
|
|
|
|
for scene in scenes:
|
|
table.add_row(
|
|
str(scene.index + 1),
|
|
f"{scene.start_time:.2f}s",
|
|
f"{scene.end_time:.2f}s",
|
|
f"{scene.duration:.2f}s"
|
|
)
|
|
|
|
console.print(table)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
scene_detect() |