mxivideo/docs/multi-command-integration.md

16 KiB
Raw Blame History

多命令集成设计方案

🎯 设计目标

将所有服务的命令集成到一个统一的CLI中提供一致的用户体验和管理界面。

🏗️ 架构设计

方案1: 主CLI + 子命令组

mixvideo
├── media          # 媒体管理命令组
│   ├── upload
│   ├── batch-upload
│   ├── list
│   └── status
├── scene          # 场景检测命令组
│   ├── detect
│   ├── batch-detect
│   ├── compare
│   └── analyze
├── template       # 模板管理命令组
│   ├── import
│   ├── export
│   ├── list
│   └── validate
└── system         # 系统管理命令组
    ├── status
    ├── config
    ├── storage
    └── logs

方案2: 扁平化命令

mixvideo
├── media-upload
├── media-batch-upload
├── scene-detect
├── scene-batch-detect
├── template-import
├── template-export
├── system-status
└── system-config

方案3: 混合方案(推荐)

mixvideo
├── upload         # 常用命令提升到顶层
├── batch-upload
├── detect
├── batch-detect
├── media          # 完整的媒体管理命令组
├── scene          # 完整的场景检测命令组
├── template       # 模板管理命令组
└── system         # 系统管理命令组

📁 文件结构设计

python_core/
├── cli/                    # 统一CLI模块
│   ├── __init__.py
│   ├── main.py            # 主CLI入口
│   ├── commands/          # 命令组织
│   │   ├── __init__.py
│   │   ├── media.py       # 媒体管理命令组
│   │   ├── scene.py       # 场景检测命令组
│   │   ├── template.py    # 模板管理命令组
│   │   └── system.py      # 系统管理命令组
│   └── utils/             # CLI工具
│       ├── __init__.py
│       ├── common.py      # 通用CLI工具
│       └── decorators.py  # CLI装饰器
├── services/              # 现有服务保持不变
└── __main__.py            # 项目入口

🔧 实现方案

1. 主CLI框架

# python_core/cli/main.py
import typer
from rich.console import Console
from typing import Optional

from .commands import media, scene, template, system
from python_core.utils.progress import ProgressJSONRPCCommander

console = Console()

class MixVideoCommander(ProgressJSONRPCCommander):
    """MixVideo 统一命令行接口"""
    
    def __init__(self):
        super().__init__("mixvideo")
        self.app = typer.Typer(
            name="mixvideo",
            help="""
            🎬 MixVideo - 智能视频处理平台
            
            功能完整的视频处理和管理工具套件:
            • 📤 媒体管理 - 上传、处理、组织视频文件
            • 🎯 场景检测 - 智能识别视频场景变化
            • 📋 模板管理 - 视频模板导入导出
            • ⚙️ 系统管理 - 配置、状态、存储管理
            
            快速开始:
                mixvideo upload video.mp4          # 上传视频
                mixvideo detect video.mp4          # 检测场景
                mixvideo system status             # 查看状态
            """,
            rich_markup_mode="rich",
            no_args_is_help=True
        )
        self._setup_commands()
    
    def _register_commands(self):
        """注册命令(继承要求)"""
        pass
    
    def _is_progressive_command(self, command: str) -> bool:
        """判断是否需要进度报告"""
        return command.startswith(("batch-", "import-", "export-", "analyze-"))
    
    def _execute_with_progress(self, command: str, args: dict):
        """执行带进度的命令"""
        pass
    
    def _execute_simple_command(self, command: str, args: dict):
        """执行简单命令"""
        pass
    
    def _setup_commands(self):
        """设置命令结构"""
        # 添加子命令组
        self.app.add_typer(media.app, name="media", help="📤 媒体管理")
        self.app.add_typer(scene.app, name="scene", help="🎯 场景检测")
        self.app.add_typer(template.app, name="template", help="📋 模板管理")
        self.app.add_typer(system.app, name="system", help="⚙️ 系统管理")
        
        # 添加常用命令到顶层(快捷方式)
        self._add_shortcuts()
    
    def _add_shortcuts(self):
        """添加常用命令的快捷方式"""
        
        @self.app.command()
        def upload(
            video_path: Path = typer.Argument(..., help="📹 视频文件路径"),
            tags: Optional[str] = typer.Option(None, "--tags", "-t", help="🏷️ 标签")
        ):
            """📤 快速上传视频media upload 的快捷方式)"""
            # 调用媒体管理的上传命令
            return media.upload_video(video_path, tags)
        
        @self.app.command()
        def detect(
            video_path: Path = typer.Argument(..., help="📹 视频文件路径"),
            threshold: float = typer.Option(30.0, help="🎚️ 检测阈值")
        ):
            """🎯 快速场景检测scene detect 的快捷方式)"""
            # 调用场景检测的检测命令
            return scene.detect_scenes(video_path, threshold)
        
        @self.app.command()
        def status():
            """📊 快速状态查看system status 的快捷方式)"""
            # 调用系统状态命令
            return system.show_status()
    
    def run(self):
        """运行CLI"""
        self.app()

