json rpc commander 封装

This commit is contained in:
root
2025-07-11 21:27:17 +08:00
parent 2a16067367
commit 7b50c6e28e
37 changed files with 3518 additions and 2596 deletions

View File

@@ -3,147 +3,99 @@
视频拆分服务命令行接口
"""
import sys
import json
import logging
from typing import Optional, Dict, Any
from typing import Dict, Any
from dataclasses import asdict
from .types import DetectionConfig, DetectorType, ValidationError, DependencyError
from .types import DetectionConfig, DetectorType
from .service import VideoSplitterService
from python_core.utils.commander import JSONRPCCommander
# 导入必需依赖
from python_core.utils.command_utils import (
CommandLineParser, JSONRPCHandler, create_command_service_base
)
logger = logging.getLogger(__name__)
class VideoSplitterCommander(JSONRPCCommander):
"""视频拆分服务命令行接口"""
class CommandLineInterface:
"""命令行接口"""
def __init__(self):
self.service = None
self.rpc_handler = None
def setup_service(self, output_base: Optional[str] = None) -> None:
"""设置服务"""
try:
self.service = VideoSplitterService(output_base_dir=output_base)
except DependencyError as e:
logger.error(f"Service setup failed: {e}")
sys.exit(1)
def setup_rpc_handler(self) -> None:
"""设置RPC处理器"""
try:
service_config = create_command_service_base(
service_name="video_splitter_enhanced",
optional_dependencies={
"jsonrpc": {
"module_name": "python_core.utils.jsonrpc",
"import_items": ["create_response_handler"],
}
}
)
if "jsonrpc" in service_config.get("dependencies", {}):
create_response_handler = service_config["dependencies"]["jsonrpc"]["create_response_handler"]
self.rpc_handler = create_response_handler()
except Exception as e:
logger.warning(f"RPC setup failed: {e}")
# 不设置RPC处理器使用普通JSON输出
def parse_arguments(self) -> tuple:
"""解析命令行参数"""
if len(sys.argv) < 3:
print("Usage: python -m python_core.services.video_splitter <command> <video_path> [options...]")
sys.exit(1)
command = sys.argv[1]
video_path = sys.argv[2]
# 解析配置
if UTILS_AVAILABLE:
arg_definitions = {
"threshold": {"type": float, "default": 30.0},
"detector": {"type": str, "default": "content", "choices": ["content", "threshold"]},
"min-scene-length": {"type": float, "default": 1.0},
"output-base": {"type": str, "default": None}
super().__init__("video_splitter")
def _register_commands(self) -> None:
"""注册命令"""
# 注册analyze命令
self.register_command(
name="analyze",
description="分析视频场景",
required_args=["video_path"],
optional_args={
"threshold": {"type": float, "default": 30.0, "description": "检测阈值"},
"detector": {"type": str, "default": "content", "choices": ["content", "threshold"], "description": "检测器类型"},
"min-scene-length": {"type": float, "default": 1.0, "description": "最小场景长度(秒)"},
"output-base": {"type": str, "default": None, "description": "输出基础目录"}
}
try:
parsed_args = CommandLineParser.parse_command_args(sys.argv[3:], arg_definitions)
config = DetectionConfig(
threshold=parsed_args["threshold"],
detector_type=DetectorType(parsed_args["detector"]),
min_scene_length=parsed_args["min_scene_length"]
)
return command, video_path, config, parsed_args.get("output_base")
except (ValueError, ValidationError) as e:
logger.error(f"Argument error: {e}")
sys.exit(1)
else:
# 简化版参数解析
config = DetectionConfig()
return command, video_path, config, None
def handle_response(self, result: Dict[str, Any], error_code: str) -> None:
"""处理响应"""
if UTILS_AVAILABLE and self.rpc_handler:
JSONRPCHandler.handle_command_response(self.rpc_handler, result, error_code)
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
def run(self) -> None:
"""运行命令行接口"""
# 解析参数
command, video_path, config, output_base = self.parse_arguments()
)
# 注册detect_scenes命令
self.register_command(
name="detect_scenes",
description="检测视频场景(仅返回场景信息)",
required_args=["video_path"],
optional_args={
"threshold": {"type": float, "default": 30.0, "description": "检测阈值"},
"detector": {"type": str, "default": "content", "choices": ["content", "threshold"], "description": "检测器类型"},
"min-scene-length": {"type": float, "default": 1.0, "description": "最小场景长度(秒)"},
"output-base": {"type": str, "default": None, "description": "输出基础目录"}
}
)
def _setup_service(self, output_base: str = None) -> None:
"""设置服务"""
if self.service is None:
self.service = VideoSplitterService(output_base_dir=output_base)
def execute_command(self, command: str, args: Dict[str, Any]) -> Any:
"""执行命令"""
# 设置服务
self.setup_service(output_base)
self.setup_rpc_handler()
# 执行命令
try:
if command == "analyze":
result = self.service.analyze_video(video_path, config)
self.handle_response(result.to_dict(), "ANALYSIS_FAILED")
elif command == "detect_scenes":
result = self.service.analyze_video(video_path, config)
# 只返回场景信息
scenes_result = {
"success": result.success,
"video_path": result.video_path,
"total_scenes": result.total_scenes,
"scenes": [asdict(scene) for scene in result.scenes],
"detection_settings": asdict(config),
"detection_time": result.analysis_time
}
if not result.success:
scenes_result["error"] = result.error
self.handle_response(scenes_result, "DETECTION_FAILED")
else:
error_msg = f"Unknown command: {command}. Available: analyze, detect_scenes"
if self.rpc_handler:
self.rpc_handler.error("INVALID_COMMAND", error_msg)
else:
logger.error(error_msg)
sys.exit(1)
except Exception as e:
logger.error(f"Command execution failed: {e}")
if self.rpc_handler:
self.rpc_handler.error("INTERNAL_ERROR", str(e))
else:
sys.exit(1)
self._setup_service(args.get("output_base"))
# 创建配置
config = DetectionConfig(
threshold=args.get("threshold", 30.0),
detector_type=DetectorType(args.get("detector", "content")),
min_scene_length=args.get("min_scene_length", 1.0)
)
video_path = args["video_path"]
if command == "analyze":
# 完整的视频分析
result = self.service.analyze_video(video_path, config)
return result.to_dict()
elif command == "detect_scenes":
# 仅检测场景
result = self.service.analyze_video(video_path, config)
# 只返回场景信息
scenes_result = {
"success": result.success,
"video_path": result.video_path,
"total_scenes": result.total_scenes,
"scenes": [asdict(scene) for scene in result.scenes],
"detection_settings": asdict(config),
"detection_time": result.analysis_time
}
if not result.success:
scenes_result["error"] = result.error
return scenes_result
else:
raise ValueError(f"Unknown command: {command}")
def main():
"""主函数"""
cli = CommandLineInterface()
cli.run()
commander = VideoSplitterCommander()
commander.run()
if __name__ == "__main__":
main()