json rpc commander 封装
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user