OrangePi3588Media/scripts/manage.sh

417 lines
14 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 统一管理脚本
# 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