def main():
    """主入口函数"""
    commander = MixVideoCommander()
    commander.run()

2. 媒体管理命令组

# python_core/cli/commands/media.py
import typer
from pathlib import Path
from typing import Optional
from rich.console import Console

from python_core.services.media_manager import MediaManagerService
from ..utils.common import create_progress_task, parse_tags

console = Console()
app = typer.Typer(help="📤 媒体管理命令")

# 全局服务实例
media_service = MediaManagerService()

@app.command()
def upload(
    video_path: Path = typer.Argument(..., help="📹 视频文件路径", exists=True),
    tags: Optional[str] = typer.Option(None, "--tags", "-t", help="🏷️ 标签列表"),
    filename: Optional[str] = typer.Option(None, "--filename", "-f", help="📝 自定义文件名")
):
    """📤 上传单个视频文件"""
    return upload_video(video_path, tags, filename)

@app.command()
def batch_upload(
    directory: Path = typer.Argument(..., help="📁 视频目录", exists=True),
    tags: Optional[str] = typer.Option(None, "--tags", "-t", help="🏷️ 标签列表"),
    recursive: bool = typer.Option(False, "--recursive", "-r", help="🔄 递归扫描")
):
    """📦 批量上传视频文件"""
    tag_list = parse_tags(tags)
    
    with create_progress_task("批量上传") as task:
        result = media_service.batch_upload(directory, tag_list, recursive)
        task.finish(f"上传完成: {result['successful']}/{result['total']} 成功")
    
    return result

@app.command()
def list_videos(
    limit: int = typer.Option(10, "--limit", "-l", help="📊 显示数量"),
    tags: Optional[str] = typer.Option(None, "--tags", "-t", help="🏷️ 标签过滤")
):
    """📋 列出视频文件"""
    # 实现列表逻辑
    pass

@app.command()
def delete(
    video_id: str = typer.Argument(..., help="🗑️ 视频ID"),
    confirm: bool = typer.Option(False, "--yes", "-y", help="✅ 确认删除")
):
    """🗑️ 删除视频文件"""
    if not confirm:
        confirm = typer.confirm("确定要删除这个视频吗?")
    
    if confirm:
        # 实现删除逻辑
        console.print("✅ 视频已删除")
    else:
        console.print("❌ 取消删除")

# 共享函数
def upload_video(video_path: Path, tags: str = None, filename: str = None):
    """上传视频的共享实现"""
    tag_list = parse_tags(tags)
    
    console.print(f"🚀 开始上传: [bold blue]{video_path}[/bold blue]")
    
    result = media_service.upload_video(video_path, tag_list, filename)
    
    console.print("✅ [bold green]上传完成[/bold green]")
    return result

3. 场景检测命令组

# python_core/cli/commands/scene.py
import typer
from pathlib import Path
from typing import Optional
from rich.console import Console

