diff --git a/.gitignore b/.gitignore index e800035..cf5f44a 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ *.swp *.swo .DS_Store +agent/rk3588-agent_linux_arm64 diff --git a/agent/rk3588-agent_linux_arm64 b/agent/rk3588-agent_linux_arm64 index 9115d6f..fcdc079 100755 Binary files a/agent/rk3588-agent_linux_arm64 and b/agent/rk3588-agent_linux_arm64 differ diff --git a/scripts/deploy.sh b/scripts/deploy.sh index a4764ee..80643bc 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -191,6 +191,14 @@ cmd_install_media_server() { cp "$BUILD_DIR/media-server" "$INSTALL_DIR/bin/" chmod +x "$INSTALL_DIR/bin/media-server" + # 复制运维脚本 + mkdir -p "$INSTALL_DIR/scripts" + if [ -f "$PROJECT_DIR/scripts/ops.sh" ]; then + cp "$PROJECT_DIR/scripts/ops.sh" "$INSTALL_DIR/scripts/" + chmod +x "$INSTALL_DIR/scripts/ops.sh" + echo -e "${GREEN}✓${NC} 已复制运维脚本: ops.sh" + fi + # 复制插件 if [ -d "$BUILD_DIR/plugins" ]; then cp "$BUILD_DIR"/plugins/*.so "$INSTALL_DIR/bin/plugins/" 2>/dev/null || true diff --git a/scripts/manage.sh b/scripts/manage.sh deleted file mode 100755 index ae5b0ac..0000000 --- a/scripts/manage.sh +++ /dev/null @@ -1,416 +0,0 @@ -#!/bin/bash -# RK3588 Media Server + Agent 统一管理脚本 -# Media Server 和 Agent 是独立的 systemd 服务 -# 用法: sudo ./manage.sh [install|status|uninstall] - -set -e - -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' - -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" -BUILD_DIR="$PROJECT_DIR/build" -INSTALL_DIR="/opt/rk3588-media-server" -AGENT_INSTALL_DIR="/opt/rk3588-agent" -SERVICE_DIR="/etc/systemd/system" - -# ==================== 功能函数 ==================== - -cmd_install() { - echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}" - echo -e "${BLUE}║ RK3588 Media Server + Agent 安装脚本 ║${NC}" - echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}" - echo "" - - if [ "$(id -u)" -ne 0 ]; then - echo -e "${RED}错误: 请使用 sudo 运行此脚本${NC}" - exit 1 - fi - - echo "项目目录: $PROJECT_DIR" - echo "Media Server 安装目录: $INSTALL_DIR" - echo "Agent 安装目录: $AGENT_INSTALL_DIR" - echo "" - - # 检查 Media Server 编译产物 - if [ ! -f "$BUILD_DIR/media-server" ]; then - echo -e "${RED}错误: 未找到编译好的 media-server${NC}" - echo "请先编译项目:" - echo " cd $PROJECT_DIR" - echo " cmake -S . -B build -DCMAKE_BUILD_TYPE=Release" - echo " cmake --build build -j\$(nproc)" - exit 1 - fi - - # 检查插件 - if [ ! -d "$BUILD_DIR/plugins" ] || [ -z "$(ls -A $BUILD_DIR/plugins/*.so 2>/dev/null)" ]; then - echo -e "${YELLOW}警告: 未找到插件目录或插件为空${NC}" - read -p "是否继续? (y/N): " -r - [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ] && exit 1 - fi - - # 检查 Agent 编译产物(强制要求) - AGENT_SOURCE="" - if [ -f "$PROJECT_DIR/agent/rk3588-agent_linux_arm64" ]; then - AGENT_SOURCE="$PROJECT_DIR/agent/rk3588-agent_linux_arm64" - elif [ -f "$PROJECT_DIR/agent/cmd/rk3588-agent/rk3588-agent" ]; then - AGENT_SOURCE="$PROJECT_DIR/agent/cmd/rk3588-agent/rk3588-agent" - fi - - if [ -z "$AGENT_SOURCE" ]; then - echo -e "${RED}错误: 未找到编译好的 rk3588-agent${NC}" - echo "请先编译 Agent:" - echo " cd $PROJECT_DIR/agent" - echo " go build -o rk3588-agent_linux_arm64 ./cmd/rk3588-agent" - exit 1 - fi - - echo -e "${GREEN}✓${NC} 编译产物检查通过" - echo "" - - # 选择配置文件 - echo "请选择配置文件:" - echo " 1) test_cam1_face_det_rtsp_server.json (人脸检测)" - echo " 2) sample_cam1_native_rtsp_face.json (完整功能)" - echo " 3) test_cam1_face_det_recog_rtsp_server.json (人脸识别)" - echo " 4) sample_cam1.json (完整功能,需手动修复)" - echo "" - printf "请输入选项 [1-4,默认1]: " - read choice - choice=${choice:-1} - - case $choice in - 1) CONFIG_FILE="$PROJECT_DIR/configs/test_cam1_face_det_rtsp_server.json" ;; - 2) CONFIG_FILE="$PROJECT_DIR/configs/sample_cam1_native_rtsp_face.json" ;; - 3) CONFIG_FILE="$PROJECT_DIR/configs/test_cam1_face_det_recog_rtsp_server.json" ;; - 4) CONFIG_FILE="$PROJECT_DIR/configs/sample_cam1.json" ;; - *) CONFIG_FILE="$PROJECT_DIR/configs/test_cam1_face_det_rtsp_server.json" ;; - esac - - echo "" - - # 安装 Media Server - echo -e "${YELLOW}[1/3] 安装 Media Server...${NC}" - rm -rf "$INSTALL_DIR" - mkdir -p "$INSTALL_DIR/bin/plugins" - mkdir -p "$INSTALL_DIR/lib" - mkdir -p "$INSTALL_DIR/etc" - mkdir -p "$INSTALL_DIR/logs" - mkdir -p "$INSTALL_DIR/models" - mkdir -p "$INSTALL_DIR/web/hls" - - cp "$BUILD_DIR/media-server" "$INSTALL_DIR/bin/" - chmod +x "$INSTALL_DIR/bin/media-server" - - if [ -d "$BUILD_DIR/plugins" ]; then - cp "$BUILD_DIR"/plugins/*.so "$INSTALL_DIR/bin/plugins/" 2>/dev/null || true - fi - - if ls "$BUILD_DIR"/*.so 1> /dev/null 2>&1; then - cp "$BUILD_DIR"/*.so "$INSTALL_DIR/lib/" 2>/dev/null || true - fi - - # 复制模型 - if [ -d "$PROJECT_DIR/third_party/rknpu2/examples/rknn_yolov5_demo/model/RK3588" ]; then - cp "$PROJECT_DIR/third_party/rknpu2/examples/rknn_yolov5_demo/model/RK3588"/*.rknn "$INSTALL_DIR/models/" 2>/dev/null || true - fi - if [ -d "$PROJECT_DIR/models" ]; then - cp -r "$PROJECT_DIR/models"/* "$INSTALL_DIR/models/" 2>/dev/null || true - fi - - # 处理配置 - cp "$CONFIG_FILE" "$INSTALL_DIR/etc/media-server.json" - python3 << 'EOF' -import json, os -config_file = "/opt/rk3588-media-server/etc/media-server.json" -install_dir = "/opt/rk3588-media-server" -project_dir = os.path.expanduser("~/apps/OrangePi3588Media") - -def fix_path(path): - if not path or not isinstance(path, str): - return path - if 'third_party/rknpu2' in path: - return os.path.join(install_dir, 'models', os.path.basename(path)) - if path.startswith('./'): - if path.startswith('./web/'): - return os.path.join(install_dir, path[2:]) - elif path.startswith('./models/'): - return os.path.join(install_dir, path[2:]) - else: - abs_path = os.path.join(project_dir, path) - if os.path.exists(abs_path): - return abs_path - return os.path.join(install_dir, path[2:]) - return path - -try: - with open(config_file, 'r') as f: - config = json.load(f) - for graph in config.get('graphs', []): - nodes = graph.get('nodes', []) - edges = graph.get('edges', []) - node_ids = {node['id'] for node in nodes} - nodes_with_input = set() - for edge in edges: - if isinstance(edge, list) and len(edge) >= 2: - nodes_with_input.add(edge[1]) - for node in nodes: - if node.get('role') in ['filter', 'sink'] and node['id'] not in nodes_with_input: - if node.get('enable', True): - node['enable'] = False - if 'model_path' in node: - node['model_path'] = fix_path(node['model_path']) - if 'gallery' in node and 'path' in node['gallery']: - node['gallery']['path'] = fix_path(node['gallery']['path']) - if 'outputs' in node: - for output in node['outputs']: - if 'path' in output: - output['path'] = fix_path(output['path']) - with open(config_file, 'w') as f: - json.dump(config, f, indent=2) - print("配置处理完成") -except Exception as e: - print(f"配置处理出错: {e}") -EOF - echo -e "${GREEN}✓${NC} Media Server 安装完成" - - # 安装 Agent - echo -e "${YELLOW}[2/3] 安装 Agent...${NC}" - rm -rf "$AGENT_INSTALL_DIR" - mkdir -p "$AGENT_INSTALL_DIR" - mkdir -p "/var/lib/rk3588-agent" - - cp "$AGENT_SOURCE" "$AGENT_INSTALL_DIR/rk3588-agent" - chmod +x "$AGENT_INSTALL_DIR/rk3588-agent" - - # Agent 配置 - 禁用进程管理,改为监控模式 - cat > "$AGENT_INSTALL_DIR/agent.config.json" << 'AGENT_CONFIG' -{ - "agent": { - "listen": "0.0.0.0:9100", - "token": "CHANGE_ME", - "require_token_for_read": false, - "discovery_enable": true, - "discovery_port": 35688, - "device_name": "rk3588_cam1", - "device_id_path": "/var/lib/rk3588-agent/device_id", - "models_dir": "/opt/rk3588-media-server/models", - "max_upload_mb": 200, - "config_path": "/opt/rk3588-media-server/etc/media-server.json", - "media_server_process": { - "enable": false, - "exec_path": "", - "work_dir": "", - "configs_dir": "", - "pid_file": "", - "graceful_timeout_ms": 5000 - }, - "media_server_base_url": "http://127.0.0.1:9000", - "media_server_timeout_ms": 3000, - "media_server_retry": { "max_attempts": 3, "backoff_ms": [200, 500] } - } -} -AGENT_CONFIG - chown -R orangepi:orangepi "/var/lib/rk3588-agent" - chmod 755 "$AGENT_INSTALL_DIR" - echo -e "${GREEN}✓${NC} Agent 安装完成" - - # 安装服务 - echo -e "${YELLOW}[3/3] 安装 Systemd 服务...${NC}" - - # Media Server 独立服务 - cat > "$SERVICE_DIR/media-server.service" << 'EOF' -[Unit] -Description=RK3588 Media Server -After=network.target - -[Service] -Type=simple -User=root -WorkingDirectory=/opt/rk3588-media-server -ExecStart=/opt/rk3588-media-server/bin/media-server --config /opt/rk3588-media-server/etc/media-server.json -Restart=always -RestartSec=5 -StandardOutput=journal -StandardError=journal - -[Install] -WantedBy=multi-user.target -EOF - - # Agent 独立服务 - cat > "$SERVICE_DIR/rk3588-agent.service" << 'EOF' -[Unit] -Description=RK3588 Agent Service -After=network.target media-server.service -Wants=media-server.service - -[Service] -Type=simple -User=root -WorkingDirectory=/opt/rk3588-agent -ExecStart=/opt/rk3588-agent/rk3588-agent --config /opt/rk3588-agent/agent.config.json -Restart=always -RestartSec=5 -StandardOutput=journal -StandardError=journal - -[Install] -WantedBy=multi-user.target -EOF - - systemctl daemon-reload - - # 启动服务(独立运行) - systemctl enable media-server - systemctl start media-server - - systemctl enable rk3588-agent - systemctl start rk3588-agent - - echo -e "${GREEN}✓${NC} 服务已启动" - - # 完成 - echo "" - echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}" - echo -e "${GREEN}║ 安装完成! ║${NC}" - echo -e "${GREEN}╚════════════════════════════════════════════════════════════╝${NC}" - echo "" - echo "架构说明:" - echo " Media Server: 独立 systemd 服务(高可用,崩溃自动重启)" - echo " Agent: 独立 systemd 服务(监控状态,Web 管理)" - echo "" - echo "管理命令:" - echo " 状态: sudo ./manage.sh status" - echo " 日志: sudo journalctl -u media-server -f" - echo " 界面: http://<设备IP>:9100" -} - -cmd_status() { - echo -e "${BLUE}========== RK3588 Media Server 状态 ==========${NC}" - echo "" - - echo -e "${YELLOW}[系统信息]${NC}" - echo " 时间: $(date '+%Y-%m-%d %H:%M:%S')" - echo " 运行时间: $(uptime -p 2>/dev/null || uptime | awk -F',' '{print $1}')" - echo "" - - echo -e "${YELLOW}[NPU 负载]${NC}" - if [ -f /sys/kernel/debug/rknpu/load ]; then - cat /sys/kernel/debug/rknpu/load | sed 's/^/ /' - else - echo " NPU 信息不可用" - fi - echo "" - - echo -e "${YELLOW}[Media Server]${NC}" - if systemctl is-active --quiet media-server 2>/dev/null; then - echo -e " 状态: ${GREEN}● 运行中${NC}" - PID=$(systemctl show --property=MainPID --value media-server 2>/dev/null) - echo " PID: $PID" - if [ -n "$PID" ] && [ "$PID" != "0" ]; then - CPU_MEM=$(ps -p $PID -o %cpu,%mem --no-headers 2>/dev/null || echo "N/A") - echo " CPU/MEM: $CPU_MEM" - fi - echo " 端口:" - ss -tlnp 2>/dev/null | grep -E "(9000|8554|8555)" | head -3 | sed 's/^/ /' - else - echo -e " 状态: ${RED}○ 停止${NC}" - echo " 错误日志:" - journalctl -u media-server --no-pager -n 3 2>/dev/null | sed 's/^/ /' - fi - echo "" - - echo -e "${YELLOW}[RK3588 Agent]${NC}" - if systemctl is-active --quiet rk3588-agent 2>/dev/null; then - echo -e " 状态: ${GREEN}● 运行中${NC}" - PID=$(systemctl show --property=MainPID --value rk3588-agent 2>/dev/null) - if [ -n "$PID" ] && [ "$PID" != "0" ]; then - CPU_MEM=$(ps -p $PID -o %cpu,%mem --no-headers 2>/dev/null || echo "N/A") - echo " CPU/MEM: $CPU_MEM" - fi - echo " 管理界面: http://$(hostname -I | awk '{print $1}'):9100" - else - echo -e " 状态: ${RED}○ 停止${NC}" - fi - echo "" - - echo -e "${YELLOW}[最近日志 - Media Server]${NC}" - journalctl -u media-server --no-pager -n 5 2>/dev/null | tail -5 || echo " 无日志" - echo "" - - echo "常用命令:" - echo " 启动: sudo systemctl start media-server" - echo " 停止: sudo systemctl stop media-server" - echo " 重启: sudo systemctl restart media-server" - echo " 配置: sudo nano /opt/rk3588-media-server/etc/media-server.json" -} - -cmd_uninstall() { - echo -e "${YELLOW}========== RK3588 Media Server 卸载 ==========${NC}" - echo "" - - if [ "$(id -u)" -ne 0 ]; then - echo -e "${RED}错误: 请使用 sudo 运行${NC}" - exit 1 - fi - - read -p "确定要卸载并停止所有服务? (y/N): " -r - [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ] && echo "已取消" && exit 0 - - echo "[1/3] 停止服务..." - systemctl stop media-server rk3588-agent 2>/dev/null || true - systemctl disable media-server rk3588-agent 2>/dev/null || true - echo -e "${GREEN}✓${NC} 服务已停止" - - echo "[2/3] 删除服务文件..." - rm -f "$SERVICE_DIR/media-server.service" - rm -f "$SERVICE_DIR/rk3588-agent.service" - systemctl daemon-reload - echo -e "${GREEN}✓${NC} 服务文件已删除" - - echo "[3/3] 备份并清理..." - BACKUP_DIR="/root/rk3588-backup-$(date +%Y%m%d%H%M%S)" - mkdir -p "$BACKUP_DIR" - [ -f "$INSTALL_DIR/etc/media-server.json" ] && cp "$INSTALL_DIR/etc/media-server.json" "$BACKUP_DIR/" - [ -d "$INSTALL_DIR/models" ] && cp -r "$INSTALL_DIR/models" "$BACKUP_DIR/" 2>/dev/null || true - echo -e "${GREEN}✓${NC} 配置已备份到: $BACKUP_DIR" - - read -p "是否删除安装目录? (y/N): " -r - if [ "$REPLY" = "y" ] || [ "$REPLY" = "Y" ]; then - rm -rf "$INSTALL_DIR" "$AGENT_INSTALL_DIR" - echo -e "${GREEN}✓${NC} 目录已删除" - else - echo "保留目录,手动删除: sudo rm -rf $INSTALL_DIR $AGENT_INSTALL_DIR" - fi - - echo "" - echo -e "${GREEN}卸载完成${NC}" -} - -# ==================== 主入口 ==================== - -case "${1:-install}" in - install) - cmd_install - ;; - status) - cmd_status - ;; - uninstall) - cmd_uninstall - ;; - *) - echo "用法: sudo ./manage.sh [install|status|uninstall]" - echo "" - echo "命令:" - echo " install - 安装 Media Server 和 Agent (默认)" - echo " status - 查看运行状态" - echo " uninstall - 卸载服务" - exit 1 - ;; -esac diff --git a/scripts/ops.sh b/scripts/ops.sh new file mode 100644 index 0000000..5a4a27f --- /dev/null +++ b/scripts/ops.sh @@ -0,0 +1,158 @@ +#!/bin/bash +# RK3588 Media Server 运维脚本 +# 安装后位于 /opt/rk3588-media-server/script/ops.sh +# +# 用法: sudo ./ops.sh [status|start|stop|restart|logs|metrics] + +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' + +# 服务名称 +MEDIA_SERVICE="media-server" +AGENT_SERVICE="rk3588-agent" + +cmd_status() { + echo -e "${BLUE}========== RK3588 Media Server 状态 ==========${NC}" + echo "" + + # 系统信息 + echo -e "${CYAN}[系统信息]${NC}" + echo " 时间: $(date '+%Y-%m-%d %H:%M:%S')" + echo " 运行时间: $(uptime -p 2>/dev/null || uptime | awk -F',' '{print $1}')" + echo "" + + # NPU + echo -e "${CYAN}[NPU 负载]${NC}" + if [ -f /proc/rknpu/load ]; then + cat /proc/rknpu/load | sed 's/^/ /' + else + echo " NPU 信息不可用" + fi + echo "" + + # Media Server + echo -e "${CYAN}[Media Server]${NC}" + if systemctl is-active --quiet $MEDIA_SERVICE 2>/dev/null; then + echo -e " 状态: ${GREEN}● 运行中${NC}" + PID=$(systemctl show --property=MainPID --value $MEDIA_SERVICE 2>/dev/null) + echo " PID: $PID" + if [ -n "$PID" ] && [ "$PID" != "0" ]; then + CPU_MEM=$(ps -p $PID -o %cpu,%mem --no-headers 2>/dev/null || echo "N/A") + echo " CPU/MEM: $CPU_MEM" + fi + echo " 端口:" + ss -tlnp 2>/dev/null | grep -E "(9000|8555)" | head -3 | sed 's/^/ /' + else + echo -e " 状态: ${RED}○ 停止${NC}" + fi + echo "" + + # Agent + echo -e "${CYAN}[RK3588 Agent]${NC}" + if systemctl is-active --quiet $AGENT_SERVICE 2>/dev/null; then + echo -e " 状态: ${GREEN}● 运行中${NC}" + echo " 管理界面: http://$(hostname -I | awk '{print $1}'):9100" + else + echo -e " 状态: ${RED}○ 停止${NC}" + fi + echo "" + + # HLS 输出 + echo -e "${CYAN}[HLS 输出]${NC}" + if [ -d "/var/lib/rk3588-media-server/hls" ]; then + CHANNELS=$(find "/var/lib/rk3588-media-server/hls" -maxdepth 1 -type d 2>/dev/null | wc -l) + CHANNELS=$((CHANNELS - 1)) + echo " 通道数: $CHANNELS" + fi + echo "" + + # 存储使用 + echo -e "${CYAN}[存储使用]${NC}" + echo " HLS: $(du -sh /var/lib/rk3588-media-server/hls 2>/dev/null | cut -f1)" + echo " 日志: $(du -sh /var/lib/rk3588-media-server/logs 2>/dev/null | cut -f1)" + echo "" + + echo "命令帮助:" + echo " $(basename $0) status - 查看状态" + echo " $(basename $0) start - 启动服务" + echo " $(basename $0) stop - 停止服务" + echo " $(basename $0) logs - 查看日志" + echo " $(basename $0) metrics - 硬件监控" +} + +cmd_start() { + echo -e "${YELLOW}启动服务...${NC}" + systemctl start $MEDIA_SERVICE + systemctl start $AGENT_SERVICE + echo -e "${GREEN}✓${NC} 服务已启动" + echo " 管理界面: http://$(hostname -I | awk '{print $1}'):9100" +} + +cmd_stop() { + echo -e "${YELLOW}停止服务...${NC}" + systemctl stop $AGENT_SERVICE + systemctl stop $MEDIA_SERVICE + echo -e "${GREEN}✓${NC} 服务已停止" +} + +cmd_restart() { + echo -e "${YELLOW}重启服务...${NC}" + systemctl restart $MEDIA_SERVICE + systemctl restart $AGENT_SERVICE + echo -e "${GREEN}✓${NC} 服务已重启" +} + +cmd_logs() { + echo -e "${CYAN}查看日志 (按 Ctrl+C 退出)...${NC}" + echo "" + journalctl -u $MEDIA_SERVICE -f +} + +cmd_metrics() { + /opt/rk3588-media-server/script/monitor_hw.sh +} + +# 主入口 +case "${1:-status}" in + status) + cmd_status + ;; + start) + cmd_start + ;; + stop) + cmd_stop + ;; + restart) + cmd_restart + ;; + logs) + cmd_logs + ;; + metrics|monitor) + cmd_metrics + ;; + *) + echo "RK3588 Media Server 运维脚本" + echo "" + echo "用法: sudo $(basename $0) [命令]" + echo "" + echo "命令:" + echo " status 查看运行状态 (默认)" + echo " start 启动服务" + echo " stop 停止服务" + echo " restart 重启服务" + echo " logs 查看实时日志" + echo " metrics 查看硬件监控" + echo "" + echo "示例:" + echo " sudo $(basename $0) status" + echo " sudo $(basename $0) logs" + ;; +esac