mxivideo/docs/multi-command-integration.md

560 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 多命令集成设计方案
## 🎯 设计目标
将所有服务的命令集成到一个统一的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
# 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
# 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
# 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
# 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
# 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
# python_core/__main__.py
"""
MixVideo 项目主入口
支持: python -m python_core
"""
from .cli.main import main
if __name__ == "__main__":
main()
```
## 🎯 使用示例
### **命令组方式**
```bash
# 媒体管理
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
```
### **快捷命令方式**
```bash
# 常用命令的快捷方式
mixvideo upload video.mp4 --tags "demo"
mixvideo detect video.mp4 --threshold 30
mixvideo status
```
### **帮助系统**
```bash
# 查看主帮助
mixvideo --help
# 查看命令组帮助
mixvideo media --help
mixvideo scene --help
# 查看具体命令帮助
mixvideo media upload --help
mixvideo scene detect --help
```
## 🎉 方案优势
### **1. 统一体验**
- 🎯 一个入口点,所有功能
- 📋 一致的命令风格和参数
- 🎨 统一的输出格式和样式
### **2. 灵活使用**
- ⚡ 快捷命令满足日常需求
- 🔧 完整命令组满足专业需求
- 📚 清晰的帮助系统
### **3. 易于扩展**
- 🔌 新服务易于集成
- 📦 模块化的命令组织
- 🔄 向后兼容的设计
### **4. 开发友好**
- 🧩 清晰的代码组织
- 🔧 共享的工具函数
- 📝 统一的开发规范
这个设计方案提供了完整的多命令集成解决方案,既保持了各服务的独立性,又提供了统一的用户体验!