from python_core.services.scene_detection import SceneDetectionService
from ..utils.common import create_progress_task

console = Console()
app = typer.Typer(help="🎯 场景检测命令")

# 全局服务实例
scene_service = SceneDetectionService()

@app.command()
def detect(
    video_path: Path = typer.Argument(..., help="📹 视频文件路径", exists=True),
    threshold: float = typer.Option(30.0, help="🎚️ 检测阈值"),
    output: Optional[Path] = typer.Option(None, "--output", "-o", help="📄 输出文件")
):
    """🎯 检测单个视频的场景"""
    return detect_scenes(video_path, threshold, output)

@app.command()
def batch_detect(
    directory: Path = typer.Argument(..., help="📁 视频目录", exists=True),
    threshold: float = typer.Option(30.0, help="🎚️ 检测阈值"),
    output: Optional[Path] = typer.Option(None, "--output", "-o", help="📄 输出文件")
):
    """📦 批量检测场景"""
    with create_progress_task("批量检测") as task:
        result = scene_service.batch_detect(directory, threshold)
        task.finish(f"检测完成: {result['processed']} 个文件")
    
    return result

@app.command()
def compare(
    video_path: Path = typer.Argument(..., help="📹 视频文件路径", exists=True),
    thresholds: str = typer.Option("20,30,40", help="🎚️ 阈值列表")
):
    """🔬 比较不同检测器效果"""
    with create_progress_task("检测器比较") as task:
        result = scene_service.compare_detectors(video_path, thresholds)
        task.finish("比较完成")
    
    return result

# 共享函数
def detect_scenes(video_path: Path, threshold: float = 30.0, output: Path = None):
    """场景检测的共享实现"""
    console.print(f"🎯 开始检测: [bold blue]{video_path}[/bold blue]")
    
    result = scene_service.detect_single(video_path, threshold)
    
    if output:
        scene_service.save_result(result, output)
        console.print(f"📄 结果已保存: {output}")
    
    console.print("✅ [bold green]检测完成[/bold green]")
    return result

4. 系统管理命令组

# python_core/cli/commands/system.py
import typer
from rich.console import Console
from rich.table import Table
from rich.panel import Panel

from python_core.storage import get_storage
from python_core.config import settings

console = Console()
app = typer.Typer(help="⚙️ 系统管理命令")

@app.command()
def status():
    """📊 显示系统状态"""
    return show_status()

@app.command()
def config(
    show: bool = typer.Option(False, "--show", help="📋 显示配置"),
    set_key: Optional[str] = typer.Option(None, "--set", help="⚙️ 设置配置项"),
    value: Optional[str] = typer.Option(None, "--value", help="💾 配置值")
):
    """⚙️ 配置管理"""
    if show:
        show_config()
    elif set_key and value:
        set_config(set_key, value)
    else:
        console.print("❌ 请指定 --show 或 --set 和 --value")

@app.command()
def storage(
    action: str = typer.Argument(..., help="📦 操作类型 (info/clean/migrate)"),
    target: Optional[str] = typer.Option(None, help="🎯 目标存储类型")
):
    """📦 存储管理"""
    if action == "info":
        show_storage_info()
    elif action == "clean":
        clean_storage()
    elif action == "migrate":
        migrate_storage(target)
    else:
        console.print("❌ 未知操作类型")

@app.command()
def logs(
    lines: int = typer.Option(50, "--lines", "-n", help="📄 显示行数"),
    follow: bool = typer.Option(False, "--follow", "-f", help="🔄 实时跟踪")
):
    """📄 查看日志"""
    # 实现日志查看逻辑
    pass

