# PySceneDetect 视频拆分服务 JSON-RPC 接口 ## 🎯 概述 PySceneDetect视频拆分服务现在支持JSON-RPC协议,提供标准化的API接口,便于与其他系统集成。 ## 📡 JSON-RPC 协议 ### 输出格式 所有命令的输出都遵循JSON-RPC 2.0规范: #### 成功响应 ```json { "jsonrpc": "2.0", "id": null, "result": { // 具体的结果数据 } } ``` #### 错误响应 ```json { "jsonrpc": "2.0", "id": null, "error": { "code": "ERROR_CODE", "message": "错误描述" } } ``` ## 🔧 可用命令 ### 1. analyze - 视频分析 #### 命令格式 ```bash python python_core/services/video_splitter.py analyze [--threshold ] ``` #### 参数 - `video_path`: 视频文件路径 - `--threshold`: 检测阈值 (默认: 30.0) #### 成功响应示例 ```json { "jsonrpc": "2.0", "id": null, "result": { "success": true, "video_path": "/path/to/video.mp4", "total_scenes": 3, "total_duration": 10.04, "average_scene_duration": 3.35, "scenes": [ { "scene_number": 1, "start_time": 0.0, "end_time": 4.04, "duration": 4.04, "start_frame": 0, "end_frame": 97 }, { "scene_number": 2, "start_time": 4.04, "end_time": 8.04, "duration": 4.0, "start_frame": 97, "end_frame": 193 }, { "scene_number": 3, "start_time": 8.04, "end_time": 10.04, "duration": 2.0, "start_frame": 193, "end_frame": 241 } ] } } ``` #### 错误响应示例 ```json { "jsonrpc": "2.0", "id": null, "error": { "code": "ANALYSIS_FAILED", "message": "Video file not found: /path/to/video.mp4" } } ``` ### 2. detect_scenes - 场景检测 #### 命令格式 ```bash python python_core/services/video_splitter.py detect_scenes [--threshold ] [--detector ] ``` #### 参数 - `video_path`: 视频文件路径 - `--threshold`: 检测阈值 (默认: 30.0) - `--detector`: 检测器类型 ("content" 或 "threshold", 默认: "content") #### 成功响应示例 ```json { "jsonrpc": "2.0", "id": null, "result": { "success": true, "video_path": "/path/to/video.mp4", "total_scenes": 3, "scenes": [ { "scene_number": 1, "start_time": 0.0, "end_time": 4.04, "duration": 4.04, "start_frame": 0, "end_frame": 97 } ], "detection_settings": { "threshold": 30.0, "detector_type": "content" } } } ``` ### 3. split - 视频拆分 #### 命令格式 ```bash python python_core/services/video_splitter.py split [options...] ``` #### 参数 - `video_path`: 视频文件路径 - `--threshold`: 检测阈值 (默认: 30.0) - `--detector`: 检测器类型 (默认: "content") - `--output-dir`: 输出目录 - `--output-base`: 输出基础目录 #### 成功响应示例 ```json { "jsonrpc": "2.0", "id": null, "result": { "success": true, "message": "Successfully split video into 3 scenes", "input_video": "/path/to/video.mp4", "output_directory": "/tmp/video_splits/video_20250711_201530", "scenes": [ { "scene_number": 1, "start_time": 0.0, "end_time": 4.04, "duration": 4.04, "start_frame": 0, "end_frame": 97 } ], "output_files": [ "/tmp/video_splits/video_20250711_201530/video-Scene-001.mp4", "/tmp/video_splits/video_20250711_201530/video-Scene-002.mp4", "/tmp/video_splits/video_20250711_201530/video-Scene-003.mp4" ], "total_scenes": 3, "total_duration": 10.04, "processing_time": 3.02 } } ``` #### 错误响应示例 ```json { "jsonrpc": "2.0", "id": null, "error": { "code": "SPLIT_FAILED", "message": "FFmpeg failed with return code: 1" } } ``` ## 🔍 错误代码 | 错误代码 | 描述 | 可能原因 | |---------|------|----------| | `ANALYSIS_FAILED` | 视频分析失败 | 文件不存在、格式不支持 | | `SPLIT_FAILED` | 视频拆分失败 | FFmpeg错误、磁盘空间不足 | | `INVALID_COMMAND` | 无效命令 | 命令名称错误 | | `INTERNAL_ERROR` | 内部错误 | 程序异常、依赖缺失 | ## 💻 编程接口使用 ### Python 示例 ```python import subprocess import json def call_video_splitter(command, video_path, **kwargs): """调用视频拆分服务""" cmd = [ "python", "python_core/services/video_splitter.py", command, video_path ] # 添加参数 for key, value in kwargs.items(): cmd.extend([f"--{key.replace('_', '-')}", str(value)]) result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode == 0: # 解析JSON-RPC响应 if result.stdout.startswith("JSONRPC:"): json_str = result.stdout[8:] return json.loads(json_str) else: return json.loads(result.stdout) else: raise Exception(f"Command failed: {result.stderr}") # 使用示例 try: # 分析视频 response = call_video_splitter("analyze", "video.mp4", threshold=30.0) if "result" in response: result = response["result"] print(f"检测到 {result['total_scenes']} 个场景") # 拆分视频 response = call_video_splitter("split", "video.mp4", threshold=30.0) if "result" in response: result = response["result"] if result["success"]: print(f"拆分成功: {len(result['output_files'])} 个文件") else: print(f"拆分失败: {result['message']}") except Exception as e: print(f"调用失败: {e}") ``` ### Node.js 示例 ```javascript const { spawn } = require('child_process'); function callVideoSplitter(command, videoPath, options = {}) { return new Promise((resolve, reject) => { const args = [ 'python_core/services/video_splitter.py', command, videoPath ]; // 添加参数 for (const [key, value] of Object.entries(options)) { args.push(`--${key.replace(/_/g, '-')}`, String(value)); } const process = spawn('python3', args); let stdout = ''; let stderr = ''; process.stdout.on('data', (data) => { stdout += data.toString(); }); process.stderr.on('data', (data) => { stderr += data.toString(); }); process.on('close', (code) => { if (code === 0) { try { // 解析JSON-RPC响应 let jsonStr = stdout.trim(); if (jsonStr.startsWith('JSONRPC:')) { jsonStr = jsonStr.substring(8); } const response = JSON.parse(jsonStr); resolve(response); } catch (error) { reject(new Error(`JSON parse error: ${error.message}`)); } } else { reject(new Error(`Command failed: ${stderr}`)); } }); }); } // 使用示例 async function example() { try { // 分析视频 const analyzeResponse = await callVideoSplitter('analyze', 'video.mp4', { threshold: 30.0 }); if (analyzeResponse.result) { console.log(`检测到 ${analyzeResponse.result.total_scenes} 个场景`); } // 拆分视频 const splitResponse = await callVideoSplitter('split', 'video.mp4', { threshold: 30.0, 'output-dir': './output' }); if (splitResponse.result && splitResponse.result.success) { console.log(`拆分成功: ${splitResponse.result.output_files.length} 个文件`); } } catch (error) { console.error('调用失败:', error.message); } } ``` ## 🔧 集成建议 ### 1. 错误处理 ```python def safe_call_video_splitter(command, video_path, **kwargs): try: response = call_video_splitter(command, video_path, **kwargs) if "error" in response: # JSON-RPC错误 error = response["error"] raise Exception(f"[{error['code']}] {error['message']}") if "result" in response: result = response["result"] if isinstance(result, dict) and not result.get("success", True): # 业务逻辑错误 raise Exception(f"Operation failed: {result.get('error', 'Unknown error')}") return result return response except json.JSONDecodeError as e: raise Exception(f"Invalid JSON response: {e}") except subprocess.CalledProcessError as e: raise Exception(f"Process error: {e}") ``` ### 2. 异步处理 ```python import asyncio import concurrent.futures async def async_video_splitter(command, video_path, **kwargs): """异步调用视频拆分服务""" loop = asyncio.get_event_loop() with concurrent.futures.ThreadPoolExecutor() as executor: future = executor.submit(call_video_splitter, command, video_path, **kwargs) return await loop.run_in_executor(None, lambda: future.result()) # 使用示例 async def process_videos(video_list): tasks = [] for video_path in video_list: task = async_video_splitter("analyze", video_path) tasks.append(task) results = await asyncio.gather(*tasks) return results ``` ### 3. 批量处理 ```python def batch_process_videos(video_list, command="analyze", **kwargs): """批量处理视频""" results = [] for video_path in video_list: try: result = call_video_splitter(command, video_path, **kwargs) results.append({ "video_path": video_path, "success": True, "result": result }) except Exception as e: results.append({ "video_path": video_path, "success": False, "error": str(e) }) return results ``` ## 🎉 总结 PySceneDetect视频拆分服务的JSON-RPC接口提供了: - ✅ **标准化协议**: 遵循JSON-RPC 2.0规范 - ✅ **完整功能**: 支持分析、检测、拆分三种操作 - ✅ **详细响应**: 包含完整的场景信息和处理结果 - ✅ **错误处理**: 标准化的错误代码和消息 - ✅ **易于集成**: 支持多种编程语言调用 现在可以轻松地将视频拆分功能集成到任何系统中! --- *JSON-RPC接口 - 让视频拆分服务更易集成!*