236 lines
7.0 KiB
Python
236 lines
7.0 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
完整的AI监控系统启动器(包含GUI界面)
|
||
同时启动后端服务和GUI前端
|
||
"""
|
||
|
||
import sys
|
||
import os
|
||
import time
|
||
import signal
|
||
import subprocess
|
||
import threading
|
||
import websockets
|
||
from pathlib import Path
|
||
|
||
class AIMonitorSystem:
|
||
def __init__(self):
|
||
self.base_dir = Path(__file__).parent
|
||
self.processes = []
|
||
self.running = True
|
||
|
||
def check_dependencies(self):
|
||
"""检查依赖包"""
|
||
print("检查系统依赖...")
|
||
|
||
required_packages = [
|
||
'cv2', 'yaml', 'websockets', 'flask',
|
||
'PyQt6', 'numpy'
|
||
]
|
||
|
||
missing_packages = []
|
||
|
||
for package in required_packages:
|
||
try:
|
||
if package == 'cv2':
|
||
import cv2
|
||
elif package == 'yaml':
|
||
import yaml
|
||
elif package == 'websockets':
|
||
import websockets
|
||
elif package == 'flask':
|
||
import flask
|
||
elif package == 'PyQt6':
|
||
from PyQt6 import QtWidgets
|
||
elif package == 'numpy':
|
||
import numpy
|
||
print(f"✓ {package}")
|
||
except ImportError:
|
||
missing_packages.append(package)
|
||
print(f"✗ {package} (缺失)")
|
||
|
||
if missing_packages:
|
||
print(f"\n缺少依赖包: {', '.join(missing_packages)}")
|
||
print("请运行: pip install -r requirements.txt")
|
||
return False
|
||
|
||
print("✓ 所有依赖检查通过")
|
||
return True
|
||
|
||
def start_backend_services(self):
|
||
"""启动后端服务"""
|
||
print("启动后端服务...")
|
||
|
||
# 创建必要目录
|
||
os.makedirs("videos", exist_ok=True)
|
||
os.makedirs("YOLO_Pipe_results", exist_ok=True)
|
||
|
||
# 启动RTSP服务
|
||
try:
|
||
rtsp_process = subprocess.Popen(
|
||
[sys.executable, "rtsp_service_ws.py"],
|
||
cwd=str(self.base_dir),
|
||
stdout=subprocess.PIPE,
|
||
stderr=subprocess.STDOUT,
|
||
universal_newlines=True
|
||
)
|
||
self.processes.append(("RTSP服务", rtsp_process))
|
||
|
||
def monitor_rtsp():
|
||
for line in iter(rtsp_process.stdout.readline, ''):
|
||
if line.strip() and self.running:
|
||
print(f"[RTSP] {line.strip()}")
|
||
|
||
threading.Thread(target=monitor_rtsp, daemon=True).start()
|
||
print("✓ RTSP服务已启动")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 启动RTSP服务失败: {e}")
|
||
return False
|
||
|
||
# 等待RTSP服务启动
|
||
time.sleep(2)
|
||
|
||
# 启动HTTP服务
|
||
try:
|
||
http_process = subprocess.Popen(
|
||
[sys.executable, "static_server.py"],
|
||
cwd=str(self.base_dir),
|
||
stdout=subprocess.PIPE,
|
||
stderr=subprocess.STDOUT,
|
||
universal_newlines=True
|
||
)
|
||
self.processes.append(("HTTP服务", http_process))
|
||
|
||
def monitor_http():
|
||
for line in iter(http_process.stdout.readline, ''):
|
||
if line.strip() and self.running:
|
||
print(f"[HTTP] {line.strip()}")
|
||
|
||
threading.Thread(target=monitor_http, daemon=True).start()
|
||
print("✓ HTTP服务已启动")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 启动HTTP服务失败: {e}")
|
||
return False
|
||
|
||
# 等待服务完全启动
|
||
time.sleep(2)
|
||
|
||
# 验证端口监听
|
||
import socket
|
||
|
||
def check_port(port, name):
|
||
try:
|
||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||
sock.settimeout(1)
|
||
result = sock.connect_ex(('localhost', port))
|
||
sock.close()
|
||
return result == 0
|
||
except:
|
||
return False
|
||
|
||
if not check_port(8765, "RTSP"):
|
||
print("✗ RTSP服务端口未监听")
|
||
return False
|
||
|
||
if not check_port(5000, "HTTP"):
|
||
print("✗ HTTP服务端口未监听")
|
||
return False
|
||
|
||
print("✓ 后端服务验证通过")
|
||
return True
|
||
|
||
def start_gui(self):
|
||
"""启动GUI界面"""
|
||
print("启动GUI界面...")
|
||
|
||
try:
|
||
# 导入GUI模块
|
||
from monitor_gui import AIMonitorGUI
|
||
import sys
|
||
from PyQt6.QtWidgets import QApplication
|
||
|
||
# 在主线程中创建GUI应用
|
||
if not QApplication.instance():
|
||
app = QApplication(sys.argv)
|
||
|
||
# 创建主窗口
|
||
self.gui_window = AIMonitorGUI()
|
||
self.gui_window.show()
|
||
|
||
print("✓ GUI界面已启动")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 启动GUI失败: {e}")
|
||
return False
|
||
|
||
def signal_handler(self, signum, frame):
|
||
"""处理退出信号"""
|
||
print("\n正在关闭系统...")
|
||
self.running = False
|
||
self.stop_all()
|
||
sys.exit(0)
|
||
|
||
def stop_all(self):
|
||
"""停止所有服务"""
|
||
for name, process in self.processes:
|
||
try:
|
||
process.terminate()
|
||
try:
|
||
process.wait(timeout=5)
|
||
except subprocess.TimeoutExpired:
|
||
process.kill()
|
||
print(f"✓ {name}已停止")
|
||
except Exception as e:
|
||
print(f"✗ 停止{name}失败: {e}")
|
||
|
||
def run(self):
|
||
"""运行完整系统"""
|
||
print("=== AI监控系统完整启动器 ===")
|
||
print("包含后端服务和GUI前端\n")
|
||
|
||
# 注册信号处理
|
||
signal.signal(signal.SIGINT, self.signal_handler)
|
||
signal.signal(signal.SIGTERM, self.signal_handler)
|
||
|
||
# 检查依赖
|
||
if not self.check_dependencies():
|
||
return False
|
||
|
||
# 启动后端服务
|
||
if not self.start_backend_services():
|
||
return False
|
||
|
||
print("\n=== 后端服务启动完成 ===")
|
||
print("RTSP WebSocket服务: ws://localhost:8765")
|
||
print("HTTP静态文件服务: http://localhost:5000")
|
||
print()
|
||
|
||
# 启动GUI
|
||
if not self.start_gui():
|
||
return False
|
||
|
||
print("\n=== GUI界面启动完成 ===")
|
||
print("请使用GUI界面进行监控操作")
|
||
print("按 Ctrl+C 停止所有服务")
|
||
|
||
# 保持主线程运行
|
||
try:
|
||
while self.running:
|
||
time.sleep(1)
|
||
except KeyboardInterrupt:
|
||
self.signal_handler(signal.SIGINT, None)
|
||
|
||
return True
|
||
|
||
|
||
def main():
|
||
"""主函数"""
|
||
system = AIMonitorSystem()
|
||
system.run()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main() |