fix: 修复命令行工具
This commit is contained in:
86
examples/test_jsonrpc_registration.py
Normal file
86
examples/test_jsonrpc_registration.py
Normal file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test JSON-RPC Registration
|
||||
测试JSON-RPC方法注册
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
project_root = Path(__file__).parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from python_core.utils.jsonrpc_enhanced import method_registry
|
||||
from python_core.scene_detection import SceneDetector
|
||||
|
||||
|
||||
def test_method_registration():
|
||||
"""测试方法注册"""
|
||||
print("🧪 测试JSON-RPC方法注册...")
|
||||
|
||||
# 创建检测器并注册方法
|
||||
detector = SceneDetector()
|
||||
detector.register_jsonrpc_methods()
|
||||
|
||||
# 检查注册的方法
|
||||
print(f"📋 已注册的方法: {list(method_registry.methods.keys())}")
|
||||
|
||||
# 测试方法调用
|
||||
test_request = '''
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "scene.get_video_info",
|
||||
"params": {
|
||||
"video_path": "assets/1/1752032011698.mp4"
|
||||
},
|
||||
"id": 1
|
||||
}
|
||||
'''
|
||||
|
||||
print("📤 测试方法调用...")
|
||||
response = method_registry.handle_request(test_request)
|
||||
|
||||
if response:
|
||||
print("📥 收到响应:")
|
||||
print(response)
|
||||
else:
|
||||
print("📥 收到空响应(异步模式)")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def test_direct_method_call():
|
||||
"""测试直接方法调用"""
|
||||
print("\n🧪 测试直接方法调用...")
|
||||
|
||||
detector = SceneDetector()
|
||||
|
||||
# 直接调用方法
|
||||
result = detector.jsonrpc_get_video_info("assets/1/1752032011698.mp4")
|
||||
|
||||
print(f"📋 直接调用结果: {result}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("🚀 开始测试JSON-RPC方法注册")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
test_method_registration()
|
||||
test_direct_method_call()
|
||||
print("\n✅ 所有测试通过")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"\n❌ 测试失败: {e}")
|
||||
import traceback
|
||||
print(f"详细错误: {traceback.format_exc()}")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
271
examples/test_jsonrpc_workflow.py
Normal file
271
examples/test_jsonrpc_workflow.py
Normal file
@@ -0,0 +1,271 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
测试JSON-RPC工作流进度反馈
|
||||
Test JSON-RPC Workflow Progress Feedback
|
||||
"""
|
||||
|
||||
import json
|
||||
import requests
|
||||
import time
|
||||
import threading
|
||||
import websocket
|
||||
from typing import Dict, Any
|
||||
|
||||
|
||||
class JSONRPCWorkflowTester:
|
||||
"""JSON-RPC工作流测试器"""
|
||||
|
||||
def __init__(self, server_url: str = "http://localhost:8081"):
|
||||
self.server_url = server_url
|
||||
self.request_id = 0
|
||||
self.progress_updates = []
|
||||
|
||||
def _call_method(self, method: str, params: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""调用JSON-RPC方法"""
|
||||
self.request_id += 1
|
||||
|
||||
payload = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": method,
|
||||
"params": params,
|
||||
"id": self.request_id
|
||||
}
|
||||
|
||||
print(f"📤 发送请求 (ID: {self.request_id}): {method}")
|
||||
print(f" 参数: {json.dumps(params, indent=2, ensure_ascii=False)}")
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
self.server_url,
|
||||
json=payload,
|
||||
headers={'Content-Type': 'application/json'},
|
||||
timeout=120 # 增加超时时间
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
print(f"📥 收到响应 (ID: {self.request_id}): {response.status_code}")
|
||||
return result
|
||||
else:
|
||||
print(f"❌ HTTP错误: {response.status_code}")
|
||||
return {
|
||||
"error": {
|
||||
"code": response.status_code,
|
||||
"message": f"HTTP Error: {response.text}"
|
||||
}
|
||||
}
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"❌ 请求失败: {str(e)}")
|
||||
return {
|
||||
"error": {
|
||||
"code": -1,
|
||||
"message": f"Request failed: {str(e)}"
|
||||
}
|
||||
}
|
||||
|
||||
def test_basic_detection(self):
|
||||
"""测试基础场景检测"""
|
||||
print("\n" + "="*60)
|
||||
print("🎯 测试基础场景检测")
|
||||
print("="*60)
|
||||
|
||||
params = {
|
||||
"video_path": "assets/1/1752032011698.mp4",
|
||||
"detector_type": "content",
|
||||
"threshold": 15.0,
|
||||
"min_scene_length": 1.0
|
||||
}
|
||||
|
||||
start_time = time.time()
|
||||
result = self._call_method("scene.detect", params)
|
||||
end_time = time.time()
|
||||
|
||||
if "error" in result:
|
||||
print(f"❌ 检测失败: {result['error']}")
|
||||
return False
|
||||
|
||||
detection_result = result.get("result", {})
|
||||
if detection_result.get("success"):
|
||||
print(f"✅ 基础检测成功!")
|
||||
print(f" 场景数量: {detection_result['total_scenes']}")
|
||||
print(f" 检测时间: {detection_result['detection_time']:.2f}秒")
|
||||
print(f" API调用时间: {end_time - start_time:.2f}秒")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ 检测失败: {detection_result.get('error', '未知错误')}")
|
||||
return False
|
||||
|
||||
def test_workflow_detection(self):
|
||||
"""测试工作流场景检测"""
|
||||
print("\n" + "="*60)
|
||||
print("🔄 测试LangGraph工作流检测")
|
||||
print("="*60)
|
||||
|
||||
params = {
|
||||
"video_path": "assets/1/1752032011698.mp4",
|
||||
"detector_type": "content",
|
||||
"threshold": 15.0,
|
||||
"min_scene_length": 1.0,
|
||||
"enable_ai_analysis": False # 禁用AI分析避免API密钥问题
|
||||
}
|
||||
|
||||
start_time = time.time()
|
||||
result = self._call_method("scene.detect_workflow", params)
|
||||
end_time = time.time()
|
||||
|
||||
if "error" in result:
|
||||
print(f"❌ 工作流检测失败: {result['error']}")
|
||||
return False
|
||||
|
||||
workflow_result = result.get("result", {})
|
||||
detection_result = workflow_result.get("detection_result", {})
|
||||
|
||||
if detection_result.get("success"):
|
||||
print(f"✅ 工作流检测成功!")
|
||||
print(f" 工作流状态: {workflow_result.get('workflow_state')}")
|
||||
print(f" 场景数量: {detection_result['total_scenes']}")
|
||||
print(f" 检测时间: {detection_result['detection_time']:.2f}秒")
|
||||
print(f" API调用时间: {end_time - start_time:.2f}秒")
|
||||
|
||||
# 显示视频信息
|
||||
video_info = workflow_result.get("video_info", {})
|
||||
if video_info:
|
||||
print(f" 视频信息: {video_info.get('resolution')}, {video_info.get('fps'):.2f}fps")
|
||||
|
||||
# 显示AI分析结果
|
||||
ai_analysis = workflow_result.get("ai_analysis")
|
||||
if ai_analysis:
|
||||
print(f" AI分析: {ai_analysis[:100]}...")
|
||||
|
||||
return True
|
||||
else:
|
||||
print(f"❌ 工作流检测失败: {detection_result.get('error', '未知错误')}")
|
||||
return False
|
||||
|
||||
def test_video_info(self):
|
||||
"""测试视频信息获取"""
|
||||
print("\n" + "="*60)
|
||||
print("📊 测试视频信息获取")
|
||||
print("="*60)
|
||||
|
||||
params = {
|
||||
"video_path": "assets/1/1752032011698.mp4"
|
||||
}
|
||||
|
||||
start_time = time.time()
|
||||
result = self._call_method("scene.get_video_info", params)
|
||||
end_time = time.time()
|
||||
|
||||
if "error" in result:
|
||||
print(f"❌ 获取失败: {result['error']}")
|
||||
return False
|
||||
|
||||
info_result = result.get("result", {})
|
||||
if info_result.get("success"):
|
||||
info = info_result.get("info", {})
|
||||
print(f"✅ 信息获取成功!")
|
||||
print(f" 文件名: {info.get('filename')}")
|
||||
print(f" 分辨率: {info.get('resolution')}")
|
||||
print(f" 帧率: {info.get('fps'):.2f} fps")
|
||||
print(f" 时长: {info.get('duration'):.2f}秒")
|
||||
print(f" 文件大小: {info.get('file_size'):,} 字节")
|
||||
print(f" API调用时间: {end_time - start_time:.2f}秒")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ 获取失败: {info_result.get('error', '未知错误')}")
|
||||
return False
|
||||
|
||||
def test_error_handling(self):
|
||||
"""测试错误处理"""
|
||||
print("\n" + "="*60)
|
||||
print("🚨 测试错误处理")
|
||||
print("="*60)
|
||||
|
||||
# 测试不存在的文件
|
||||
params = {
|
||||
"video_path": "nonexistent_video.mp4",
|
||||
"threshold": 15.0
|
||||
}
|
||||
|
||||
result = self._call_method("scene.detect", params)
|
||||
|
||||
if "error" in result:
|
||||
print(f"✅ 正确处理了请求错误: {result['error']['message']}")
|
||||
else:
|
||||
detection_result = result.get("result", {})
|
||||
if not detection_result.get("success"):
|
||||
print(f"✅ 正确处理了应用错误: {detection_result.get('error')}")
|
||||
else:
|
||||
print(f"❌ 应该返回错误,但返回了成功结果")
|
||||
return False
|
||||
|
||||
# 测试无效的方法
|
||||
result = self._call_method("scene.invalid_method", {})
|
||||
if "error" in result and result["error"]["code"] == -32601:
|
||||
print(f"✅ 正确处理了方法不存在错误")
|
||||
else:
|
||||
print(f"❌ 没有正确处理方法不存在错误")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def run_all_tests(self):
|
||||
"""运行所有测试"""
|
||||
print("🚀 JSON-RPC工作流测试开始")
|
||||
print("="*60)
|
||||
|
||||
# 检查服务器连接
|
||||
try:
|
||||
test_result = self._call_method("scene.get_video_info", {"video_path": "test.mp4"})
|
||||
if "error" in test_result and "Request failed" in str(test_result["error"]):
|
||||
print("❌ 无法连接到JSON-RPC服务器")
|
||||
print("💡 请先启动服务器: python3 -m python_core.cli jsonrpc start --port 8081")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"❌ 连接测试失败: {e}")
|
||||
return False
|
||||
|
||||
print("✅ 服务器连接正常")
|
||||
|
||||
# 运行测试
|
||||
tests = [
|
||||
("视频信息获取", self.test_video_info),
|
||||
("基础场景检测", self.test_basic_detection),
|
||||
("工作流场景检测", self.test_workflow_detection),
|
||||
("错误处理", self.test_error_handling),
|
||||
]
|
||||
|
||||
passed = 0
|
||||
total = len(tests)
|
||||
|
||||
for test_name, test_func in tests:
|
||||
try:
|
||||
if test_func():
|
||||
passed += 1
|
||||
print(f"✅ {test_name} - 通过")
|
||||
else:
|
||||
print(f"❌ {test_name} - 失败")
|
||||
except Exception as e:
|
||||
print(f"❌ {test_name} - 异常: {e}")
|
||||
|
||||
print("\n" + "="*60)
|
||||
print(f"🎉 测试完成: {passed}/{total} 通过")
|
||||
print("="*60)
|
||||
|
||||
if passed == total:
|
||||
print("🎊 所有测试都通过了!JSON-RPC工作流功能正常")
|
||||
else:
|
||||
print("⚠️ 部分测试失败,请检查服务器和配置")
|
||||
|
||||
return passed == total
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
tester = JSONRPCWorkflowTester("http://localhost:8081")
|
||||
tester.run_all_tests()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
248
examples/test_refactored_modules.py
Normal file
248
examples/test_refactored_modules.py
Normal file
@@ -0,0 +1,248 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test Refactored Modules
|
||||
测试重构后的模块
|
||||
|
||||
验证重构后的场景检测模块是否正常工作
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
project_root = Path(__file__).parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from python_core.scene_detection import (
|
||||
SceneDetector,
|
||||
DetectorType,
|
||||
OutputFormat,
|
||||
SceneInfo,
|
||||
DetectionResult,
|
||||
SceneDetectionWorkflowState
|
||||
)
|
||||
|
||||
|
||||
def test_imports():
|
||||
"""测试模块导入"""
|
||||
print("🧪 测试模块导入...")
|
||||
|
||||
try:
|
||||
# 测试类型导入
|
||||
assert DetectorType.CONTENT == "content"
|
||||
assert OutputFormat.JSON == "json"
|
||||
print("✅ 类型导入成功")
|
||||
|
||||
# 测试数据模型
|
||||
scene = SceneInfo(0, 0.0, 5.0, 5.0)
|
||||
assert scene.index == 0
|
||||
assert scene.duration == 5.0
|
||||
print("✅ 数据模型导入成功")
|
||||
|
||||
# 测试主接口类
|
||||
detector = SceneDetector()
|
||||
assert detector is not None
|
||||
assert hasattr(detector, 'detect_scenes')
|
||||
assert hasattr(detector, 'detect_with_workflow')
|
||||
print("✅ 主接口类导入成功")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 导入测试失败: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def test_basic_functionality():
|
||||
"""测试基础功能"""
|
||||
print("\n🧪 测试基础功能...")
|
||||
|
||||
try:
|
||||
detector = SceneDetector()
|
||||
|
||||
# 测试视频信息获取
|
||||
video_path = Path("assets/1/1752032011698.mp4")
|
||||
if video_path.exists():
|
||||
info_result = detector.get_video_info(video_path)
|
||||
if info_result["success"]:
|
||||
print("✅ 视频信息获取成功")
|
||||
print(f" 分辨率: {info_result['info']['resolution']}")
|
||||
print(f" 时长: {info_result['info']['duration']:.2f}秒")
|
||||
else:
|
||||
print(f"⚠️ 视频信息获取失败: {info_result['error']}")
|
||||
else:
|
||||
print("⚠️ 测试视频文件不存在,跳过视频信息测试")
|
||||
|
||||
# 测试JSON-RPC方法注册
|
||||
detector.register_jsonrpc_methods()
|
||||
print("✅ JSON-RPC方法注册成功")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 基础功能测试失败: {e}")
|
||||
import traceback
|
||||
print(f"详细错误: {traceback.format_exc()}")
|
||||
return False
|
||||
|
||||
|
||||
def test_services():
|
||||
"""测试服务层"""
|
||||
print("\n🧪 测试服务层...")
|
||||
|
||||
try:
|
||||
from python_core.scene_detection.services import (
|
||||
SceneDetectorService,
|
||||
VideoInfoService,
|
||||
AIAnalysisService
|
||||
)
|
||||
|
||||
# 测试检测服务
|
||||
detector_service = SceneDetectorService()
|
||||
assert len(detector_service.supported_formats) > 0
|
||||
print("✅ 场景检测服务初始化成功")
|
||||
|
||||
# 测试视频信息服务
|
||||
video_info_service = VideoInfoService()
|
||||
assert hasattr(video_info_service, 'extract_video_info')
|
||||
print("✅ 视频信息服务初始化成功")
|
||||
|
||||
# 测试AI分析服务
|
||||
ai_service = AIAnalysisService()
|
||||
assert hasattr(ai_service, 'analyze_detection_result')
|
||||
print(f"✅ AI分析服务初始化成功 (AI启用: {ai_service.ai_enabled})")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 服务层测试失败: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def test_workflows():
|
||||
"""测试工作流"""
|
||||
print("\n🧪 测试工作流...")
|
||||
|
||||
try:
|
||||
from python_core.scene_detection.workflows import (
|
||||
SceneDetectionWorkflowManager,
|
||||
WorkflowNodes
|
||||
)
|
||||
|
||||
# 测试工作流管理器
|
||||
workflow_manager = SceneDetectionWorkflowManager()
|
||||
assert hasattr(workflow_manager, 'create_detection_workflow')
|
||||
print("✅ 工作流管理器初始化成功")
|
||||
|
||||
# 测试工作流节点
|
||||
nodes = WorkflowNodes()
|
||||
assert hasattr(nodes, 'validate_input')
|
||||
assert hasattr(nodes, 'detect_scenes')
|
||||
assert hasattr(nodes, 'finalize_results')
|
||||
print("✅ 工作流节点初始化成功")
|
||||
|
||||
# 测试工作流创建
|
||||
workflow = workflow_manager.create_detection_workflow()
|
||||
if workflow:
|
||||
print("✅ LangGraph工作流创建成功")
|
||||
else:
|
||||
print("⚠️ LangGraph工作流创建失败(可能是依赖问题)")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 工作流测试失败: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def test_utils():
|
||||
"""测试工具类"""
|
||||
print("\n🧪 测试工具类...")
|
||||
|
||||
try:
|
||||
from python_core.scene_detection.utils import (
|
||||
ResultSaver,
|
||||
InputValidator
|
||||
)
|
||||
|
||||
# 测试结果保存器
|
||||
saver = ResultSaver()
|
||||
assert hasattr(saver, 'save_results')
|
||||
print("✅ 结果保存器初始化成功")
|
||||
|
||||
# 测试输入验证器
|
||||
validator = InputValidator({'.mp4', '.avi'})
|
||||
assert hasattr(validator, 'validate_video_path')
|
||||
print("✅ 输入验证器初始化成功")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 工具类测试失败: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def test_cli_integration():
|
||||
"""测试CLI集成"""
|
||||
print("\n🧪 测试CLI集成...")
|
||||
|
||||
try:
|
||||
# 测试新的CLI模块
|
||||
from python_core.cli.scene_detect_new import app
|
||||
assert app is not None
|
||||
print("✅ 新CLI模块导入成功")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ CLI集成测试失败: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
"""主测试函数"""
|
||||
print("🚀 开始测试重构后的场景检测模块")
|
||||
print("=" * 60)
|
||||
|
||||
tests = [
|
||||
("模块导入", test_imports),
|
||||
("基础功能", test_basic_functionality),
|
||||
("服务层", test_services),
|
||||
("工作流", test_workflows),
|
||||
("工具类", test_utils),
|
||||
("CLI集成", test_cli_integration),
|
||||
]
|
||||
|
||||
passed = 0
|
||||
total = len(tests)
|
||||
|
||||
for test_name, test_func in tests:
|
||||
try:
|
||||
if test_func():
|
||||
passed += 1
|
||||
print(f"✅ {test_name} - 通过")
|
||||
else:
|
||||
print(f"❌ {test_name} - 失败")
|
||||
except Exception as e:
|
||||
print(f"❌ {test_name} - 异常: {e}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(f"🎉 测试完成: {passed}/{total} 通过")
|
||||
|
||||
if passed == total:
|
||||
print("🎊 所有测试都通过了!重构成功!")
|
||||
print("\n📋 重构后的模块结构:")
|
||||
print("├── types/ # 类型定义和数据模型")
|
||||
print("├── services/ # 核心业务逻辑服务")
|
||||
print("├── workflows/ # LangGraph工作流")
|
||||
print("├── utils/ # 工具类和辅助函数")
|
||||
print("└── scene_detector.py # 主接口类")
|
||||
else:
|
||||
print("⚠️ 部分测试失败,请检查重构实现")
|
||||
|
||||
return passed == total
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
206
examples/test_scene_detection_fix.py
Normal file
206
examples/test_scene_detection_fix.py
Normal file
@@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test Scene Detection Fix
|
||||
测试场景检测修复
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
project_root = Path(__file__).parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from python_core.scene_detection.services import SceneDetectorService
|
||||
from python_core.scene_detection.types import DetectorType
|
||||
|
||||
|
||||
def test_basic_detection():
|
||||
"""测试基础场景检测"""
|
||||
print("🧪 测试基础场景检测...")
|
||||
|
||||
try:
|
||||
# 创建检测服务
|
||||
detector_service = SceneDetectorService()
|
||||
|
||||
# 测试视频路径
|
||||
video_path = Path("assets/1/1752032011698.mp4")
|
||||
|
||||
if not video_path.exists():
|
||||
print(f"❌ 测试视频不存在: {video_path}")
|
||||
return False
|
||||
|
||||
print(f"📹 测试视频: {video_path}")
|
||||
|
||||
# 执行检测
|
||||
result = detector_service.detect_scenes(
|
||||
video_path,
|
||||
DetectorType.CONTENT,
|
||||
30.0,
|
||||
1.0
|
||||
)
|
||||
|
||||
if result.success:
|
||||
print(f"✅ 检测成功!")
|
||||
print(f" 场景数量: {result.total_scenes}")
|
||||
print(f" 检测时间: {result.detection_time:.2f}秒")
|
||||
print(f" 视频时长: {result.total_duration:.2f}秒")
|
||||
|
||||
# 显示前几个场景
|
||||
for i, scene in enumerate(result.scenes[:3]):
|
||||
print(f" 场景 {i+1}: {scene.start_time:.2f}s - {scene.end_time:.2f}s (时长: {scene.duration:.2f}s)")
|
||||
|
||||
if len(result.scenes) > 3:
|
||||
print(f" ... 还有 {len(result.scenes) - 3} 个场景")
|
||||
|
||||
return True
|
||||
else:
|
||||
print(f"❌ 检测失败: {result.error}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 测试异常: {e}")
|
||||
import traceback
|
||||
print(f"详细错误: {traceback.format_exc()}")
|
||||
return False
|
||||
|
||||
|
||||
def test_video_info():
|
||||
"""测试视频信息提取"""
|
||||
print("\n🧪 测试视频信息提取...")
|
||||
|
||||
try:
|
||||
from python_core.scene_detection.services import VideoInfoService
|
||||
|
||||
video_info_service = VideoInfoService()
|
||||
video_path = Path("assets/1/1752032011698.mp4")
|
||||
|
||||
if not video_path.exists():
|
||||
print(f"❌ 测试视频不存在: {video_path}")
|
||||
return False
|
||||
|
||||
info = video_info_service.extract_video_info(video_path)
|
||||
|
||||
print(f"✅ 视频信息提取成功!")
|
||||
print(f" 文件名: {info['filename']}")
|
||||
print(f" 分辨率: {info['resolution']}")
|
||||
print(f" 帧率: {info['fps']:.2f} fps")
|
||||
print(f" 时长: {info['duration']:.2f}秒")
|
||||
print(f" 文件大小: {info['file_size']:,} 字节")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 测试异常: {e}")
|
||||
import traceback
|
||||
print(f"详细错误: {traceback.format_exc()}")
|
||||
return False
|
||||
|
||||
|
||||
def test_pyscenedetect_version():
|
||||
"""测试PySceneDetect版本和API"""
|
||||
print("\n🧪 测试PySceneDetect版本和API...")
|
||||
|
||||
try:
|
||||
import scenedetect
|
||||
print(f"📦 PySceneDetect版本: {scenedetect.__version__}")
|
||||
|
||||
# 测试基本API
|
||||
from scenedetect import open_video, SceneManager
|
||||
from scenedetect.detectors import ContentDetector
|
||||
|
||||
video_path = Path("assets/1/1752032011698.mp4")
|
||||
if not video_path.exists():
|
||||
print(f"❌ 测试视频不存在: {video_path}")
|
||||
return False
|
||||
|
||||
# 打开视频
|
||||
video = open_video(str(video_path))
|
||||
scene_manager = SceneManager()
|
||||
scene_manager.add_detector(ContentDetector(threshold=30.0))
|
||||
|
||||
print("📊 执行基础场景检测...")
|
||||
scene_manager.detect_scenes(video, show_progress=False)
|
||||
scene_list = scene_manager.get_scene_list()
|
||||
|
||||
print(f"✅ 基础检测成功,找到 {len(scene_list)} 个场景")
|
||||
|
||||
# 测试时间码API
|
||||
if scene_list:
|
||||
start_time, end_time = scene_list[0]
|
||||
print(f"📋 第一个场景时间码类型: {type(start_time)}")
|
||||
|
||||
# 测试不同的时间获取方法
|
||||
methods = []
|
||||
|
||||
if hasattr(start_time, 'total_seconds'):
|
||||
try:
|
||||
seconds = start_time.total_seconds()
|
||||
methods.append(f"total_seconds(): {seconds:.2f}")
|
||||
except Exception as e:
|
||||
methods.append(f"total_seconds() 失败: {e}")
|
||||
|
||||
if hasattr(start_time, 'get_seconds'):
|
||||
try:
|
||||
seconds = start_time.get_seconds()
|
||||
methods.append(f"get_seconds(): {seconds:.2f}")
|
||||
except Exception as e:
|
||||
methods.append(f"get_seconds() 失败: {e}")
|
||||
|
||||
try:
|
||||
seconds = float(start_time)
|
||||
methods.append(f"float(): {seconds:.2f}")
|
||||
except Exception as e:
|
||||
methods.append(f"float() 失败: {e}")
|
||||
|
||||
print("🔍 可用的时间获取方法:")
|
||||
for method in methods:
|
||||
print(f" - {method}")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 测试异常: {e}")
|
||||
import traceback
|
||||
print(f"详细错误: {traceback.format_exc()}")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("🚀 开始测试场景检测修复")
|
||||
print("=" * 60)
|
||||
|
||||
tests = [
|
||||
("PySceneDetect版本和API", test_pyscenedetect_version),
|
||||
("视频信息提取", test_video_info),
|
||||
("基础场景检测", test_basic_detection),
|
||||
]
|
||||
|
||||
passed = 0
|
||||
total = len(tests)
|
||||
|
||||
for test_name, test_func in tests:
|
||||
try:
|
||||
if test_func():
|
||||
passed += 1
|
||||
print(f"✅ {test_name} - 通过")
|
||||
else:
|
||||
print(f"❌ {test_name} - 失败")
|
||||
except Exception as e:
|
||||
print(f"❌ {test_name} - 异常: {e}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(f"🎉 测试完成: {passed}/{total} 通过")
|
||||
|
||||
if passed == total:
|
||||
print("🎊 所有测试都通过了!场景检测修复成功!")
|
||||
else:
|
||||
print("⚠️ 部分测试失败,需要进一步调试")
|
||||
|
||||
return passed == total
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
303
examples/test_workflow_results.py
Normal file
303
examples/test_workflow_results.py
Normal file
@@ -0,0 +1,303 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
测试工作流结果返回
|
||||
Test Workflow Result Return
|
||||
"""
|
||||
|
||||
import json
|
||||
import requests
|
||||
import time
|
||||
import threading
|
||||
import queue
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
|
||||
class WorkflowResultTester:
|
||||
"""工作流结果测试器"""
|
||||
|
||||
def __init__(self, server_url: str = "http://localhost:8081"):
|
||||
self.server_url = server_url
|
||||
self.request_id = 0
|
||||
self.progress_queue = queue.Queue()
|
||||
self.result_queue = queue.Queue()
|
||||
|
||||
def _call_method_async(self, method: str, params: Dict[str, Any]) -> str:
|
||||
"""异步调用JSON-RPC方法"""
|
||||
self.request_id += 1
|
||||
request_id = f"test_{self.request_id}_{int(time.time())}"
|
||||
|
||||
payload = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": method,
|
||||
"params": params,
|
||||
"id": request_id
|
||||
}
|
||||
|
||||
print(f"📤 发送异步请求 (ID: {request_id}): {method}")
|
||||
print(f" 参数: {json.dumps(params, indent=2, ensure_ascii=False)}")
|
||||
|
||||
def make_request():
|
||||
try:
|
||||
response = requests.post(
|
||||
self.server_url,
|
||||
json=payload,
|
||||
headers={'Content-Type': 'application/json'},
|
||||
timeout=120
|
||||
)
|
||||
|
||||
print(f"📥 收到HTTP响应 (ID: {request_id}): {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
# 检查是否有响应体
|
||||
if response.text.strip():
|
||||
try:
|
||||
result = response.json()
|
||||
print(f"📋 JSON响应内容: {json.dumps(result, indent=2, ensure_ascii=False)}")
|
||||
self.result_queue.put(("response", request_id, result))
|
||||
except json.JSONDecodeError:
|
||||
print(f"⚠️ 响应不是有效的JSON: {response.text}")
|
||||
self.result_queue.put(("invalid_json", request_id, response.text))
|
||||
else:
|
||||
print(f"✅ 空响应体 - 表示结果已异步发送")
|
||||
self.result_queue.put(("empty_response", request_id, None))
|
||||
else:
|
||||
print(f"❌ HTTP错误: {response.status_code} - {response.text}")
|
||||
self.result_queue.put(("http_error", request_id, {
|
||||
"status_code": response.status_code,
|
||||
"text": response.text
|
||||
}))
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"❌ 请求异常: {str(e)}")
|
||||
self.result_queue.put(("request_error", request_id, str(e)))
|
||||
|
||||
# 在后台线程中发送请求
|
||||
thread = threading.Thread(target=make_request)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
return request_id
|
||||
|
||||
def test_workflow_with_progress_monitoring(self):
|
||||
"""测试带进度监控的工作流"""
|
||||
print("\n" + "="*60)
|
||||
print("🔄 测试工作流进度监控和结果返回")
|
||||
print("="*60)
|
||||
|
||||
# 启动进度监控(模拟WebSocket或长轮询)
|
||||
progress_thread = threading.Thread(target=self._monitor_progress)
|
||||
progress_thread.daemon = True
|
||||
progress_thread.start()
|
||||
|
||||
# 发送工作流请求
|
||||
params = {
|
||||
"video_path": "assets/1/1752032011698.mp4",
|
||||
"detector_type": "content",
|
||||
"threshold": 15.0,
|
||||
"min_scene_length": 1.0,
|
||||
"enable_ai_analysis": False
|
||||
}
|
||||
|
||||
request_id = self._call_method_async("scene.detect_workflow", params)
|
||||
|
||||
# 等待结果
|
||||
print(f"⏳ 等待工作流完成 (Request ID: {request_id})...")
|
||||
|
||||
start_time = time.time()
|
||||
timeout = 60 # 60秒超时
|
||||
|
||||
while time.time() - start_time < timeout:
|
||||
try:
|
||||
result_type, result_id, result_data = self.result_queue.get(timeout=1)
|
||||
|
||||
if result_id == request_id:
|
||||
print(f"\n📋 收到结果 (类型: {result_type}):")
|
||||
|
||||
if result_type == "response":
|
||||
print("✅ 收到JSON-RPC响应:")
|
||||
print(json.dumps(result_data, indent=2, ensure_ascii=False))
|
||||
return True
|
||||
elif result_type == "empty_response":
|
||||
print("✅ 收到空响应 - 结果已通过进度通道发送")
|
||||
return True
|
||||
elif result_type == "http_error":
|
||||
print(f"❌ HTTP错误: {result_data}")
|
||||
return False
|
||||
elif result_type == "request_error":
|
||||
print(f"❌ 请求错误: {result_data}")
|
||||
return False
|
||||
else:
|
||||
print(f"⚠️ 未知结果类型: {result_type}")
|
||||
return False
|
||||
|
||||
except queue.Empty:
|
||||
continue
|
||||
|
||||
print(f"⏰ 等待超时 ({timeout}秒)")
|
||||
return False
|
||||
|
||||
def _monitor_progress(self):
|
||||
"""监控进度更新(模拟)"""
|
||||
# 这里应该是WebSocket连接或长轮询
|
||||
# 为了演示,我们只是打印一些模拟的进度信息
|
||||
print("📊 进度监控已启动...")
|
||||
|
||||
# 模拟进度更新
|
||||
progress_steps = [
|
||||
("validate", "🔍 验证输入参数..."),
|
||||
("extract_info", "📊 提取视频信息..."),
|
||||
("detect", "🎯 执行场景检测..."),
|
||||
("analyze", "🧠 AI分析场景结果..."),
|
||||
("finalize", "📋 整理最终结果...")
|
||||
]
|
||||
|
||||
for step, message in progress_steps:
|
||||
time.sleep(2) # 模拟处理时间
|
||||
print(f"📈 [进度] {step}: {message}")
|
||||
|
||||
def test_basic_method_comparison(self):
|
||||
"""测试基础方法对比"""
|
||||
print("\n" + "="*60)
|
||||
print("🔍 测试基础方法 vs 工作流方法")
|
||||
print("="*60)
|
||||
|
||||
# 测试基础方法(应该返回结果)
|
||||
print("1️⃣ 测试基础场景检测方法:")
|
||||
basic_params = {
|
||||
"video_path": "assets/1/1752032011698.mp4",
|
||||
"threshold": 15.0
|
||||
}
|
||||
|
||||
basic_request_id = self._call_method_async("scene.detect", basic_params)
|
||||
|
||||
# 等待基础方法结果
|
||||
time.sleep(5)
|
||||
|
||||
try:
|
||||
result_type, result_id, result_data = self.result_queue.get(timeout=1)
|
||||
if result_id == basic_request_id:
|
||||
if result_type == "response":
|
||||
print("✅ 基础方法正确返回了JSON响应")
|
||||
print(f" 场景数: {result_data.get('result', {}).get('total_scenes', 'N/A')}")
|
||||
else:
|
||||
print(f"⚠️ 基础方法返回了意外的结果类型: {result_type}")
|
||||
except queue.Empty:
|
||||
print("⏰ 基础方法响应超时")
|
||||
|
||||
print("\n2️⃣ 测试工作流方法:")
|
||||
# 工作流方法测试在上面的方法中进行
|
||||
return self.test_workflow_with_progress_monitoring()
|
||||
|
||||
def test_error_handling(self):
|
||||
"""测试错误处理"""
|
||||
print("\n" + "="*60)
|
||||
print("🚨 测试工作流错误处理")
|
||||
print("="*60)
|
||||
|
||||
# 测试不存在的文件
|
||||
params = {
|
||||
"video_path": "nonexistent_video.mp4",
|
||||
"threshold": 15.0,
|
||||
"enable_ai_analysis": False
|
||||
}
|
||||
|
||||
request_id = self._call_method_async("scene.detect_workflow", params)
|
||||
|
||||
# 等待错误结果
|
||||
print(f"⏳ 等待错误处理 (Request ID: {request_id})...")
|
||||
|
||||
start_time = time.time()
|
||||
timeout = 30
|
||||
|
||||
while time.time() - start_time < timeout:
|
||||
try:
|
||||
result_type, result_id, result_data = self.result_queue.get(timeout=1)
|
||||
|
||||
if result_id == request_id:
|
||||
if result_type == "response" and "error" in result_data:
|
||||
print("✅ 正确收到错误响应:")
|
||||
print(json.dumps(result_data, indent=2, ensure_ascii=False))
|
||||
return True
|
||||
elif result_type == "empty_response":
|
||||
print("✅ 错误已通过进度通道发送")
|
||||
return True
|
||||
else:
|
||||
print(f"⚠️ 意外的错误处理结果: {result_type}")
|
||||
return False
|
||||
|
||||
except queue.Empty:
|
||||
continue
|
||||
|
||||
print(f"⏰ 错误处理等待超时")
|
||||
return False
|
||||
|
||||
def run_all_tests(self):
|
||||
"""运行所有测试"""
|
||||
print("🚀 工作流结果返回测试开始")
|
||||
print("="*60)
|
||||
|
||||
# 检查服务器连接
|
||||
try:
|
||||
response = requests.get(f"{self.server_url.replace('//', '//').replace('http:', 'http:').replace('8081', '8081')}")
|
||||
except:
|
||||
try:
|
||||
# 简单的连接测试
|
||||
test_payload = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "scene.get_video_info",
|
||||
"params": {"video_path": "test.mp4"},
|
||||
"id": "test"
|
||||
}
|
||||
response = requests.post(
|
||||
self.server_url,
|
||||
json=test_payload,
|
||||
headers={'Content-Type': 'application/json'},
|
||||
timeout=5
|
||||
)
|
||||
except Exception as e:
|
||||
print("❌ 无法连接到JSON-RPC服务器")
|
||||
print("💡 请先启动服务器: python3 -m python_core.cli jsonrpc start --port 8081")
|
||||
return False
|
||||
|
||||
print("✅ 服务器连接正常")
|
||||
|
||||
# 运行测试
|
||||
tests = [
|
||||
("基础方法对比", self.test_basic_method_comparison),
|
||||
("错误处理", self.test_error_handling),
|
||||
]
|
||||
|
||||
passed = 0
|
||||
total = len(tests)
|
||||
|
||||
for test_name, test_func in tests:
|
||||
try:
|
||||
print(f"\n🧪 运行测试: {test_name}")
|
||||
if test_func():
|
||||
passed += 1
|
||||
print(f"✅ {test_name} - 通过")
|
||||
else:
|
||||
print(f"❌ {test_name} - 失败")
|
||||
except Exception as e:
|
||||
print(f"❌ {test_name} - 异常: {e}")
|
||||
|
||||
print("\n" + "="*60)
|
||||
print(f"🎉 测试完成: {passed}/{total} 通过")
|
||||
print("="*60)
|
||||
|
||||
if passed == total:
|
||||
print("🎊 所有测试都通过了!工作流结果返回功能正常")
|
||||
else:
|
||||
print("⚠️ 部分测试失败,请检查实现")
|
||||
|
||||
return passed == total
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
tester = WorkflowResultTester("http://localhost:8081")
|
||||
tester.run_all_tests()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user