safesight-edge/scripts/manage.sh

440 lines
15 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# RK3588 Media Server + Agent 统一管理脚本
# 用法: sudo ./install.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 [ "$EUID" -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 ""
# 检查编译产物
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): " -n 1 -r
echo
[[ ! $REPLY =~ ^[Yy]$ ]] && 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" ]; then
AGENT_SOURCE="$PROJECT_DIR/agent/cmd/rk3588-agent"
fi
if [ -z "$AGENT_SOURCE" ]; then
echo -e "${YELLOW}警告: 未找到编译好的 rk3588-agent${NC}"
echo " 如需 Agent 功能,请先编译:"
echo " cd $PROJECT_DIR/agent"
echo " GOOS=linux GOARCH=arm64 go build -o rk3588-agent_linux_arm64 ./cmd"
fi
echo -e "${GREEN}${NC} 编译产物检查通过"
echo ""
# 选择模式
echo "请选择运行模式:"
echo " 1) 独立模式 - Media Server 由 systemd 直接管理 (简单)"
echo " 2) Agent 模式 - Media Server 由 Agent 管理 (推荐,支持 Web 管理)"
echo ""
read -p "请输入选项 [1-2默认2]: " mode_choice
mode_choice=${mode_choice:-2}
USE_AGENT=false
if [ "$mode_choice" = "2" ] && [ -n "$AGENT_SOURCE" ]; then
USE_AGENT=true
elif [ "$mode_choice" = "2" ] && [ -z "$AGENT_SOURCE" ]; then
echo -e "${YELLOW}Agent 未编译,使用独立模式${NC}"
fi
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 ""
read -p "请输入选项 [1-4默认1]: " 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 ""
echo -e "运行模式: ${GREEN}$([ "$USE_AGENT" = true ] && echo "Agent 模式" || echo "独立模式")${NC}"
echo ""
# 安装 Media Server
echo -e "${YELLOW}[1/4] 安装 Media Server...${NC}"
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{bin/plugins,lib,etc,logs,models,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 = "$INSTALL_DIR/etc/media-server.json"
install_dir = "$INSTALL_DIR"
project_dir = "$PROJECT_DIR"
def fix_path(path):
if not path or not isinstance(path, str):
return 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
if [ "$USE_AGENT" = true ] && [ -n "$AGENT_SOURCE" ]; then
echo -e "${YELLOW}[2/4] 安装 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"
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": true,
"exec_path": "/opt/rk3588-media-server/bin/media-server",
"work_dir": "/opt/rk3588-media-server",
"configs_dir": "/opt/rk3588-media-server/etc",
"pid_file": "/var/run/rk3588sys-media-server.pid",
"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 安装完成"
fi
# 安装服务
echo -e "${YELLOW}[3/4] 安装 Systemd 服务...${NC}"
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
if [ "$USE_AGENT" = true ] && [ -n "$AGENT_SOURCE" ]; then
cat > "$SERVICE_DIR/rk3588-agent.service" << 'EOF'
[Unit]
Description=RK3588 Agent Service
After=network.target
[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
fi
systemctl daemon-reload
touch /var/run/rk3588sys-media-server.pid
chmod 666 /var/run/rk3588sys-media-server.pid
echo -e "${GREEN}${NC} 服务安装完成"
# 启动服务
echo -e "${YELLOW}[4/4] 启动服务...${NC}"
if [ "$USE_AGENT" = true ] && [ -n "$AGENT_SOURCE" ]; then
systemctl disable media-server 2>/dev/null || true
systemctl stop media-server 2>/dev/null || true
systemctl enable rk3588-agent
systemctl start rk3588-agent
else
systemctl enable media-server
systemctl start media-server
fi
echo -e "${GREEN}${NC} 服务已启动"
# 完成
echo ""
echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ 安装完成! ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
if [ "$USE_AGENT" = true ] && [ -n "$AGENT_SOURCE" ]; then
echo "管理命令:"
echo " 状态: sudo $0 status"
echo " 日志: sudo journalctl -u rk3588-agent -f"
echo " 界面: http://<设备IP>:9100"
else
echo "管理命令:"
echo " 状态: sudo $0 status"
echo " 日志: sudo journalctl -u media-server -f"
fi
}
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}"
fi
echo ""
if systemctl list-unit-files 2>/dev/null | grep -q rk3588-agent; then
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 ""
fi
echo -e "${YELLOW}[最近日志]${NC}"
if systemctl is-active --quiet rk3588-agent 2>/dev/null; then
journalctl -u rk3588-agent --no-pager -n 5 2>/dev/null | tail -5 || echo " 无日志"
else
journalctl -u media-server --no-pager -n 5 2>/dev/null | tail -5 || echo " 无日志"
fi
echo ""
echo "常用命令:"
echo " 重启: sudo systemctl restart media-server|rk3588-agent"
echo " 日志: sudo journalctl -u media-server|rk3588-agent -f"
echo " 配置: sudo nano /opt/rk3588-media-server/etc/media-server.json"
}
cmd_uninstall() {
echo -e "${YELLOW}========== RK3588 Media Server 卸载 ==========${NC}"
echo ""
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}错误: 请使用 sudo 运行${NC}"
exit 1
fi
read -p "确定要卸载并停止所有服务? (y/N): " -n 1 -r
echo
[[ ! $REPLY =~ ^[Yy]$ ]] && 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): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; 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