#!/bin/bash # RTSP Multi-View 目标机安装脚本 (RK3568 / aarch64) set -e if [ "$EUID" -ne 0 ]; then echo "请以 root 运行: sudo ./install.sh" exit 1 fi SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" INSTALL_BIN="/usr/local/bin" INSTALL_CONF="/etc/rtsp_multi_view" INSTALL_DATA="/opt/rtsp_multi_view" SERVICE="/etc/systemd/system/rtsp_multi_view.service" echo "== [1/6] 检查运行依赖 ==" # 生产镜像 (RK3568 Debian bullseye) 已预装全部运行依赖: # gstreamer 全家桶 + gstreamer1.0-rockchip1(mppvideodec) + librga2 + librockchip-mpp1 # + libdrm/libpng/libjpeg/libfreetype/libcurl/glib 等。 # 因此正常情况无需联网。这里只做检查: 齐全则完全离线安装; # 万一某台机器缺东西, 依次尝试随包离线 deps/ -> 联网 apt 补救。 missing="" # 用 ldd 直接检查随包二进制能否解析 (比 ldconfig 可靠, 不受 PATH 影响) if command -v ldd >/dev/null 2>&1; then miss_libs=$(ldd "$SCRIPT_DIR/bin/rtsp_multi_view" 2>/dev/null | awk '/not found/ {print $1}') [ -n "$miss_libs" ] && missing="$missing $miss_libs" fi # GStreamer 元件 (dlopen 加载, ldd 查不到) if command -v gst-inspect-1.0 >/dev/null 2>&1; then for el in rtspsrc parsebin appsink mppvideodec h265parse; do gst-inspect-1.0 "$el" >/dev/null 2>&1 || missing="$missing gst:$el" done fi if [ -z "$missing" ]; then echo " OK: 运行依赖齐全, 无需联网。" elif ls "$SCRIPT_DIR/deps/"*.deb >/dev/null 2>&1; then echo " 缺少:$missing" echo " 使用随包离线依赖 deps/ 安装..." dpkg -i "$SCRIPT_DIR/deps/"*.deb 2>/dev/null || true elif command -v apt-get >/dev/null 2>&1 && timeout 3 bash -c 'echo > /dev/tcp/deb.debian.org/80' 2>/dev/null; then echo " 缺少:$missing" echo " 尝试联网安装补救..." apt-get update -qq 2>/dev/null apt-get install -y --no-install-recommends \ libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \ gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \ librga2 librockchip-mpp1 \ libdrm2 libpng16-16 libjpeg62-turbo libfreetype6 libcurl4 \ 2>/dev/null || echo " WARN: 联网安装部分失败" else echo " 缺少:$missing" echo " WARN: 缺少依赖且无离线包、无网络。请确认镜像是否完整, 程序可能无法启动。" fi echo "== [2/6] 安装二进制 ==" cp "$SCRIPT_DIR/bin/rtsp_multi_view" "$INSTALL_BIN/" cp "$SCRIPT_DIR/bin/plc_sim" "$INSTALL_BIN/" chmod +x "$INSTALL_BIN/rtsp_multi_view" "$INSTALL_BIN/plc_sim" echo "== [3/6] 安装脚本 ==" cp "$SCRIPT_DIR/scripts/auto_reboot.sh" "$INSTALL_BIN/" chmod +x "$INSTALL_BIN/auto_reboot.sh" echo "== [4/6] 安装配置 ==" mkdir -p "$INSTALL_CONF" if [ -f "$INSTALL_CONF/channels.conf" ]; then cp "$INSTALL_CONF/channels.conf" "$INSTALL_CONF/channels.conf.bak.$(date +%Y%m%d_%H%M%S)" echo " 旧配置已备份: $(ls -t "$INSTALL_CONF"/channels.conf.bak.* | head -1)" fi cp "$SCRIPT_DIR/conf/channels.conf" "$INSTALL_CONF/" echo " 已安装最新配置: $INSTALL_CONF/channels.conf" echo "== [5/6] 安装数据文件 ==" mkdir -p "$INSTALL_DATA" [ -d "$SCRIPT_DIR/models" ] && cp -r "$SCRIPT_DIR/models" "$INSTALL_DATA/" [ -f "$SCRIPT_DIR/fltk.png" ] && cp "$SCRIPT_DIR/fltk.png" "$INSTALL_DATA/" cp "$SCRIPT_DIR/scripts/plc_server.py" "$INSTALL_DATA/" cp "$SCRIPT_DIR/scripts/plc_server.sh" "$INSTALL_DATA/" cp "$SCRIPT_DIR/scripts/auto_reboot.sh" "$INSTALL_DATA/" chmod +x "$INSTALL_DATA/plc_server.sh" "$INSTALL_DATA/auto_reboot.sh" echo "== [5.5/6] 安装中文字体 ==" if [ -d "$SCRIPT_DIR/fonts" ] && ls "$SCRIPT_DIR/fonts/"* >/dev/null 2>&1; then mkdir -p /usr/share/fonts/truetype/wqy cp "$SCRIPT_DIR/fonts/"* /usr/share/fonts/truetype/wqy/ chmod 644 /usr/share/fonts/truetype/wqy/* command -v fc-cache >/dev/null 2>&1 && fc-cache -f >/dev/null 2>&1 || true echo " 字体已安装到 /usr/share/fonts/truetype/wqy/" else echo " WARN: 未随包提供字体,标题栏文字可能不显示(程序已支持自动回退)" fi echo "== [6/6] 创建 systemd 服务 ==" cat > "$SERVICE" << 'UNIT' [Unit] Description=RTSP Multi-View Display After=network.target [Service] Type=simple WorkingDirectory=/opt/rtsp_multi_view ExecStart=/usr/local/bin/rtsp_multi_view -c /etc/rtsp_multi_view/channels.conf Restart=always RestartSec=3 Nice=-10 SupplementaryGroups=video Environment=LD_LIBRARY_PATH=/usr/lib/aarch64-linux-gnu:/usr/local/lib # 注意:不要加 DeviceAllow。systemd 一旦有 DeviceAllow= 就会启用设备白名单, # 且 /dev/dri rw 这种"目录路径"匹配不到 /dev/dri/card0,会导致 open 失败 # 直接表现为 "Failed to create display"、服务反复重启(手动运行却正常)。 [Install] WantedBy=multi-user.target UNIT systemctl daemon-reload systemctl enable rtsp_multi_view echo " 主服务已启用 (自动重启由程序内置 [auto_reboot] 调度,无需独立服务)" echo "== [6.5/6] 配置静态 IP ==" # 现场通常没有路由器/DHCP。给 eth0 追加一个固定地址 192.168.100.245/24, # 并保留 DHCP:有路由器时照常拿自动地址,没路由器时也有这个固定地址。 # 这些板子的 eth0 由 NetworkManager 管理,必须用 nmcli 写连接; # /etc/network/interfaces 在 NM 托管时不生效(ifupdown 未接管 eth0)。 STATIC_IFACE="eth0" STATIC_CIDR="192.168.100.245/24" if command -v nmcli >/dev/null 2>&1 && nmcli -t -g RUNNING general 2>/dev/null | grep -qx running; then CON="$(nmcli -t -f GENERAL.CONNECTION dev show "$STATIC_IFACE" 2>/dev/null | head -1 | cut -d: -f2-)" if [ -n "$CON" ] && [ "$CON" != "--" ]; then nmcli con mod "$CON" +ipv4.addresses "$STATIC_CIDR" >/dev/null 2>&1 || true nmcli dev reapply "$STATIC_IFACE" >/dev/null 2>&1 || nmcli con up "$CON" >/dev/null 2>&1 || true echo " 已在 $STATIC_IFACE 追加 $STATIC_CIDR (保留 DHCP, 连接 \"$CON\")" else nmcli con add type ethernet ifname "$STATIC_IFACE" con-name rtsp-static \ ipv4.method auto >/dev/null 2>&1 || true nmcli con mod rtsp-static +ipv4.addresses "$STATIC_CIDR" >/dev/null 2>&1 || true nmcli con up rtsp-static >/dev/null 2>&1 || true echo " 已创建连接 rtsp-static: $STATIC_IFACE += $STATIC_CIDR (保留 DHCP)" fi else echo " WARN: 未检测到运行中的 NetworkManager, 跳过静态 IP 设置" fi echo "" echo "==========================================" echo " 安装完成!" echo "==========================================" echo "" echo " 启动主服务: systemctl start rtsp_multi_view" echo " 查看状态: systemctl status rtsp_multi_view" echo " 查看日志: journalctl -u rtsp_multi_view -f" echo " PLC 调试: cd $INSTALL_DATA && ./plc_server.sh" echo " 自动重启: 编辑 $INSTALL_CONF/channels.conf 的 [auto_reboot] 段" echo "" echo " 配置文件: $INSTALL_CONF/channels.conf" echo " 数据目录: $INSTALL_DATA/" echo ""