简化安装脚本和文档
This commit is contained in:
parent
ad0f7ccfa3
commit
3cd38e1ce3
@ -8,18 +8,18 @@
|
||||
"discovery_port": 35688,
|
||||
|
||||
"device_name": "cam1_strict_minio_alarm",
|
||||
"device_id_path": "./device_id",
|
||||
"device_id_path": "/var/lib/rk3588-agent/device_id",
|
||||
|
||||
"models_dir": "./models",
|
||||
"models_dir": "/opt/rk3588-media-server/models",
|
||||
"max_upload_mb": 200,
|
||||
|
||||
"config_path": "./configs/test_cam1_strict_minio_alarm_rtsp_server.json",
|
||||
"config_path": "/opt/rk3588-media-server/etc/media-server.json",
|
||||
"media_server_process": {
|
||||
"enable": true,
|
||||
"exec_path": "../build/media-server",
|
||||
"work_dir": "..",
|
||||
"configs_dir": "../configs",
|
||||
"pid_file": "./rk3588sys-media-server.pid",
|
||||
"exec_path": "/opt/rk3588-media-server/bin/systemctl-wrapper.sh",
|
||||
"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",
|
||||
|
||||
224
docs/deployment.md
Normal file
224
docs/deployment.md
Normal file
@ -0,0 +1,224 @@
|
||||
# RK3588 Media Server 部署指南
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 编译
|
||||
|
||||
在 RK3588 设备上编译:
|
||||
|
||||
```bash
|
||||
cd ~/apps/OrangePi3588Media
|
||||
|
||||
# 编译 Media Server
|
||||
mkdir -p build && cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||
make -j$(nproc)
|
||||
|
||||
# 编译 Agent(可选,用于 Web 管理)
|
||||
cd ../agent
|
||||
GOOS=linux GOARCH=arm64 go build -o rk3588-agent_linux_arm64 ./cmd
|
||||
```
|
||||
|
||||
### 2. 安装
|
||||
|
||||
使用统一脚本安装:
|
||||
|
||||
```bash
|
||||
cd ~/apps/OrangePi3588Media
|
||||
sudo ./scripts/manage.sh install
|
||||
```
|
||||
|
||||
安装过程会提示:
|
||||
- **运行模式**:
|
||||
- `独立模式` - Media Server 由 systemd 直接管理
|
||||
- `Agent 模式` - Media Server 由 Agent 管理(推荐,支持 Web 界面)
|
||||
- **配置文件**:
|
||||
- `test_cam1_face_det_rtsp_server.json` - 人脸检测(推荐)
|
||||
- `sample_cam1_native_rtsp_face.json` - 完整功能
|
||||
- `test_cam1_face_det_recog_rtsp_server.json` - 人脸识别
|
||||
- `sample_cam1.json` - 完整功能(需手动修复)
|
||||
|
||||
### 3. 查看状态
|
||||
|
||||
```bash
|
||||
sudo ./scripts/manage.sh status
|
||||
```
|
||||
|
||||
显示内容:
|
||||
- 系统运行时间
|
||||
- NPU 负载
|
||||
- Media Server 状态(PID、CPU/内存、端口)
|
||||
- Agent 状态(如果安装)
|
||||
- 最近日志
|
||||
|
||||
### 4. 卸载
|
||||
|
||||
```bash
|
||||
sudo ./scripts/manage.sh uninstall
|
||||
```
|
||||
|
||||
卸载会:
|
||||
1. 停止所有服务
|
||||
2. 删除 systemd 服务文件
|
||||
3. 自动备份配置文件和模型到 `/root/rk3588-backup-时间戳/`
|
||||
4. 提示是否删除安装目录
|
||||
|
||||
---
|
||||
|
||||
## 升级
|
||||
|
||||
升级步骤与安装相同,脚本会自动处理:
|
||||
|
||||
```bash
|
||||
cd ~/apps/OrangePi3588Media
|
||||
|
||||
# 1. 拉取最新代码(如果是 git 仓库)
|
||||
git pull
|
||||
|
||||
# 2. 重新编译
|
||||
mkdir -p build && cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||
make -j$(nproc)
|
||||
|
||||
# 3. 重新安装(会自动备份旧配置)
|
||||
cd ..
|
||||
sudo ./scripts/manage.sh install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 管理命令
|
||||
|
||||
### 独立模式
|
||||
|
||||
```bash
|
||||
# 启动/停止/重启
|
||||
sudo systemctl start media-server
|
||||
sudo systemctl stop media-server
|
||||
sudo systemctl restart media-server
|
||||
|
||||
# 查看状态
|
||||
sudo systemctl status media-server
|
||||
|
||||
# 查看日志
|
||||
sudo journalctl -u media-server -f
|
||||
```
|
||||
|
||||
### Agent 模式
|
||||
|
||||
```bash
|
||||
# 启动/停止/重启
|
||||
sudo systemctl start rk3588-agent
|
||||
sudo systemctl stop rk3588-agent
|
||||
sudo systemctl restart rk3588-agent
|
||||
|
||||
# 查看状态
|
||||
sudo systemctl status rk3588-agent
|
||||
|
||||
# 查看日志
|
||||
sudo journalctl -u rk3588-agent -f
|
||||
|
||||
# Web 管理界面
|
||||
http://<设备IP>:9100
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 配置修改
|
||||
|
||||
编辑配置文件:
|
||||
|
||||
```bash
|
||||
sudo nano /opt/rk3588-media-server/etc/media-server.json
|
||||
```
|
||||
|
||||
常用修改:
|
||||
- **修改 RTSP 输入源**:找到 `input_rtsp` 节点,修改 `url` 字段
|
||||
- **修改输出端口**:找到 `publish` 节点,修改 `port` 字段
|
||||
|
||||
修改后重启服务:
|
||||
|
||||
```bash
|
||||
# 独立模式
|
||||
sudo systemctl restart media-server
|
||||
|
||||
# Agent 模式
|
||||
sudo systemctl restart rk3588-agent
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 目录结构
|
||||
|
||||
安装后的目录结构:
|
||||
|
||||
```
|
||||
/opt/rk3588-media-server/
|
||||
├── bin/
|
||||
│ ├── media-server # 主程序
|
||||
│ └── plugins/ # 插件目录
|
||||
│ ├── libinput_rtsp.so
|
||||
│ ├── libai_yolo.so
|
||||
│ └── ...
|
||||
├── lib/ # 依赖库
|
||||
├── etc/
|
||||
│ └── media-server.json # 配置文件
|
||||
├── models/ # AI 模型
|
||||
├── logs/ # 日志目录
|
||||
└── web/hls/ # HLS 输出目录
|
||||
|
||||
/opt/rk3588-agent/ # Agent 安装目录(如果使用)
|
||||
├── rk3588-agent
|
||||
└── agent.config.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 服务无法启动
|
||||
|
||||
```bash
|
||||
# 查看详细错误
|
||||
sudo journalctl -u media-server -n 50
|
||||
# 或
|
||||
sudo journalctl -u rk3588-agent -n 50
|
||||
```
|
||||
|
||||
### 检查 NPU 是否正常
|
||||
|
||||
```bash
|
||||
# 查看 NPU 负载
|
||||
cat /sys/kernel/debug/rknpu/load
|
||||
|
||||
# 查看 NPU 驱动
|
||||
ls /dev/rknpu
|
||||
```
|
||||
|
||||
### RTSP 流无法播放
|
||||
|
||||
```bash
|
||||
# 在设备上测试播放
|
||||
ffplay rtsp://localhost:8555/live/cam1_face_det
|
||||
|
||||
# 测试输入源
|
||||
ffplay rtsp://输入源IP:端口/路径
|
||||
```
|
||||
|
||||
### 端口占用
|
||||
|
||||
```bash
|
||||
# 查看端口占用
|
||||
sudo ss -tlnp | grep -E "(8554|8555|9000|9100)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 系统要求
|
||||
|
||||
- **硬件**: Orange Pi 5 Plus (RK3588)
|
||||
- **系统**: Ubuntu 22.04 LTS (ARM64)
|
||||
- **依赖**:
|
||||
- RKNN Runtime
|
||||
- MPP (Media Process Platform)
|
||||
- FFmpeg (带 rkmpp 支持)
|
||||
@ -9,4 +9,13 @@ winget install Gyan.FFmpeg
|
||||
ffmpeg -version
|
||||
|
||||
- 推流到RTSP服务器(设置摄像头的分辨率为720P)
|
||||
ffmpeg -f dshow -rtbufsize 100M -video_size 1280x720 -framerate 30 -vcodec mjpeg -i video="4K AutoFocus Webcam" -c:v libx264 -preset ultrafast -pix_fmt yuv420p -f rtsp rtsp://localhost:8554/cam
|
||||
ffmpeg -f dshow -rtbufsize 100M -video_size 1280x720 -framerate 30 -vcodec mjpeg -i video="4K AutoFocus Webcam" -c:v libx264 -preset ultrafast -pix_fmt yuv420p -f rtsp rtsp://localhost:8554/cam
|
||||
|
||||
- 本地验证RTSP拉流正确
|
||||
ffplay rtsp://localhost:8554/cam
|
||||
|
||||
在3588上测试RTSP输出
|
||||
ffplay rtsp://localhost:8555/live/cam1_face_det
|
||||
|
||||
- 在 Windows 上用 VLC 播放处理后的流:
|
||||
rtsp://3588的IP:8555/live/cam1_face_det
|
||||
439
scripts/manage.sh
Executable file
439
scripts/manage.sh
Executable file
@ -0,0 +1,439 @@
|
||||
#!/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
|
||||
@ -1,150 +0,0 @@
|
||||
# RK3588 Media Server Systemd 部署脚本
|
||||
|
||||
本目录包含 RK3588 Media Server 的完整 systemd 部署方案,适用于 Orange Pi 5 Plus。
|
||||
|
||||
## 文件说明
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `install.sh` | **主安装脚本** - 一键安装media-server到systemd |
|
||||
| `uninstall.sh` | 卸载脚本 |
|
||||
| `status.sh` | 状态查看脚本 |
|
||||
| `media-server.service` | Systemd服务文件 |
|
||||
| `rk3588-agent.service` | Agent服务文件(可选) |
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 编译项目
|
||||
|
||||
确保已编译项目:
|
||||
|
||||
```bash
|
||||
cd /path/to/OrangePi3588Media
|
||||
cmake -S . -B build \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_TESTS=OFF \
|
||||
-DRK3588_ENABLE_FFMPEG=ON \
|
||||
-DRK3588_ENABLE_MPP=ON \
|
||||
-DRK3588_ENABLE_RGA=ON \
|
||||
-DRK3588_ENABLE_RKNN=ON
|
||||
cmake --build build -j$(nproc)
|
||||
```
|
||||
|
||||
### 2. 安装服务
|
||||
|
||||
```bash
|
||||
cd /path/to/OrangePi3588Media
|
||||
sudo ./scripts/systemd/install.sh
|
||||
```
|
||||
|
||||
安装脚本会:
|
||||
1. 自动选择配置文件(推荐用 `test_cam1_face_det_rtsp_server.json`)
|
||||
2. 复制主程序和**所有插件**到 `/opt/rk3588-media-server/`
|
||||
3. 复制模型文件
|
||||
4. **自动修复配置文件**(处理路径、禁用无输入的gate节点)
|
||||
5. 安装并启动systemd服务
|
||||
|
||||
### 3. 修改RTSP源地址
|
||||
|
||||
编辑配置文件,修改为你的RTSP源:
|
||||
|
||||
```bash
|
||||
sudo nano /opt/rk3588-media-server/etc/media-server.json
|
||||
```
|
||||
|
||||
找到 `"url": "rtsp://..."`,改成你的摄像头/推流地址。
|
||||
|
||||
### 4. 管理服务
|
||||
|
||||
```bash
|
||||
# 查看状态
|
||||
sudo ./scripts/systemd/status.sh
|
||||
|
||||
# 或手动管理
|
||||
sudo systemctl start media-server # 启动
|
||||
sudo systemctl stop media-server # 停止
|
||||
sudo systemctl restart media-server # 重启
|
||||
sudo systemctl status media-server # 查看状态
|
||||
|
||||
# 查看日志
|
||||
sudo journalctl -u media-server -f # 实时跟踪
|
||||
sudo journalctl -u media-server -n 100 # 最近100行
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
安装后的目录结构:
|
||||
|
||||
```
|
||||
/opt/rk3588-media-server/
|
||||
├── bin/
|
||||
│ ├── media-server # 主程序
|
||||
│ └── plugins/ # 插件目录
|
||||
│ ├── libinput_rtsp.so
|
||||
│ ├── libpublish.so
|
||||
│ ├── libpreprocess.so
|
||||
│ ├── libai_yolo.so
|
||||
│ └── ...
|
||||
├── lib/ # 依赖库
|
||||
├── etc/
|
||||
│ └── media-server.json # 配置文件
|
||||
├── models/ # 模型文件
|
||||
│ ├── yolov5s-640-640.rknn
|
||||
│ └── ...
|
||||
├── web/hls/ # HLS输出目录
|
||||
└── logs/ # 日志目录
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 服务启动失败
|
||||
|
||||
```bash
|
||||
# 1. 查看详细错误
|
||||
sudo journalctl -u media-server -n 50 --no-pager
|
||||
|
||||
# 2. 检查插件是否存在
|
||||
ls -la /opt/rk3588-media-server/bin/plugins/
|
||||
|
||||
# 3. 检查模型文件
|
||||
ls -la /opt/rk3588-media-server/models/
|
||||
|
||||
# 4. 直接运行看错误
|
||||
sudo /opt/rk3588-media-server/bin/media-server --config /opt/rk3588-media-server/etc/media-server.json
|
||||
```
|
||||
|
||||
### 常见错误
|
||||
|
||||
**错误1**: `Failed to load plugin 'input_rtsp': ... No such file or directory`
|
||||
- 原因:插件未复制
|
||||
- 解决:重新运行 `sudo ./scripts/systemd/install.sh`
|
||||
|
||||
**错误2**: `Node gate_face_cam1 role=filter must have input`
|
||||
- 原因:配置文件中的gate节点没有输入连接
|
||||
- 解决:安装时选择 `test_cam1_face_det_rtsp_server.json`(选项1),或手动禁用该节点
|
||||
|
||||
**错误3**: `Failed to open input: Connection refused`
|
||||
- 原因:RTSP源无法连接
|
||||
- 解决:检查RTSP源地址和端口
|
||||
|
||||
## 卸载
|
||||
|
||||
```bash
|
||||
sudo ./scripts/systemd/uninstall.sh
|
||||
```
|
||||
|
||||
会保留配置备份到 `/root/rk3588-backup-xxx/`。
|
||||
|
||||
## 更新配置
|
||||
|
||||
修改配置后重启服务:
|
||||
|
||||
```bash
|
||||
sudo nano /opt/rk3588-media-server/etc/media-server.json
|
||||
sudo systemctl restart media-server
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [命令.md](../../docs/命令.md) - 开发和部署命令参考
|
||||
- [API_Device_RemoteMgmt_InterfaceTable.md](../../API_Device_RemoteMgmt_InterfaceTable.md) - Agent API文档
|
||||
@ -1,271 +0,0 @@
|
||||
#!/bin/bash
|
||||
# RK3588 Media Server Systemd 安装脚本
|
||||
# 适用于 Orange Pi 5 Plus (RK3588)
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ RK3588 Media Server Systemd 安装脚本 ║${NC}"
|
||||
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
|
||||
# 检查 root 权限
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}错误: 请使用 sudo 运行此脚本${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 确定项目目录
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
BUILD_DIR="$PROJECT_DIR/build"
|
||||
INSTALL_DIR="/opt/rk3588-media-server"
|
||||
SERVICE_DIR="/etc/systemd/system"
|
||||
|
||||
echo "项目目录: $PROJECT_DIR"
|
||||
echo "安装目录: $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}"
|
||||
echo "请确保编译了插件: cmake --build build -j\$(nproc)"
|
||||
read -p "是否继续? (y/N): " -n 1 -r
|
||||
echo
|
||||
[[ ! $REPLY =~ ^[Yy]$ ]] && exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✓${NC} 编译产物检查通过"
|
||||
echo ""
|
||||
|
||||
# 选择配置文件
|
||||
echo "请选择配置文件:"
|
||||
echo ""
|
||||
echo " 1) test_cam1_face_det_rtsp_server.json (推荐 - 简单稳定,无gate问题)"
|
||||
echo " 2) sample_cam1_native_rtsp_face.json (完整功能 - YOLO+人脸检测+识别)"
|
||||
echo " 3) test_cam1_face_det_recog_rtsp_server.json (人脸识别)"
|
||||
echo " 4) sample_cam1.json (完整功能 - 需要手动禁用gate_face_cam1)"
|
||||
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"
|
||||
CONFIG_DESC="test_cam1_face_det_rtsp_server.json (简单稳定)"
|
||||
;;
|
||||
2)
|
||||
CONFIG_FILE="$PROJECT_DIR/configs/sample_cam1_native_rtsp_face.json"
|
||||
CONFIG_DESC="sample_cam1_native_rtsp_face.json (完整功能)"
|
||||
;;
|
||||
3)
|
||||
CONFIG_FILE="$PROJECT_DIR/configs/test_cam1_face_det_recog_rtsp_server.json"
|
||||
CONFIG_DESC="test_cam1_face_det_recog_rtsp_server.json (人脸识别)"
|
||||
;;
|
||||
4)
|
||||
CONFIG_FILE="$PROJECT_DIR/configs/sample_cam1.json"
|
||||
CONFIG_DESC="sample_cam1.json (完整功能,需手动修复)"
|
||||
;;
|
||||
*)
|
||||
echo "无效选项,使用默认配置"
|
||||
CONFIG_FILE="$PROJECT_DIR/configs/test_cam1_face_det_rtsp_server.json"
|
||||
CONFIG_DESC="test_cam1_face_det_rtsp_server.json (默认)"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo -e "选择配置: ${GREEN}$CONFIG_DESC${NC}"
|
||||
echo ""
|
||||
|
||||
# 开始安装
|
||||
echo -e "${YELLOW}[1/6] 创建安装目录...${NC}"
|
||||
mkdir -p "$INSTALL_DIR"/{bin/plugins,lib,etc,logs,models,web/hls}
|
||||
echo -e "${GREEN}✓${NC} 目录创建完成"
|
||||
|
||||
echo -e "${YELLOW}[2/6] 复制主程序和插件...${NC}"
|
||||
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
|
||||
echo -e "${GREEN}✓${NC} 插件复制完成 ($(ls $INSTALL_DIR/bin/plugins/*.so 2>/dev/null | wc -l) 个)"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ 未找到插件目录${NC}"
|
||||
fi
|
||||
|
||||
# 复制依赖库
|
||||
if ls "$BUILD_DIR"/*.so 1> /dev/null 2>&1; then
|
||||
cp "$BUILD_DIR"/*.so "$INSTALL_DIR/lib/" 2>/dev/null || true
|
||||
echo -e "${GREEN}✓${NC} 依赖库复制完成"
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}[3/6] 复制模型文件...${NC}"
|
||||
# 复制第三方模型
|
||||
if [ -d "$PROJECT_DIR/third_party/rknpu2/examples/rknn_yolov5_demo/model/RK3588" ]; then
|
||||
mkdir -p "$INSTALL_DIR/models"
|
||||
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
|
||||
echo -e "${GREEN}✓${NC} 模型文件复制完成"
|
||||
|
||||
echo -e "${YELLOW}[4/6] 处理配置文件...${NC}"
|
||||
# 复制并修复配置
|
||||
cp "$CONFIG_FILE" "$INSTALL_DIR/etc/media-server.json"
|
||||
|
||||
# 使用 Python 修复配置文件中的路径
|
||||
python3 << EOF
|
||||
import json
|
||||
import 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('./'):
|
||||
# web/ 路径指向安装目录
|
||||
if path.startswith('./web/'):
|
||||
return os.path.join(install_dir, path[2:])
|
||||
# models/ 路径指向安装目录
|
||||
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)
|
||||
|
||||
# 修复 sample_cam1.json 中的 gate_face_cam1 问题
|
||||
for graph in config.get('graphs', []):
|
||||
nodes = graph.get('nodes', [])
|
||||
edges = graph.get('edges', [])
|
||||
|
||||
# 找到所有节点ID
|
||||
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])
|
||||
|
||||
# 禁用没有输入的 filter/sink 节点
|
||||
for node in nodes:
|
||||
if node.get('role') in ['filter', 'sink'] and node['id'] not in nodes_with_input:
|
||||
if node.get('enable', True):
|
||||
print(f"禁用无输入节点: {node['id']} (role={node.get('role')})")
|
||||
node['enable'] = False
|
||||
|
||||
# 修复所有路径
|
||||
for node in nodes:
|
||||
if 'model_path' in node:
|
||||
old = node['model_path']
|
||||
node['model_path'] = fix_path(old)
|
||||
if old != node['model_path']:
|
||||
print(f"修复路径: {old} -> {node['model_path']}")
|
||||
|
||||
if 'gallery' in node and 'path' in node['gallery']:
|
||||
old = node['gallery']['path']
|
||||
node['gallery']['path'] = fix_path(old)
|
||||
if old != node['gallery']['path']:
|
||||
print(f"修复路径: {old} -> {node['gallery']['path']}")
|
||||
|
||||
if 'outputs' in node:
|
||||
for output in node['outputs']:
|
||||
if 'path' in output:
|
||||
old = output['path']
|
||||
output['path'] = fix_path(old)
|
||||
if old != output['path']:
|
||||
print(f"修复路径: {old} -> {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} 配置文件处理完成"
|
||||
echo " 配置文件: $INSTALL_DIR/etc/media-server.json"
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}[5/6] 安装 Systemd 服务...${NC}"
|
||||
cp "$SCRIPT_DIR/media-server.service" "$SERVICE_DIR/"
|
||||
|
||||
# 重新加载 systemd
|
||||
systemctl daemon-reload
|
||||
systemctl enable media-server
|
||||
|
||||
echo -e "${GREEN}✓${NC} Systemd 服务安装完成"
|
||||
|
||||
echo -e "${YELLOW}[6/6] 验证安装...${NC}"
|
||||
echo ""
|
||||
echo "安装内容:"
|
||||
echo " 主程序: $(ls -lh $INSTALL_DIR/bin/media-server | awk '{print $5, $9}')"
|
||||
echo " 插件数: $(ls $INSTALL_DIR/bin/plugins/*.so 2>/dev/null | wc -l) 个"
|
||||
echo " 模型数: $(ls $INSTALL_DIR/models/*.rknn 2>/dev/null | wc -l) 个"
|
||||
echo " 配置: $INSTALL_DIR/etc/media-server.json"
|
||||
echo ""
|
||||
|
||||
echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ 安装完成! ║${NC}"
|
||||
echo -e "${GREEN}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo "管理命令:"
|
||||
echo " 启动: sudo systemctl start media-server"
|
||||
echo " 停止: sudo systemctl stop media-server"
|
||||
echo " 状态: sudo systemctl status media-server"
|
||||
echo " 日志: sudo journalctl -u media-server -f"
|
||||
echo ""
|
||||
echo "重要提示:"
|
||||
echo " 1. 编辑配置修改RTSP源地址:"
|
||||
echo " sudo nano $INSTALL_DIR/etc/media-server.json"
|
||||
echo ""
|
||||
echo " 2. 确保模型文件存在:"
|
||||
echo " ls $INSTALL_DIR/models/"
|
||||
echo ""
|
||||
echo " 3. 首次启动前检查RTSP源是否可访问"
|
||||
echo ""
|
||||
|
||||
read -p "是否立即启动服务? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
systemctl start media-server
|
||||
sleep 2
|
||||
if systemctl is-active --quiet media-server; then
|
||||
echo -e "${GREEN}✓${NC} 服务启动成功!"
|
||||
systemctl status media-server --no-pager
|
||||
else
|
||||
echo -e "${RED}✗${NC} 服务启动失败,查看日志:"
|
||||
echo " sudo journalctl -u media-server -n 20"
|
||||
fi
|
||||
fi
|
||||
@ -1,40 +0,0 @@
|
||||
[Unit]
|
||||
Description=RK3588 Agent (Management API)
|
||||
Documentation=https://github.com/your-org/OrangePi3588Media
|
||||
After=network-online.target media-server.service
|
||||
Wants=network-online.target
|
||||
# 如果 agent 依赖 media-server,取消下面这行的注释
|
||||
# Requires=media-server.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Group=root
|
||||
WorkingDirectory=/opt/rk3588-agent
|
||||
ExecStart=/opt/rk3588-agent/rk3588-agent --config /opt/rk3588-agent/agent.config.json
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=mixed
|
||||
KillSignal=SIGTERM
|
||||
TimeoutStopSec=30
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
StartLimitInterval=60s
|
||||
StartLimitBurst=5
|
||||
|
||||
# 资源限制
|
||||
LimitNOFILE=65535
|
||||
LimitNPROC=4096
|
||||
|
||||
# 日志输出
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=rk3588-agent
|
||||
|
||||
# 安全设置
|
||||
# NoNewPrivileges=true
|
||||
# ProtectSystem=strict
|
||||
# ProtectHome=true
|
||||
# ReadWritePaths=/opt/rk3588-agent
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@ -1,81 +0,0 @@
|
||||
#!/bin/bash
|
||||
# RK3588 Media Server & Agent 状态查看脚本
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
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 ""
|
||||
|
||||
# NPU 负载
|
||||
echo -e "${YELLOW}[NPU 负载]${NC}"
|
||||
if [ -f /sys/kernel/debug/rknpu/load ]; then
|
||||
cat /sys/kernel/debug/rknpu/load | while read line; do
|
||||
echo " $line"
|
||||
done
|
||||
else
|
||||
echo " NPU 信息不可用"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Media Server 状态
|
||||
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 | while read line; do
|
||||
echo " $line"
|
||||
done
|
||||
else
|
||||
echo -e " 状态: ${RED}○ 停止${NC}"
|
||||
echo " 最后错误:"
|
||||
journalctl -u media-server --no-pager -n 3 2>/dev/null | tail -3 | sed 's/^/ /'
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Agent 状态(如果安装了)
|
||||
if systemctl list-unit-files | 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
|
||||
else
|
||||
echo -e " 状态: ${RED}○ 停止${NC}"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 日志摘要
|
||||
echo -e "${YELLOW}[最近日志 - Media Server]${NC}"
|
||||
journalctl -u media-server --no-pager -n 5 2>/dev/null | tail -5 || echo " 无日志"
|
||||
echo ""
|
||||
|
||||
# 操作提示
|
||||
echo -e "${YELLOW}[管理命令]${NC}"
|
||||
echo " 重启服务: sudo systemctl restart media-server"
|
||||
echo " 查看日志: sudo journalctl -u media-server -f"
|
||||
echo " 查看NPU: sudo watch -n 1 cat /sys/kernel/debug/rknpu/load"
|
||||
echo " 编辑配置: sudo nano /opt/rk3588-media-server/etc/media-server.json"
|
||||
@ -1,78 +0,0 @@
|
||||
#!/bin/bash
|
||||
# RK3588 Media Server 卸载脚本
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
INSTALL_DIR="${1:-/opt/rk3588-media-server}"
|
||||
|
||||
echo -e "${YELLOW}========== RK3588 Media Server 卸载 ==========${NC}"
|
||||
echo "安装目录: $INSTALL_DIR"
|
||||
echo ""
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}错误: 请使用 sudo 运行${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 确认
|
||||
read -p "确定要卸载并停止所有服务? 数据将保留。 (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "卸载已取消"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 停止服务
|
||||
echo "[1/4] 停止服务..."
|
||||
systemctl stop media-server 2>/dev/null || true
|
||||
systemctl disable media-server 2>/dev/null || true
|
||||
echo -e "${GREEN}✓${NC} 服务已停止并禁用"
|
||||
|
||||
# 删除服务文件
|
||||
echo "[2/4] 删除服务文件..."
|
||||
rm -f /etc/systemd/system/media-server.service
|
||||
systemctl daemon-reload
|
||||
echo -e "${GREEN}✓${NC} 服务文件已删除"
|
||||
|
||||
# 备份配置
|
||||
echo "[3/4] 备份配置..."
|
||||
BACKUP_DIR="/root/rk3588-backup-$(date +%Y%m%d%H%M%S)"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
if [ -f "$INSTALL_DIR/etc/media-server.json" ]; then
|
||||
cp "$INSTALL_DIR/etc/media-server.json" "$BACKUP_DIR/"
|
||||
echo " 已备份配置文件"
|
||||
fi
|
||||
|
||||
if [ -d "$INSTALL_DIR/models" ]; then
|
||||
cp -r "$INSTALL_DIR/models" "$BACKUP_DIR/" 2>/dev/null || true
|
||||
echo " 已备份模型文件"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✓${NC} 配置已备份到: $BACKUP_DIR"
|
||||
|
||||
# 提示删除文件
|
||||
echo "[4/4] 清理文件..."
|
||||
echo ""
|
||||
echo "以下目录需要手动删除(如需完全清理):"
|
||||
echo " $INSTALL_DIR/"
|
||||
echo ""
|
||||
|
||||
read -p "是否删除这些目录? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
rm -rf "$INSTALL_DIR"
|
||||
echo -e "${GREEN}✓${NC} 目录已删除"
|
||||
else
|
||||
echo "保留目录,如需删除请手动执行:"
|
||||
echo " sudo rm -rf $INSTALL_DIR"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}卸载完成${NC}"
|
||||
echo "备份位置: $BACKUP_DIR"
|
||||
Loading…
Reference in New Issue
Block a user