# 共享函数
def show_status():
    """显示系统状态的共享实现"""
    console.print("📊 MixVideo 系统状态")
    
    # 创建状态表格
    table = Table(title="系统组件状态")
    table.add_column("组件", style="cyan")
    table.add_column("状态", style="green")
    table.add_column("详情", style="yellow")
    
    # 检查各组件状态
    storage = get_storage()
    collections = storage.get_collections()
    
    table.add_row("存储系统", "✅ 正常", f"{len(collections)} 个集合")
    table.add_row("媒体管理", "✅ 就绪", "服务正常")
    table.add_row("场景检测", "✅ 就绪", "服务正常")
    table.add_row("模板管理", "✅ 就绪", "服务正常")
    
    console.print(table)
    
    # 系统信息面板
    info_panel = Panel(
        "[bold blue]MixVideo 运行正常[/bold blue]\n"
        "所有核心组件状态良好,系统准备就绪。",
        title="📊 系统摘要",
        border_style="green"
    )
    console.print(info_panel)

def show_config():
    """显示配置信息"""
    # 实现配置显示逻辑
    pass

def set_config(key: str, value: str):
    """设置配置项"""
    # 实现配置设置逻辑
    pass

5. 通用工具

# python_core/cli/utils/common.py
from contextlib import contextmanager
from typing import List, Optional
from rich.console import Console

console = Console()

def parse_tags(tags_str: Optional[str]) -> List[str]:
    """解析标签字符串"""
    if not tags_str:
        return []
    return [tag.strip() for tag in tags_str.split(",") if tag.strip()]

@contextmanager
def create_progress_task(name: str):
    """创建进度任务的上下文管理器"""
    class MockTask:
        def __init__(self, name):
            self.name = name
            console.print(f"🚀 开始{name}...")
        
        def update(self, message: str):
            console.print(f"📊 {message}")
        
        def finish(self, message: str):
            console.print(f"✅ {message}")
    
    yield MockTask(name)

def confirm_action(message: str, default: bool = False) -> bool:
    """确认操作"""
    import typer
    return typer.confirm(message, default=default)

def show_error(message: str):
    """显示错误信息"""
    console.print(f"❌ [red]{message}[/red]")

def show_success(message: str):
    """显示成功信息"""
    console.print(f"✅ [green]{message}[/green]")

def show_warning(message: str):
    """显示警告信息"""
    console.print(f"⚠️ [yellow]{message}[/yellow]")

6. 项目入口

# python_core/__main__.py
"""
MixVideo 项目主入口
支持: python -m python_core
"""

from .cli.main import main

if __name__ == "__main__":
    main()

🎯 使用示例

命令组方式

# 媒体管理
mixvideo media upload video.mp4 --tags "demo,test"
mixvideo media batch-upload /videos --recursive
mixvideo media list --limit 20

# 场景检测
mixvideo scene detect video.mp4 --threshold 25
mixvideo scene batch-detect /videos --output results.json
mixvideo scene compare video.mp4 --thresholds "20,30,40"

# 模板管理
mixvideo template import /templates --batch
mixvideo template export template_id --output template.json

# 系统管理
mixvideo system status
mixvideo system config --show
mixvideo system storage info

快捷命令方式

# 常用命令的快捷方式
mixvideo upload video.mp4 --tags "demo"
mixvideo detect video.mp4 --threshold 30
mixvideo status

帮助系统

# 查看主帮助
mixvideo --help

# 查看命令组帮助
mixvideo media --help
mixvideo scene --help

# 查看具体命令帮助
mixvideo media upload --help
mixvideo scene detect --help

🎉 方案优势

1. 统一体验

  • 🎯 一个入口点,所有功能
  • 📋 一致的命令风格和参数
  • 🎨 统一的输出格式和样式

2. 灵活使用

  • 快捷命令满足日常需求
  • 🔧 完整命令组满足专业需求
  • 📚 清晰的帮助系统

3. 易于扩展

  • 🔌 新服务易于集成
  • 📦 模块化的命令组织
  • 🔄 向后兼容的设计

4. 开发友好

  • 🧩 清晰的代码组织
  • 🔧 共享的工具函数
  • 📝 统一的开发规范

这个设计方案提供了完整的多命令集成解决方案,既保持了各服务的独立性,又提供了统一的用户体验!