install.sh 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/bin/bash
  2. # RTSP Multi-View 目标机安装脚本 (RK3568 / aarch64)
  3. set -e
  4. if [ "$EUID" -ne 0 ]; then
  5. echo "请以 root 运行: sudo ./install.sh"
  6. exit 1
  7. fi
  8. SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
  9. INSTALL_BIN="/usr/local/bin"
  10. INSTALL_CONF="/etc/rtsp_multi_view"
  11. INSTALL_DATA="/opt/rtsp_multi_view"
  12. SERVICE="/etc/systemd/system/rtsp_multi_view.service"
  13. echo "== [1/6] 检查运行依赖 =="
  14. # 生产镜像 (RK3568 Debian bullseye) 已预装全部运行依赖:
  15. # gstreamer 全家桶 + gstreamer1.0-rockchip1(mppvideodec) + librga2 + librockchip-mpp1
  16. # + libdrm/libpng/libjpeg/libfreetype/libcurl/glib 等。
  17. # 因此正常情况无需联网。这里只做检查: 齐全则完全离线安装;
  18. # 万一某台机器缺东西, 依次尝试随包离线 deps/ -> 联网 apt 补救。
  19. missing=""
  20. # 用 ldd 直接检查随包二进制能否解析 (比 ldconfig 可靠, 不受 PATH 影响)
  21. if command -v ldd >/dev/null 2>&1; then
  22. miss_libs=$(ldd "$SCRIPT_DIR/bin/rtsp_multi_view" 2>/dev/null | awk '/not found/ {print $1}')
  23. [ -n "$miss_libs" ] && missing="$missing $miss_libs"
  24. fi
  25. # GStreamer 元件 (dlopen 加载, ldd 查不到)
  26. if command -v gst-inspect-1.0 >/dev/null 2>&1; then
  27. for el in rtspsrc parsebin appsink mppvideodec h265parse; do
  28. gst-inspect-1.0 "$el" >/dev/null 2>&1 || missing="$missing gst:$el"
  29. done
  30. fi
  31. if [ -z "$missing" ]; then
  32. echo " OK: 运行依赖齐全, 无需联网。"
  33. elif ls "$SCRIPT_DIR/deps/"*.deb >/dev/null 2>&1; then
  34. echo " 缺少:$missing"
  35. echo " 使用随包离线依赖 deps/ 安装..."
  36. dpkg -i "$SCRIPT_DIR/deps/"*.deb 2>/dev/null || true
  37. elif command -v apt-get >/dev/null 2>&1 && timeout 3 bash -c 'echo > /dev/tcp/deb.debian.org/80' 2>/dev/null; then
  38. echo " 缺少:$missing"
  39. echo " 尝试联网安装补救..."
  40. apt-get update -qq 2>/dev/null
  41. apt-get install -y --no-install-recommends \
  42. libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \
  43. gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \
  44. librga2 librockchip-mpp1 \
  45. libdrm2 libpng16-16 libjpeg62-turbo libfreetype6 libcurl4 \
  46. 2>/dev/null || echo " WARN: 联网安装部分失败"
  47. else
  48. echo " 缺少:$missing"
  49. echo " WARN: 缺少依赖且无离线包、无网络。请确认镜像是否完整, 程序可能无法启动。"
  50. fi
  51. echo "== [2/6] 安装二进制 =="
  52. cp "$SCRIPT_DIR/bin/rtsp_multi_view" "$INSTALL_BIN/"
  53. cp "$SCRIPT_DIR/bin/plc_sim" "$INSTALL_BIN/"
  54. chmod +x "$INSTALL_BIN/rtsp_multi_view" "$INSTALL_BIN/plc_sim"
  55. echo "== [3/6] 安装脚本 =="
  56. cp "$SCRIPT_DIR/scripts/auto_reboot.sh" "$INSTALL_BIN/"
  57. chmod +x "$INSTALL_BIN/auto_reboot.sh"
  58. echo "== [4/6] 安装配置 =="
  59. mkdir -p "$INSTALL_CONF"
  60. if [ -f "$INSTALL_CONF/channels.conf" ]; then
  61. cp "$INSTALL_CONF/channels.conf" "$INSTALL_CONF/channels.conf.bak.$(date +%Y%m%d_%H%M%S)"
  62. echo " 旧配置已备份: $(ls -t "$INSTALL_CONF"/channels.conf.bak.* | head -1)"
  63. fi
  64. cp "$SCRIPT_DIR/conf/channels.conf" "$INSTALL_CONF/"
  65. echo " 已安装最新配置: $INSTALL_CONF/channels.conf"
  66. echo "== [5/6] 安装数据文件 =="
  67. mkdir -p "$INSTALL_DATA"
  68. [ -d "$SCRIPT_DIR/models" ] && cp -r "$SCRIPT_DIR/models" "$INSTALL_DATA/"
  69. [ -f "$SCRIPT_DIR/fltk.png" ] && cp "$SCRIPT_DIR/fltk.png" "$INSTALL_DATA/"
  70. cp "$SCRIPT_DIR/scripts/plc_server.py" "$INSTALL_DATA/"
  71. cp "$SCRIPT_DIR/scripts/plc_server.sh" "$INSTALL_DATA/"
  72. cp "$SCRIPT_DIR/scripts/auto_reboot.sh" "$INSTALL_DATA/"
  73. chmod +x "$INSTALL_DATA/plc_server.sh" "$INSTALL_DATA/auto_reboot.sh"
  74. echo "== [5.5/6] 安装中文字体 =="
  75. if [ -d "$SCRIPT_DIR/fonts" ] && ls "$SCRIPT_DIR/fonts/"* >/dev/null 2>&1; then
  76. mkdir -p /usr/share/fonts/truetype/wqy
  77. cp "$SCRIPT_DIR/fonts/"* /usr/share/fonts/truetype/wqy/
  78. chmod 644 /usr/share/fonts/truetype/wqy/*
  79. command -v fc-cache >/dev/null 2>&1 && fc-cache -f >/dev/null 2>&1 || true
  80. echo " 字体已安装到 /usr/share/fonts/truetype/wqy/"
  81. else
  82. echo " WARN: 未随包提供字体,标题栏文字可能不显示(程序已支持自动回退)"
  83. fi
  84. echo "== [6/6] 创建 systemd 服务 =="
  85. cat > "$SERVICE" << 'UNIT'
  86. [Unit]
  87. Description=RTSP Multi-View Display
  88. After=network.target
  89. [Service]
  90. Type=simple
  91. WorkingDirectory=/opt/rtsp_multi_view
  92. ExecStart=/usr/local/bin/rtsp_multi_view -c /etc/rtsp_multi_view/channels.conf
  93. Restart=always
  94. RestartSec=3
  95. Nice=-10
  96. SupplementaryGroups=video
  97. Environment=LD_LIBRARY_PATH=/usr/lib/aarch64-linux-gnu:/usr/local/lib
  98. # 注意:不要加 DeviceAllow。systemd 一旦有 DeviceAllow= 就会启用设备白名单,
  99. # 且 /dev/dri rw 这种"目录路径"匹配不到 /dev/dri/card0,会导致 open 失败
  100. # 直接表现为 "Failed to create display"、服务反复重启(手动运行却正常)。
  101. [Install]
  102. WantedBy=multi-user.target
  103. UNIT
  104. systemctl daemon-reload
  105. systemctl enable rtsp_multi_view
  106. echo " 主服务已启用 (自动重启由程序内置 [auto_reboot] 调度,无需独立服务)"
  107. echo "== [6.5/6] 配置静态 IP =="
  108. # 现场通常没有路由器/DHCP。给 eth0 追加一个固定地址 192.168.100.245/24,
  109. # 并保留 DHCP:有路由器时照常拿自动地址,没路由器时也有这个固定地址。
  110. # 这些板子的 eth0 由 NetworkManager 管理,必须用 nmcli 写连接;
  111. # /etc/network/interfaces 在 NM 托管时不生效(ifupdown 未接管 eth0)。
  112. STATIC_IFACE="eth0"
  113. STATIC_CIDR="192.168.100.245/24"
  114. if command -v nmcli >/dev/null 2>&1 && nmcli -t -g RUNNING general 2>/dev/null | grep -qx running; then
  115. CON="$(nmcli -t -f GENERAL.CONNECTION dev show "$STATIC_IFACE" 2>/dev/null | head -1 | cut -d: -f2-)"
  116. if [ -n "$CON" ] && [ "$CON" != "--" ]; then
  117. nmcli con mod "$CON" +ipv4.addresses "$STATIC_CIDR" >/dev/null 2>&1 || true
  118. nmcli dev reapply "$STATIC_IFACE" >/dev/null 2>&1 || nmcli con up "$CON" >/dev/null 2>&1 || true
  119. echo " 已在 $STATIC_IFACE 追加 $STATIC_CIDR (保留 DHCP, 连接 \"$CON\")"
  120. else
  121. nmcli con add type ethernet ifname "$STATIC_IFACE" con-name rtsp-static \
  122. ipv4.method auto >/dev/null 2>&1 || true
  123. nmcli con mod rtsp-static +ipv4.addresses "$STATIC_CIDR" >/dev/null 2>&1 || true
  124. nmcli con up rtsp-static >/dev/null 2>&1 || true
  125. echo " 已创建连接 rtsp-static: $STATIC_IFACE += $STATIC_CIDR (保留 DHCP)"
  126. fi
  127. else
  128. echo " WARN: 未检测到运行中的 NetworkManager, 跳过静态 IP 设置"
  129. fi
  130. echo ""
  131. echo "=========================================="
  132. echo " 安装完成!"
  133. echo "=========================================="
  134. echo ""
  135. echo " 启动主服务: systemctl start rtsp_multi_view"
  136. echo " 查看状态: systemctl status rtsp_multi_view"
  137. echo " 查看日志: journalctl -u rtsp_multi_view -f"
  138. echo " PLC 调试: cd $INSTALL_DATA && ./plc_server.sh"
  139. echo " 自动重启: 编辑 $INSTALL_CONF/channels.conf 的 [auto_reboot] 段"
  140. echo ""
  141. echo " 配置文件: $INSTALL_CONF/channels.conf"
  142. echo " 数据目录: $INSTALL_DATA/"
  143. echo ""