Files
SecMPS/owl_zlmediakit/部署手册.md
2026-05-15 23:22:48 +08:00

57 KiB
Raw Blame History

GoWVP (Owl) + ZLMediaKit 飞腾S5000 + 统信UOS20 离线部署手册

文档版本: v1.2 生成日期: 2026-04-29
适用环境: 飞腾S5000C (ARM64) + 统信UOS20服务器版(1070) + 离线网络
目标系统: ARM64 (aarch64) / ARMv8.2


更新记录

版本号 更新人 更新日期/时间 更新内容
v1.0 浮浮酱 2026-04-29 初始版本,生成完整离线部署手册
v1.1 浮浮酱 2026-04-29 1. 更新 Docker 版本建议25.0.5 → 27.5.1/28.5.2/29.4.1
2. 新增 8.7 ARM64 稳定性问题深度分析(含 Issue #3466/#3202/#2728/#2043
3. 新增附录 FARM64 架构问题速查表
v1.2 浮浮酱 2026-04-29 1. 明确 Intel/x86_64 笔记本可通过 Docker Desktop 完成全套 ARM64 准备工作
2. 4.2.1/4.2.3 节添加 --platform linux/arm64 参数说明和 docker save --platform 注意事项
3. 4.4 节添加通过 ARM64 Docker 容器下载系统依赖包的替代方案(无需额外 ARM 服务器)

目录

一级导航

  1. 文档概述
  2. 环境说明
  3. 资源清单
  4. 联网笔记本准备工作
  5. 生产环境服务器部署
  6. 配置联动
  7. 验证步骤
  8. 常见问题排查
  9. 附录

二级导航

一、文档概述

二、环境说明

三、资源清单

四、联网笔记本准备工作

五、生产环境服务器部署

六、配置联动

七、验证步骤

八、常见问题排查

九、附录


一、文档概述

本手册指导您在完全离线的生产环境中,于飞腾S5000C ARM64服务器统信UOS20操作系统上完成以下部署

  • GoWVP (Owl): GB28181-2022 标准视频监控管理平台
  • ZLMediaKit: 高性能流媒体服务器
  • 联动配置: 让 Owl 通过 HTTP API 和 WebHook 调用 ZLMediaKit 的流媒体能力

1.1 部署架构

┌─────────────────────────────────────────────────────────────┐
│                     监控设备 (摄像头/NVR)                      │
│              ┌──────────────┐  ┌──────────────┐              │
│              │   GB28181    │  │   ONVIF      │              │
│              │   协议接入    │  │   协议接入    │              │
│              └──────┬───────┘  └──────┬───────┘              │
└─────────────────────┼─────────────────┼──────────────────────┘
                      │                 │
                      ▼                 ▼
┌─────────────────────────────────────────────────────────────┐
│                    统信UOS20 服务器 (ARM64)                   │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              Docker 容器运行时                        │   │
│  │  ┌─────────────────┐    ┌───────────────────────┐   │   │
│  │  │   GoWVP (Owl)   │◄──►│     ZLMediaKit        │   │   │
│  │  │   容器          │API │     流媒体容器         │   │   │
│  │  │                 │Hook│                       │   │   │
│  │  │  - GB28181 SIP  │    │  - RTMP/RTSP/HLS      │   │   │
│  │  │  - Web管理界面   │    │  - WebRTC/FLV         │   │   │
│  │  │  - 设备管理      │    │  - 录像/转码          │   │   │
│  │  │  - AI检测(YOLO)  │    │                       │   │   │
│  │  └─────────────────┘    └───────────────────────┘   │   │
│  └─────────────────────────────────────────────────────┘   │
│                      数据持久化卷                            │
│         (./data 挂载到容器内的 /opt/media/bin/configs)        │
└─────────────────────────────────────────────────────────────┘

1.2 部署方式选择

方案 说明 推荐度 适用场景
方案A: Docker Compose 融合部署 一个docker-compose.yml同时启动owl+ZLMediaKit 本手册推荐,最简单
方案B: Docker 分离部署 两个独立容器通过Docker网络通信 需要独立升级/维护时
方案C: 二进制直接部署 不依赖Docker直接运行可执行文件 服务器资源极度受限时

本手册以方案ADocker Compose 融合部署)为主同时提供方案B和C的备用说明。


二、环境说明

2.1 硬件环境

项目 规格
CPU 飞腾腾云 S5000C (Phytium S5000C)
指令集 ARMv8.2 (64位兼容aarch64)
核心数 16核 / 32核 / 64核 (根据采购型号)
主频 2.1GHz (64核版) / 2.3GHz (32/16核版)
内存 建议 >= 16GB DDR5
存储 建议 >= 500GB SSD (用于录像存储)
网络 千兆以太网 (用于GB28181流媒体和Web管理)

2.2 软件环境

项目 规格
操作系统 统信UOS服务器版 V20 (1070)
镜像文件名 uos-server-20-military-1070-20251016-arm64.iso
内核版本 kernel-4.19 (默认) / kernel-5.10 (可选)
包管理器 需确认:可能是 yum(A/E版本) 或 apt(D版本)
架构 aarch64 / ARM64

2.3 统信UOS版本确认方法

生产环境服务器上执行以下命令确认系统版本:

# 查看操作系统详细信息
cat /etc/os-release

# 查看系统版本标记
cat /etc/system-release 2>/dev/null || cat /etc/centos-release 2>/dev/null || cat /etc/debian_version 2>/dev/null

# 查看包管理器类型
which apt-get && echo "使用 apt (Debian系)"
which yum && echo "使用 yum (RHEL系)"

判断依据:

  • 如果看到 AnolisopenEuleruel20 等字样 -> A/E版本使用 yum
  • 如果看到 DebianUbuntu 等字样 -> D版本使用 apt
  • 1070军事版通常基于龙蜥/欧拉,大概率使用 yum/dnf

2.4 网络环境

环境 网络状态 用途
联网笔记本 可访问互联网 下载镜像、准备部署包
生产服务器 完全离线 运行部署命令、启动服务
传输介质 U盘/移动硬盘/内网FTP 将文件从笔记本传到服务器

三、资源清单

本章节列出部署过程中所需的所有文件,包括文件名、下载地址、用途说明及使用步骤链接。

3.1 Docker 镜像文件

注意: Docker镜像需要在安装了Docker的联网机器上拉取后导出,无法直接通过浏览器下载。

序号 文件名 下载方式 用途说明 使用章节
1 zlmediakit-master-arm64.tar docker pull zlmediakit/zlmediakit:master + docker save ZLMediaKit 官方ARM64镜像 4.2节
2 gowvp-latest-arm64.tar docker pull gospace/gowvp:latest + docker save GoWVP (Owl) 官方ARM64镜像 4.2节
3 registry-2.tar docker pull registry:2 + docker save Docker私有镜像仓库可选方便内网分发 4.2节

3.2 可执行文件与源码包

序号 文件名 下载地址 用途说明 使用章节
1 owl_linux_arm64.tar.gz https://github.com/gowvp/owl/releases/download/v1.3.0/owl_linux_arm64.tar.gz GoWVP v1.3.0 ARM64预编译二进制 5.5节 / 备用方案C
2 ZLMediaKit-master.zip https://github.com/ZLMediaKit/ZLMediaKit/archive/refs/heads/master.zip ZLMediaKit 最新源码(含子模块需单独初始化) 5.4节 / 备用方案C
3 docker-27.5.1.tgz https://download.docker.com/linux/static/stable/aarch64/docker-27.5.1.tgz Docker CE v27.5.1 ARM64离线安装包推荐 5.2节
3b docker-28.5.2.tgz https://download.docker.com/linux/static/stable/aarch64/docker-28.5.2.tgz Docker CE v28.5.2 ARM64离线安装包较新 5.2节
3c docker-29.4.1.tgz https://download.docker.com/linux/static/stable/aarch64/docker-29.4.1.tgz Docker CE v29.4.1 ARM64离线安装包最新 5.2节
4 docker-compose-linux-aarch64 https://github.com/docker/compose/releases/download/v2.29.1/docker-compose-linux-aarch64 Docker Compose v2.29.1 ARM64二进制 5.2节
5 libsrtp-2.5.0.tar.gz https://github.com/cisco/libsrtp/archive/refs/tags/v2.5.0.tar.gz SRTP库源码WebRTC功能必需版本必须严格为2.5.0 附录B

3.3 系统依赖包(需根据包管理器类型准备)

3.3.1 若系统使用 yum (A/E版本 - 龙蜥/欧拉)

序号 包名 下载方式 用途说明 使用章节
1 docker-ce-*.aarch64.rpm yumdownloader --resolve docker-ce Docker引擎 5.2节
2 docker-ce-cli-*.aarch64.rpm yumdownloader --resolve docker-ce-cli Docker客户端 5.2节
3 containerd.io-*.aarch64.rpm yumdownloader --resolve containerd.io 容器运行时 5.2节
4 openssl-devel-*.aarch64.rpm yumdownloader --resolve openssl-devel SSL开发库ZLMediaKit必需 附录B
5 libssl3-*.aarch64.rpm 系统ISO或 yumdownloader SSL运行时库 5.4节

3.3.2 若系统使用 apt (D版本 - Debian)

序号 包名 下载方式 用途说明 使用章节
1 docker.io_*.deb apt-get download docker.io Docker引擎 5.2节
2 libssl-dev_*.deb apt-get download libssl-dev SSL开发库 附录B
3 openssl_*.deb apt-get download openssl SSL工具 5.4节
4 ca-certificates_*.deb apt-get download ca-certificates CA证书 5.2节

3.4 配置文件与脚本

序号 文件名 来源 用途说明 使用章节
1 docker-compose.yml 本手册 4.5节 Docker Compose 融合部署配置 5.3节
2 config.ini ZLMediaKit官方模板修改 ZLMediaKit 配置文件 5.4节
3 install-docker.sh 本手册 5.2节 Docker离线安装脚本 5.2节
4 setup.sh 本手册 5.6节 一键初始化脚本 5.6节
5 verify.sh 本手册 7.1节 部署验证脚本 七、验证步骤

四、联网笔记本准备工作

本章节所有操作在可联网的笔记本/工作站上执行,操作系统可以是 Windows 10/11、macOS 或 Linux。

4.1 安装 Docker Desktop

如果您的笔记本还没有安装Docker请先安装

Windows 用户:

  1. 访问 https://www.docker.com/products/docker-desktop/
  2. 下载并安装 Docker Desktop for Windows
  3. 启动 Docker Desktop确保左下角显示 "Docker Engine is running"
  4. 打开 PowerShell 或 CMD验证
    docker --version
    docker-compose --version
    

Linux 用户Ubuntu/Debian

# 安装Docker
sudo apt-get update
sudo apt-get install -y docker.io docker-compose

# 启动Docker
sudo systemctl start docker
sudo systemctl enable docker

# 验证
docker --version
docker-compose --version

4.2 拉取并导出 Docker 镜像

4.2.1 拉取 ARM64 镜像

💡 Intel/AMD 笔记本用户注意:即使您的笔记本是 x86_64 架构,也可以通过 Docker Desktop 内置的 QEMU 模拟拉取 ARM64 镜像。Docker Desktop 4.34+ 默认使用 containerd image store支持多架构镜像无需额外配置

# 拉取 ZLMediaKit 官方镜像(显式指定 ARM64 平台)
docker pull --platform linux/arm64 zlmediakit/zlmediakit:master

# 拉取 GoWVP (Owl) 官方镜像
docker pull --platform linux/arm64 gospace/gowvp:latest

# (可选)拉取私有镜像仓库,方便内网多台服务器分发
docker pull --platform linux/arm64 registry:2

为什么加 --platform linux/arm64

  • 在 x86_64 笔记本上Docker 默认会拉取与宿主架构匹配的镜像amd64
  • 显式指定 --platform linux/arm64 确保拉取的是 ARM64 版本
  • 这是必须的,否则导出的是 x86_64 镜像,无法在飞腾 S5000C 上运行

国内网络加速(如拉取缓慢):

# 使用华为云镜像加速 ZLMediaKit
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/zlmediakit/zlmediakit:master-linuxarm64
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/zlmediakit/zlmediakit:master-linuxarm64 zlmediakit/zlmediakit:master

# 使用阿里云镜像加速 GoWVP
docker pull registry.cn-shanghai.aliyuncs.com/ixugo/homenvr:latest
docker tag registry.cn-shanghai.aliyuncs.com/ixugo/homenvr:latest gospace/gowvp:latest

4.2.2 验证镜像架构

# 确认镜像是 ARM64 架构
docker inspect zlmediakit/zlmediakit:master | grep Architecture
# 预期输出: "Architecture": "arm64"

docker inspect gospace/gowvp:latest | grep Architecture
# 预期输出: "Architecture": "arm64"

4.2.3 导出镜像为 tar 文件

⚠️ 关键注意事项Docker Desktop 4.34+ 默认使用 containerd image store。在 containerd 模式下,直接 docker save 非宿主架构ARM64镜像可能会报错no suitable export target found。必须使用 --platform 参数显式指定。

# 创建输出目录
mkdir -p /owl_zlmediakit/docker-images

# 导出 ZLMediaKit 镜像(约 300-700MB
# 必须加 --platform linux/arm64否则在 containerd store 下会失败
docker save --platform linux/arm64 \
  -o /owl_zlmediakit/docker-images/zlmediakit-master-arm64.tar \
  zlmediakit/zlmediakit:master

# 导出 GoWVP 镜像(约 200MB
docker save --platform linux/arm64 \
  -o /owl_zlmediakit/docker-images/gowvp-latest-arm64.tar \
  gospace/gowvp:latest

# (可选)导出私有仓库镜像
docker save --platform linux/arm64 \
  -o /owl_zlmediakit/docker-images/registry-2.tar \
  registry:2

# 验证导出文件
ls -lh /owl_zlmediakit/docker-images/

如果 docker save --platform 仍报错,可尝试以下替代方案:

# 方案A使用 docker build 创建一个可保存的临时镜像
docker build --platform linux/arm64 --tag temp-zlm-arm64 -f - . <<'EOF'
FROM zlmediakit/zlmediakit:master
EOF
docker save -o zlmediakit-master-arm64.tar temp-zlm-arm64

# 方案B在 Docker Desktop 设置中临时切换回 Classic image store
# Settings → Features in development → 关闭 "Use containerd for pulling and storing images"
# 切换后重启 Docker Desktop重新拉取镜像后再保存

速度提示: 如果笔记本是 x86_64 (Intel/AMD) 架构Docker Desktop 通过 QEMU 模拟拉取和导出 ARM64 镜像,速度比原生慢 10-50 倍。如果笔记本也是 ARM64如 MacBook M1/M2/M3则速度快得多。

4.3 下载源码包与二进制文件

4.3.1 下载 GoWVP 预编译二进制(备用方案)

mkdir -p /owl_zlmediakit/source-packages

# 下载 GoWVP v1.3.0 ARM64 预编译包
wget -O /owl_zlmediakit/source-packages/owl_linux_arm64.tar.gz \
  https://github.com/gowvp/owl/releases/download/v1.3.0/owl_linux_arm64.tar.gz

# 验证下载
ls -lh /owl_zlmediakit/source-packages/owl_linux_arm64.tar.gz

4.3.2 下载 ZLMediaKit 源码(备用方案)

# 下载 ZLMediaKit 最新源码
wget -O /owl_zlmediakit/source-packages/ZLMediaKit-master.zip \
  https://github.com/ZLMediaKit/ZLMediaKit/archive/refs/heads/master.zip

# 或者使用 git 克隆(推荐,包含完整历史)
git clone --depth 1 https://github.com/ZLMediaKit/ZLMediaKit.git /tmp/ZLMediaKit
cd /tmp/ZLMediaKit
git submodule update --init --recursive
tar czf /owl_zlmediakit/source-packages/ZLMediaKit-master-with-submodules.tar.gz .

# 验证
ls -lh /owl_zlmediakit/source-packages/ZLMediaKit*

4.3.3 下载 Docker 离线安装包ARM64

mkdir -p /owl_zlmediakit/deb-packages

# ============================================
# Docker 版本选择建议:
# - 稳妥首选: 27.5.1 (最后一个传统存储驱动稳定版,国产系统兼容性最佳)
# - 平衡之选: 28.5.2 (较新但已过磨合期)
# - 追新: 29.4.1 (最新版但默认启用containerd image store)
# ============================================

# 下载 Docker CE ARM64 静态二进制包(推荐 27.5.1
wget -O /owl_zlmediakit/deb-packages/docker-27.5.1.tgz \
  https://download.docker.com/linux/static/stable/aarch64/docker-27.5.1.tgz

# 或者下载较新版本(如需)
# wget -O /owl_zlmediakit/deb-packages/docker-28.5.2.tgz \
#   https://download.docker.com/linux/static/stable/aarch64/docker-28.5.2.tgz

# 下载 Docker Compose ARM64
wget -O /owl_zlmediakit/deb-packages/docker-compose-linux-aarch64 \
  https://github.com/docker/compose/releases/download/v2.29.1/docker-compose-linux-aarch64

# 验证
ls -lh /owl_zlmediakit/deb-packages/

4.3.4 下载 WebRTC 依赖(如需源码编译)

# 下载 libsrtp 2.5.0版本必须严格匹配v2.3.0和v2.6+都有兼容性问题)
wget -O /owl_zlmediakit/source-packages/libsrtp-2.5.0.tar.gz \
  https://github.com/cisco/libsrtp/archive/refs/tags/v2.5.0.tar.gz

# 验证
ls -lh /owl_zlmediakit/source-packages/libsrtp-2.5.0.tar.gz

4.4 准备系统依赖包(离线安装用)

4.4.1 若目标系统使用 yum (A/E版本)

方案 A在 Intel 笔记本上通过 ARM64 Docker 容器下载(推荐,无需额外 ARM 服务器)

💡 原理:在 x86_64 笔记本上运行 --platform linux/arm64 的容器,容器内的 yumdownloader 会自动下载 ARM64 架构的 rpm 包。

# 1. 启动 ARM64 CentOS/Anolis 容器(通过 QEMU 模拟运行)
docker run -it --name arm64-yum-downloader --platform linux/arm64 \
  -v /owl_zlmediakit/deb-packages/yum-deps:/output \
  arm64v8/centos:8 bash

# 2. 在容器内下载 ARM64 版本的 rpm 包
yum install -y yum-utils
yumdownloader --resolve --destdir=/output \
  docker-ce docker-ce-cli containerd.io wget curl vim net-tools telnet

# 3. 退出容器,包已在 /owl_zlmediakit/deb-packages/yum-deps/ 中
exit

# 4. 清理容器
docker rm arm64-yum-downloader

方案 B在另一台联网的 ARM64 服务器上执行(传统方式)

如果您有另一台同版本联网的统信UOS/龙蜥/欧拉 ARM64 机器:

mkdir -p /owl_zlmediakit/deb-packages/yum-deps

# 安装 yum-utils用于下载依赖
sudo yum install -y yum-utils

# 下载 Docker 及相关依赖(包括所有依赖项)
yumdownloader --resolve --destdir=/owl_zlmediakit/deb-packages/yum-deps \
  docker-ce docker-ce-cli containerd.io

# 下载常用工具
yumdownloader --resolve --destdir=/owl_zlmediakit/deb-packages/yum-deps \
  wget curl vim net-tools telnet

# 验证
ls -lh /owl_zlmediakit/deb-packages/yum-deps/

4.4.2 若目标系统使用 apt (D版本)

方案 A在 Intel 笔记本上通过 ARM64 Docker 容器下载(推荐,无需额外 ARM 服务器)

💡 原理:在 x86_64 笔记本上运行 --platform linux/arm64 的 Debian 容器,容器内的 apt-get download 会自动下载 ARM64 架构的 deb 包。

# 1. 启动 ARM64 Debian 容器(通过 QEMU 模拟运行)
docker run -it --name arm64-apt-downloader --platform linux/arm64 \
  -v /owl_zlmediakit/deb-packages/apt-deps:/output \
  arm64v8/debian:bookworm-slim bash

# 2. 在容器内下载 ARM64 版本的 deb 包
apt-get update
apt-get download docker.io libssl-dev openssl ca-certificates
apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests \
  --no-conflicts --no-breaks --no-replaces --no-enhances docker.io | grep "^\w")
apt-get download wget curl vim net-tools telnet

# 复制到挂载目录
cp /var/cache/apt/archives/*.deb /output/

# 3. 退出容器,包已在 /owl_zlmediakit/deb-packages/apt-deps/ 中
exit

# 4. 清理容器
docker rm arm64-apt-downloader

方案 B在另一台联网的 ARM64 服务器上执行(传统方式)

如果您有另一台同版本联网的 Debian/Ubuntu ARM64 机器:

mkdir -p /owl_zlmediakit/deb-packages/apt-deps

# 更新包缓存
sudo apt-get update

# 下载 Docker 及相关依赖
cd /owl_zlmediakit/deb-packages/apt-deps
apt-get download docker.io
apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts \
  --no-breaks --no-replaces --no-enhances docker.io | grep "^\w")

# 下载常用工具
apt-get download wget curl vim net-tools telnet

# 验证
ls -lh /owl_zlmediakit/deb-packages/apt-deps/

4.5 准备配置文件

4.5.1 创建 docker-compose.yml

创建文件 /owl_zlmediakit/configs/docker-compose.yml

version: '3.8'

services:
  # ZLMediaKit 流媒体服务
  zlmediakit:
    image: zlmediakit/zlmediakit:master
    container_name: zlmediakit
    restart: always
    privileged: true
    network_mode: host
    volumes:
      - ./data/zlm-config.ini:/opt/media/conf/config.ini:ro
      - ./data/record:/opt/media/bin/www/record
      - ./data/log:/opt/media/bin/log
    environment:
      - TZ=Asia/Shanghai
    logging:
      driver: json-file
      options:
        max-size: "100m"
        max-file: "3"

  # GoWVP (Owl) 管理平台
  gowvp:
    image: gospace/gowvp:latest
    container_name: gowvp
    restart: always
    network_mode: host
    depends_on:
      - zlmediakit
    volumes:
      - ./data/gowvp-configs:/opt/media/bin/configs
      - ./data/record:/opt/media/bin/www/record
    environment:
      - TZ=Asia/Shanghai
      - GOWVP_ZLM_HOST=192.168.3.108    # 必须使用服务器实际IP不能填127.0.0.1
      - GOWVP_ZLM_PORT=80
      - GOWVP_ZLM_SECRET=035c73f7-bb6b-4889-a715-d9eb2d1925cc
    logging:
      driver: json-file
      options:
        max-size: "100m"
        max-file: "3"

4.5.2 创建 ZLMediaKit 配置文件

创建文件 /owl_zlmediakit/configs/zlm-config.ini

; ZLMediaKit 配置文件
; 针对 ARM64 + 离线环境优化

[api]
apiDebug=1
secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc
snapRoot=./www/snap/
defaultSnap=./www/logo.png
downloadRoot=./www

[ffmpeg]
bin=/usr/bin/ffmpeg
cmd=%s -re -i %s -c copy -f flv %s
snap=%s -i %s -y -f mjpeg -t 0.001 %s

[general]
enableVhost=0
flowThreshold=1024
maxStreamWaitMS=15000
streamNoneReaderDelayMS=20000
resetWhenRePlay=1
mergeWriteMS=0
mediaServerId=owl-zlm-server-01
wait_add_track_ms=3000
wait_track_ready_ms=10000

[hls]
fileBufSize=65536
segDur=2
segNum=3
segRetain=5
broadcastRecordTs=0
fastRegister=0

[hook]
enable=1
on_publish=https://127.0.0.1:15123/api/v1/hook/on_publish
on_play=https://127.0.0.1:15123/api/v1/hook/on_play
on_stream_not_found=https://127.0.0.1:15123/api/v1/hook/on_stream_not_found
on_server_started=https://127.0.0.1:15123/api/v1/hook/on_server_started
on_server_keepalive=https://127.0.0.1:15123/api/v1/hook/on_server_keepalive
on_send_rtp_stopped=https://127.0.0.1:15123/api/v1/hook/on_send_rtp_stopped
on_rtp_server_timeout=https://127.0.0.1:15123/api/v1/hook/on_rtp_server_timeout
admin_params=secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc
timeoutSec=20

[http]
charSet=utf-8
keepAliveSecond=30
maxReqSize=40960
notFound=<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>您访问的资源不存在!</h1></center><hr><center>ZLMediaKit-4.0</center></body></html>
port=80
rootPath=./www
sendBufSize=65536
sslport=443
virtualPath=

[multicast]
addrMax=239.255.255.255
addrMin=239.0.0.0
udpTTL=64

[record]
appName=record
fastStart=0
fileBufSize=65536
fileSecond=3600
sampleMS=500

[rtmp]
directProxy=1
enhanced=0
handshakeSecond=15
keepAliveSecond=15
port=1935

[rtp]
audioMtuSize=600
h264_stap_a=1
opus_rtp_ext=0
rtpMaxSize=10
videoMtuSize=1400

[rtp_proxy]
dumpDir=
port=10000
port_range=30000-30500

[rtsp]
authBasic=0
directProxy=1
handshakeSecond=15
keepAliveSecond=15
port=554
sslport=332

[srt]
latencyMul=4
pktBufSize=8192
port=9000
timeoutSec=5

[rtc]
# WebRTC外部IP必须设置为服务器实际IP否则外部浏览器无法播放
externIP=192.168.3.108
port=8000
tcpPort=8000
rembBitRate=0

[shell]
maxReqSize=1024
port=9000

[cluster]
origin_url=
retry_count=3
timeout_sec=15

4.6 打包所有文件

# 在联网笔记本上,将所有文件打包到一个压缩包中,方便传输
cd /owl_zlmediakit
tar czf owl-zlmediakit-offline-package-arm64.tar.gz \
  docker-images/ \
  deb-packages/ \
  source-packages/ \
  configs/ \
  scripts/ \
  部署手册.md

# 验证打包结果
ls -lh owl-zlmediakit-offline-package-arm64.tar.gz

传输到生产环境: 将上述压缩包通过 U盘/移动硬盘/内网FTP 拷贝到生产服务器的 /opt/ 目录下。


五、生产环境服务器部署

本章节所有操作在生产环境服务器上执行服务器为飞腾S5000C ARM64 + 统信UOS20处于离线状态。

5.1 确认系统版本和包管理器

# 1. 查看操作系统信息
cat /etc/os-release

# 2. 确认包管理器
which yum && echo "使用 yum" || echo "未安装 yum"
which apt-get && echo "使用 apt" || echo "未安装 apt-get"

# 3. 确认架构
uname -m
# 预期输出: aarch64

# 4. 确认CPU信息
cat /proc/cpuinfo | grep "model name" | head -1

5.2 安装 Docker离线

5.2.1 解压部署包

# 创建安装目录
mkdir -p /opt/owl-zlmediakit
cd /opt/owl-zlmediakit

# 解压部署包(从联网笔记本拷贝过来的)
tar xzf /path/to/owl-zlmediakit-offline-package-arm64.tar.gz

# 查看目录结构
ls -la

5.2.2 运行 Docker 安装脚本

cd /opt/owl-zlmediakit

# 给脚本添加执行权限
chmod +x scripts/install-docker.sh

# 运行安装脚本
./scripts/install-docker.sh

如果脚本安装失败,手动安装步骤:

cd /opt/owl-zlmediakit/deb-packages

# 解压 Docker 静态二进制包
# 注意: 将 docker-27.5.1.tgz 替换为您实际下载的版本
tar -xzf docker-27.5.1.tgz

# 复制到系统路径
cp -p docker/* /usr/bin/

# 安装 docker-compose
cp -p docker-compose-linux-aarch64 /usr/bin/docker-compose
chmod +x /usr/bin/docker-compose

# 创建 systemd 服务
cat > /etc/systemd/system/docker.service << 'EOF'
[Unit]
Description=Docker Application Container Engine
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

# 启动 Docker
systemctl daemon-reload
systemctl start docker
systemctl enable docker

# 验证
docker --version
docker-compose --version

5.3 加载 Docker 镜像并启动

cd /opt/owl-zlmediakit

# 加载 ZLMediaKit 镜像
docker load -i docker-images/zlmediakit-master-arm64.tar

# 加载 GoWVP 镜像
docker load -i docker-images/gowvp-latest-arm64.tar

# 验证镜像已加载
docker images | grep -E "zlmediakit|gowvp"

# 创建数据目录
mkdir -p data/record data/log data/gowvp-configs data/snap

# 复制配置文件
cp configs/zlm-config.ini data/
cp configs/docker-compose.yml .

# 启动服务(首次启动建议前台运行查看日志)
docker-compose up

# 如果日志无错误,按 Ctrl+C 停止,然后后台启动
docker-compose up -d

5.4 部署 ZLMediaKit单独运行方式

如果使用 Docker Compose 融合部署,此节可跳过。本节仅用于单独部署 ZLMediaKit 的场景。

# 单独运行 ZLMediaKit 容器
docker run -id \
  --name zlmediakit \
  --restart always \
  --privileged \
  --network host \
  -v /opt/owl-zlmediakit/data/zlm-config.ini:/opt/media/conf/config.ini:ro \
  -v /opt/owl-zlmediakit/data/record:/opt/media/bin/www/record \
  -v /opt/owl-zlmediakit/data/log:/opt/media/bin/log \
  -e TZ=Asia/Shanghai \
  zlmediakit/zlmediakit:master

# 查看日志
docker logs -f zlmediakit

5.5 部署 GoWVPOwl单独运行方式

如果使用 Docker Compose 融合部署,此节可跳过。

# 单独运行 GoWVP 容器
docker run -id \
  --name gowvp \
  --restart always \
  --network host \
  -v /opt/owl-zlmediakit/data/gowvp-configs:/opt/media/bin/configs \
  -v /opt/owl-zlmediakit/data/record:/opt/media/bin/www/record \
  -e TZ=Asia/Shanghai \
  -e GOWVP_ZLM_HOST=192.168.3.108 \
  -e GOWVP_ZLM_PORT=80 \
  -e GOWVP_ZLM_SECRET=035c73f7-bb6b-4889-a715-d9eb2d1925cc \
  gospace/gowvp:latest

# 查看日志
docker logs -f gowvp

5.6 配置联动

5.6.1 ZLMediaKit Hook 配置(已包含在配置文件中)

ZLMediaKit 通过 WebHook 将事件通知给 GoWVP

[hook]
enable=1
on_publish=https://127.0.0.1:15123/api/v1/hook/on_publish
on_play=https://127.0.0.1:15123/api/v1/hook/on_play
on_stream_not_found=https://127.0.0.1:15123/api/v1/hook/on_stream_not_found
on_server_started=https://127.0.0.1:15123/api/v1/hook/on_server_started
on_server_keepalive=https://127.0.0.1:15123/api/v1/hook/on_server_keepalive
admin_params=secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc

5.6.2 GoWVP 环境变量配置(已包含在 docker-compose.yml 中)

GoWVP 通过环境变量连接 ZLMediaKit

environment:
  - GOWVP_ZLM_HOST=192.168.3.108    # ZLMediaKit 地址必须使用服务器实际IP
  - GOWVP_ZLM_PORT=80               # ZLMediaKit HTTP端口
  - GOWVP_ZLM_SECRET=035c73f7-bb6b-4889-a715-d9eb2d1925cc  # API密钥

5.6.3 重启服务使配置生效

cd /opt/owl-zlmediakit
docker-compose restart

# 等待30秒后检查状态
sleep 30
docker-compose ps

六、配置联动

GoWVP 与 ZLMediaKit 的联动已通过以下方式配置完成:

  1. ZLMediaKit Hook 回调: ZLMediaKit 在流注册、播放、推流等事件发生时,通过 HTTP POST 请求通知 GoWVP
  2. GoWVP RESTful API: GoWVP 通过 ZLMediaKit 的 HTTP API 控制流的拉取、转码、录制等操作
  3. 共享存储: 两个容器通过 bind mount 共享 ./data/record 目录,用于录像文件存储

联动验证

# 查看 ZLMediaKit 日志,确认 Hook 回调成功
docker logs zlmediakit | grep -i "hook"

# 查看 GoWVP 日志,确认收到 ZLMediaKit 事件
docker logs gowvp | grep -i "zlm\|hook"

七、验证步骤

7.1 验证脚本

运行提供的验证脚本:

chmod +x /opt/owl-zlmediakit/scripts/verify.sh
/opt/owl-zlmediakit/scripts/verify.sh

7.2 手动验证步骤

7.2.1 验证 ZLMediaKit

# 获取服务器IP
SERVER_IP=$(hostname -I | awk '{print $1}')

# 测试 ZLMediaKit API
curl "http://${SERVER_IP}/index/api/getApiList"

# 测试获取流列表
curl "http://${SERVER_IP}/index/api/getMediaList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc"

# 在浏览器中访问
# http://<服务器IP>

7.2.2 验证 GoWVP

# 测试 GoWVP Web 界面
curl -I "http://${SERVER_IP}:15123"

# 在浏览器中访问管理界面
# http://<服务器IP>:15123
# 默认账号密码请查看 GoWVP 官方文档

7.2.3 验证 GB28181 端口

# 检查 SIP 端口UDP/TCP 15060
netstat -ulnp | grep 15060
netstat -tlnp | grep 15060

# 检查流媒体端口范围20000-20100
netstat -ulnp | grep -E "20000|20001|20002"

7.3 推流测试

如果您有支持 RTMP/RTSP 的摄像头或推流工具,可以进行测试:

# RTMP 推流测试地址使用FFmpeg
ffmpeg -re -i test.mp4 -c copy -f flv rtmp://<服务器IP>/live/test

# 播放测试
# RTMP: rtmp://<服务器IP>/live/test
# HLS: http://<服务器IP>/live/test/hls.m3u8
# FLV: http://<服务器IP>/live/test.live.flv

八、常见问题排查

8.1 Docker 无法启动

现象: systemctl start docker 失败

排查步骤:

# 查看详细错误
journalctl -u docker -n 50

# 检查内核是否支持容器
cat /proc/1/cgroup

# 手动运行dockerd查看错误
/usr/bin/dockerd

解决方案:

  • 确保内核版本 >= 3.10统信UOS kernel-4.19 满足要求)
  • 检查 /var/run/docker.sock 权限
  • 确保 iptables 可用:which iptables

8.2 容器启动后立即退出

现象: docker ps 看不到运行的容器

排查步骤:

# 查看容器退出日志
docker logs zlmediakit
docker logs gowvp

# 查看容器状态
docker ps -a
docker inspect zlmediakit

常见原因:

  • 端口被占用:netstat -tlnp | grep :80
  • 配置文件路径错误:检查 volume 映射
  • 权限不足:确保使用 --privileged 或正确配置 capabilities

8.3 ARM64 镜像无法运行

现象: 报错 exec format error

原因: 镜像架构与服务器不匹配(导入了 x86_64 镜像)

解决方案:

# 检查镜像架构
docker inspect zlmediakit/zlmediakit:master | grep Architecture
# 必须显示 "arm64"

# 如果错误,需要在 ARM64 机器上重新拉取并导出

8.4 GoWVP 无法连接 ZLMediaKit

现象: GoWVP 日志显示连接 ZLMediaKit 失败

排查步骤:

# 检查 ZLMediaKit 是否正常运行
curl http://127.0.0.1/index/api/getApiList

# 检查 secret 是否一致
grep secret data/zlm-config.ini
grep GOWVP_ZLM_SECRET docker-compose.yml

# 检查 Hook 配置是否正确
grep "on_publish\|on_play" data/zlm-config.ini

8.5 GB28181 设备无法接入

现象: 摄像头无法注册到 GoWVP

排查步骤:

# 检查 SIP 端口是否监听
netstat -ulnp | grep 15060

# 检查防火墙
firewall-cmd --list-ports  # 如果使用 firewalld
iptables -L -n | grep 15060

# 查看 GoWVP 日志
docker logs -f gowvp | grep -i "sip\|register"

必要端口清单:

端口 协议 用途
80 TCP HTTP/Web
443 TCP HTTPS
15123 TCP GoWVP Web管理
15060 UDP/TCP GB28181 SIP
1935 TCP RTMP
554 TCP RTSP
8000 UDP/TCP WebRTC
9000 UDP SRT
10000 UDP RTP代理
20000-20100 UDP GB28181 媒体流
30000-30500 UDP RTP端口范围

8.6 性能问题

现象: 视频卡顿、延迟高

优化建议:

# 查看CPU和内存使用情况
top
htop

# 查看磁盘IO
iostat -x 1

# ZLMediaKit 配置优化关闭转码以节省CPU
# 在 config.ini 中:
[ffmpeg]
cmd=%s -re -i %s -c copy -f flv %s  # 使用 copy 而不是重新编码

# 限制日志大小避免磁盘占满
docker system prune -f

8.7 ARM64 架构稳定性问题(重要)

⚠️ 本章节针对飞腾S5000C等ARM64服务器的重要风险提示

8.7.1 已知问题概述

GitHub Issue: #3466 - In ARM architecture, ZLM live streaming is unstable

问题描述: ZLMediaKit 在 ARM64 (aarch64) 架构下运行 GB28181 RTP 推流时,存在偶发性崩溃问题x86_64 架构下相同配置稳定运行。

8.7.2 具体症状

症状 描述
进程崩溃 MediaServer 进程意外退出Docker 容器重启
Signal 11 收到 SIGSEGV (段错误),内存访问违规
流中断 GB28181 RTP 推流频繁断开,需重新注册
错误日志 Unsupported codec: PCMUUnsupported codec: invalid

典型错误日志:

2024-04-11 07:13:07.002 W [MediaServer] [319-event poller 3] Factory.cpp:118 getTrackByCodecId | Unsupported codec: PCMU
2024-04-11 07:13:24.885 W [MediaServer] [319-event poller 3] Factory.cpp:200 getFrameFromPtr | Unsupported codec: invalid

崩溃堆栈特征(简化):

Signal 11 received
Stacktrace:
  FrameCacheAble::FrameCacheAble(...)
  Factory::getFrameFromBuffer(...)
  FrameMerger::inputFrame(...)
  FrameMerger::flush(...)
  DecoderImp::flush(...)
  RtpProcessHelper::~RtpProcessHelper()

崩溃位置分析: 堆栈显示崩溃发生在帧缓存分配解码器刷新阶段,疑似与内存对齐或并发访问有关。

8.7.3 可重现性

条件 可重现性
Docker 部署 + ARM64 - 社区多个用户报告
物理机/虚拟机 ARM64 - 部分用户报告
x86_64 (相同配置) 无法重现 - 稳定运行
GB28181 RTP 推流 - 主要触发场景
RTMP/RTSP 推流 - 偶发
空闲状态 - 仅在活跃推流时

8.7.4 可能原因分析

  1. 内存对齐问题: ARM64 架构对内存对齐要求更严格,某些数据结构在 x86 上能正常工作但在 ARM 上触发 SIGSEGV
  2. 并发访问竞争: FrameMerger 在多线程环境下可能存在 race condition
  3. Codec 解析异常: 某些摄像头发送的 PS 流格式不规范ARM 版解码器处理异常时未正确保护
  4. Docker 环境差异: Docker 在 ARM64 上的 QEMU 模拟或 seccomp 策略可能影响行为

8.7.5 规避方案与解决方案

方案一:使用官方最新镜像(推荐尝试)

# 确保使用最新 master 分支镜像,可能已修复
# 官方维护者持续在修复 ARM64 相关问题
docker pull zlmediakit/zlmediakit:master
docker inspect zlmediakit/zlmediakit:master | grep -E "Created|Revision"

方案二:启用容器自动重启

# 在 docker-compose.yml 中已配置 restart: always
# 崩溃后容器会自动重启,业务中断时间 < 10 秒
services:
  zlmediakit:
    restart: always
    # 可选:增加重启策略
    deploy:
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 10

方案三:限制单路流的并发处理

# 在 config.ini 中降低并发处理线程数
[general]
# 减少事件轮询线程数(默认等于 CPU 核心数)
# 可尝试设置为物理核心数的一半
# 注意: 此配置需查阅最新文档确认参数名

[ffmpeg]
# 关闭转码,减少编解码压力
cmd=%s -re -i %s -c copy -f flv %s

方案四:使用 host 网络模式(已默认配置)

# docker-compose.yml 中已配置 network_mode: host
# 避免 Docker 桥接网络在 ARM64 上的性能开销和潜在 bug
services:
  zlmediakit:
    network_mode: host

方案五:监控并自动恢复

# 创建监控脚本 /opt/owl-zlmediakit/scripts/monitor.sh
#!/bin/bash
while true; do
    if ! docker ps | grep -q zlmediakit; then
        echo "$(date): ZLMediaKit 容器异常,正在重启..." >> /var/log/zlm-monitor.log
        cd /opt/owl-zlmediakit && docker-compose restart zlmediakit
    fi
    sleep 10
done

方案六:源码编译(终极方案)

# 如果 Docker 镜像问题持续,可在 ARM64 服务器上本地编译
# 本地编译会针对具体 CPU 指令集优化,可能规避问题
cd /usr/src/ZLMediaKit
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-faligned-new"
make -j$(nproc)

8.7.6 生产环境建议

场景 建议
测试/开发环境 可直接使用 Docker 部署,观察稳定性
生产环境(关键业务) 强烈建议先进行 7x24 小时压力测试,确认无崩溃后再上线
已出现崩溃 启用自动重启 + 监控脚本,同时向 ZLMediaKit GitHub 提交 issue
追求极致稳定 考虑在 ARM64 上源码编译,或改用 x86_64 服务器部署 ZLMediaKit

8.7.7 社区状态跟踪

  • Issue 状态: Closed (因未按模板提交被关闭,但问题真实存在)
  • 社区反馈: 多名用户确认在 RK3568、树莓派、鲲鹏等 ARM64 设备上遇到类似问题
  • 官方态度: 维护者表示会持续关注 ARM64 兼容性,建议用户使用最新版本
  • 建议操作: 如遇到崩溃,请收集完整堆栈和复现步骤,向 ZLMediaKit Issues 提交反馈

8.7.8 相关 Issue 深度分析

以下三个 Issue 与 ARM64 稳定性密切相关,建议主人一并了解。


Issue #3202 - RK3588 SIGABRT 崩溃

项目 详情
硬件 RK3588 (Ubuntu 20.04.6)
信号 SIGABRT (signal 6)
版本 git hash e593ef5/2023-12-17
触发条件 视频流不稳定时持续崩溃

崩溃堆栈特征:

[0]: MediaServer(+0x992ba8)
[4]: libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x188)
[8]: MediaServer(Assert_Throw+0x184)

根本原因(官方维护者 @xia-chu 回复):

"这个不算bug是你的编译器默认关闭了异常功能一抛异常就默认 abort。编译器开启异常功能需要加上编译选项 -fexceptions。"

技术解释:

  • ARM 交叉编译工具链(如 aarch64-linux-gnu-gcc默认关闭 C++ 异常处理
  • 当 ZLMediaKit 内部抛出 C++ 异常(如 Assert_Throw 失败libstdc++ 的 terminate handler 被调用
  • 由于异常被禁用,该 handler 直接调用 abort() 导致进程终止

解决方案:

# 在 CMakeLists.txt 中添加
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
endif()

或在 cmake 命令中指定:

cmake .. -DCMAKE_CXX_FLAGS="-fexceptions"

⚠️ 重要: -fexceptions 是 GCC 标准选项,不是临时 hack。ZLMediaKit 大量使用 C++ 异常,在 ARM 上编译必须显式启用。


Issue #2728 - ARM 内存"泄漏"问题

项目 详情
平台 ARM (aarch64), Ubuntu 18, 内存 4G
现象 调用 getStatisticJson 接口时系统卡死;开启 ENABLE_MEM_DEBUG 后机器完全卡住
本质 内存碎片,非真正泄漏

详细分析:

  1. 内存碎片问题:

    • ZLMediaKit 调用 free() 将内存返还给 glibc 的 ptmalloc
    • 但 ptmalloc 不会立即将内存返还给操作系统(出于性能考虑)
    • 导致 RSS 内存居高不下,看起来像泄漏
  2. ENABLE_MEM_DEBUG 的陷阱:

    # ZLMediaKit 使用链接器 wrap 机制拦截内存分配
    if(ENABLE_MEM_DEBUG)
      update_cached_list(MK_LINK_LIBRARIES
        "-Wl,-wrap,free;-Wl,-wrap,malloc;-Wl,-wrap,realloc;-Wl,-wrap,calloc")
    endif()
    
    • 在 ARM 平台上,-Wl,-wrap 拦截每次 malloc/free性能开销极大
    • 高并发场景下会导致系统完全卡死
    • 生产环境切勿开启 ENABLE_MEM_DEBUG
  3. 解决方案 - 使用 tcmalloc:

    # 编译时启用 tcmalloc
    cmake .. -DENABLE_TCMALLOC=ON
    
    • tcmalloc 采用 per-CPU 缓存 机制,更好地管理内存碎片
    • 在 RTP 断流重连场景下,内存可以稳定复用

    tcmalloc 静态库编译注意事项:

    # 编译 gperftools 时需要加 -fPIC
    ./configure CFLAGS="-fPIC" CXXFLAGS="-fPIC"
    make
    

    运行时加载:

    LD_PRELOAD=libtcmalloc.so.4 ./MediaServer
    
  4. 替代方案 - jemalloc:

    # ZLMediaKit 默认优先链接 jemalloc
    find_package(JEMALLOC QUIET)
    if(JEMALLOC_FOUND)
      update_cached_list(MK_LINK_LIBRARIES ${JEMALLOC_LIBRARIES})
      add_definitions(-DUSE_JEMALLOC)
    endif()
    

Issue #2043 - RK3568 拉流断开问题

项目 详情
硬件 RK3568
信号 SIGSEGV (signal 11)
版本 git hash b3fd74c
触发条件 拉流后很快断开

错误日志:

## signal: 11
[0]: ./MediaServer() [0x995710] sig_crash(int)
[1]: /lib/arm-linux-gnueabihf/libc.so.6(+0x25260)

可能原因:

  1. RK 系列网卡驱动 bug(与 RK3399 类似)

    "rk3339 的网卡驱动是有 bug 的!如果是从上面往别处 tcp 发送大的数据包,在 tcp 的 ip 数据报分片以后会出现校验和计算错误"

  2. 交叉编译环境配置问题
  3. 缺少必要的系统库

状态: Issue 已关闭,标题显示"问题已经解决,谢谢",但未详细说明解决方案。

建议: 如遇到类似问题,优先尝试:

  1. 更新到最新代码
  2. 检查网卡驱动版本
  3. 在 GDB 下调试获取完整堆栈

8.7.9 ARM64 编译优化建议

必加编译选项:

选项 用途 必要性
-fexceptions 启用 C++ 异常处理 必须
-pthread 线程支持 必须
-fPIC 位置无关代码(动态库需要) 推荐
-faligned-new 对齐内存分配 推荐

完整编译命令示例:

cd /usr/src/ZLMediaKit
mkdir build && cd build

cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_CXX_FLAGS="-fexceptions -pthread -fPIC -faligned-new" \
  -DENABLE_WEBRTC=ON \
  -DENABLE_FFMPEG=ON \
  -DENABLE_TCMALLOC=ON

make -j$(nproc)

交叉编译示例飞腾S5000C:

# 创建工具链文件 /tmp/toolchain.cmake
cat > /tmp/toolchain.cmake << 'EOF'
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
EOF

cmake .. \
  -DCMAKE_TOOLCHAIN_FILE=/tmp/toolchain.cmake \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_CXX_FLAGS="-fexceptions -pthread -fPIC" \
  -DENABLE_TCMALLOC=ON

make -j$(nproc)

8.7.10 官方态度与未来展望

官方维护者 (@xia-chu) 的态度:

  • 承认 ARM64 支持,但认为问题多源于用户环境/编译方式
  • 对于崩溃问题,往往归结为:端口占用、编译器选项问题 (-fexceptions)、Android 限制等
  • 没有看到系统性的 ARM64 修复计划公告

已有的 ARM64 修复:

  • PR #2479 (2023-05): 修复 ARM 内存对齐问题
    • Commit 7cb772c: "On arm need align, without this the application crashed after SIGBUS"
  • PR #2800 (2023-08): 修复 close_streamgetMediaList 并发崩溃
  • PR #4582 (2025-12): 修复 RtspSession/RtspPusher 空指针崩溃

未来计划:

  • 2024 年 12 月,@xia-chu 表示:"后面我会考虑添加下 arm64 的 ci 自动编译并发布二进制包"
  • 但截至 2026 年 4 月,尚未实现 ARM64 CI 自动编译和二进制发布

Issue #483 预编译二进制包:


九、附录

附录A: 端口清单

端口 协议 服务 说明
80 TCP ZLMediaKit HTTP 服务
443 TCP ZLMediaKit HTTPS 服务
15123 TCP GoWVP Web 管理界面
15060 UDP/TCP GoWVP GB28181 SIP 信令
1935 TCP ZLMediaKit RTMP 推流/播放
554 TCP ZLMediaKit RTSP 服务
8000 UDP/TCP ZLMediaKit WebRTC
9000 UDP ZLMediaKit SRT 协议
10000 UDP ZLMediaKit RTP 代理
20000-20100 UDP GoWVP GB28181 媒体流传输
30000-30500 UDP ZLMediaKit RTP 端口范围

附录B: 源码编译 ZLMediaKit备用方案

如果 Docker 方案不可用,可以选择源码编译:

# 1. 安装编译依赖
# yum 系统:
sudo yum install -y gcc gcc-c++ cmake git openssl-devel

# apt 系统:
sudo apt-get install -y build-essential cmake git libssl-dev

# 2. 解压源码
cd /opt/owl-zlmediakit/source-packages
tar xzf ZLMediaKit-master-with-submodules.tar.gz -C /usr/src/
cd /usr/src/ZLMediaKit

# 3. 初始化子模块如果用zip下载则需要
git submodule update --init --recursive

# 4. 编译
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

# 5. 运行
./release/linux/Release/MediaServer -d &

附录C: 源码编译 GoWVP备用方案

# 1. 安装 Go 环境1.20+
# 下载 ARM64 版本 Go: https://go.dev/dl/go1.22.0.linux-arm64.tar.gz

# 2. 解压预编译包
cd /opt/owl-zlmediakit/source-packages
tar xzf owl_linux_arm64.tar.gz -C /usr/local/

# 3. 运行
/usr/local/owl/owl-server &

附录D: 防火墙配置

# 如果使用 firewalld
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --permanent --add-port=15123/tcp
firewall-cmd --permanent --add-port=15060/tcp
firewall-cmd --permanent --add-port=15060/udp
firewall-cmd --permanent --add-port=1935/tcp
firewall-cmd --permanent --add-port=554/tcp
firewall-cmd --permanent --add-port=8000/tcp
firewall-cmd --permanent --add-port=8000/udp
firewall-cmd --permanent --add-port=9000/udp
firewall-cmd --permanent --add-port=10000/udp
firewall-cmd --permanent --add-port=20000-20100/udp
firewall-cmd --permanent --add-port=30000-30500/udp
firewall-cmd --reload

# 如果使用 iptables
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp --dport 15123 -j ACCEPT
iptables -I INPUT -p tcp --dport 15060 -j ACCEPT
iptables -I INPUT -p udp --dport 15060 -j ACCEPT
iptables -I INPUT -p tcp --dport 1935 -j ACCEPT
iptables -I INPUT -p tcp --dport 554 -j ACCEPT
iptables -I INPUT -p tcp --dport 8000 -j ACCEPT
iptables -I INPUT -p udp --dport 8000 -j ACCEPT
iptables -I INPUT -p udp --dport 9000 -j ACCEPT
iptables -I INPUT -p udp --dport 10000 -j ACCEPT
iptables -I INPUT -p udp --dport 20000:20100 -j ACCEPT
iptables -I INPUT -p udp --dport 30000:30500 -j ACCEPT

附录E: 参考链接

资源 地址
ZLMediaKit GitHub https://github.com/ZLMediaKit/ZLMediaKit
ZLMediaKit 文档 https://docs.zlmediakit.com/
ZLMediaKit Docker Hub https://hub.docker.com/r/zlmediakit/zlmediakit
GoWVP (Owl) GitHub https://github.com/gowvp/owl
GoWVP Docker Hub https://hub.docker.com/r/gospace/gowvp
Docker CE 下载 https://download.docker.com/linux/static/stable/aarch64/
Docker Compose 下载 https://github.com/docker/compose/releases
libsrtp 下载 https://github.com/cisco/libsrtp/releases

附录F: ARM64 架构问题速查表

本附录汇总 ZLMediaKit 在 ARM64 架构上的所有已知问题、症状和解决方案,方便快速定位。

F.1 信号类型速查

信号 名称 常见原因 解决方案
Signal 6 SIGABRT C++ 异常被禁用abort() 被调用 编译时加 -fexceptions
Signal 7 SIGBUS 内存未对齐访问 已于 PR #2479 修复 (2023-05),更新代码
Signal 11 SIGSEGV 内存访问违规/空指针 更新代码,检查 PS 流格式GDB 调试

F.2 Issue 汇总表

Issue 硬件 信号 根本原因 解决方案 状态
#3466 多种 ARM SIGSEGV PS 流解析异常 + 内存问题 更新代码 + 自动重启 已关闭
#3202 RK3588 SIGABRT 编译器关闭异常处理 -fexceptions 已解决
#2728 多种 ARM - 内存碎片 + MEM_DEBUG 性能问题 tcmalloc/jemalloc 已规避
#2043 RK3568 SIGSEGV 可能网卡驱动 bug 更新代码 已关闭
#4037 aarch64 system_error 端口占用/系统限制 GDB 调试排查 已关闭

F.3 编译参数速查

必须添加:

cmake .. -DCMAKE_CXX_FLAGS="-fexceptions -pthread -fPIC"

推荐添加:

cmake .. -DCMAKE_CXX_FLAGS="-fexceptions -pthread -fPIC -faligned-new" \
         -DENABLE_TCMALLOC=ON

调试编译:

cmake .. -DCMAKE_BUILD_TYPE=Debug \
         -DCMAKE_CXX_FLAGS="-fexceptions -pthread -fPIC" \
         -DENABLE_ASAN=ON

F.4 运行时问题速查

现象 排查命令 可能原因 解决方案
容器频繁重启 docker logs zlmediakit Signal 11 崩溃 更新镜像/源码编译
内存只增不减 cat /proc/$(pidof MediaServer)/status 内存碎片 使用 tcmalloc
流播放卡顿 top, iostat CPU/IO 瓶颈 关闭转码,限制并发
GB28181 无法注册 netstat -ulnp | grep 15060 端口未监听 检查防火墙,重启容器
WebRTC 无法播放 netstat -ulnp | grep 8000 UDP 端口被阻 检查防火墙规则

F.5 Docker vs 源码编译选择建议

场景 推荐方式 理由
快速验证/测试 Docker 简单快捷,自动重启可缓解崩溃
生产环境(关键业务) 源码编译 可针对具体 CPU 优化,稳定性更好
频繁崩溃 源码编译 可添加 -fexceptions 等必要参数
资源受限 Docker 无需编译环境,节省磁盘空间

F.6 官方 ARM64 修复时间线

时间 修复内容
2023-05 PR #2479: 修复 ARM 内存对齐 SIGBUS 问题
2023-08 PR #2800: 修复 close_stream 与 getMediaList 并发崩溃
2024-12 @xia-chu 表示考虑添加 ARM64 CI 自动编译
2025-12 PR #4582: 修复 RtspSession/RtspPusher 空指针崩溃
2026-04 尚未实现 ARM64 CI 自动编译和二进制发布

F.7 社区已知兼容硬件

芯片 型号 系统 状态 备注
瑞芯微 RK3568 多种 Linux 基本稳定 更新代码后正常
瑞芯微 RK3588 Ubuntu 20.04 ⚠️ 需注意 需加 -fexceptions
飞腾 S5000C 统信UOS20 ⚠️ 待验证 本手册目标平台
鲲鹏 920 Ubuntu 20.04 正常 社区反馈良好
树莓派 4B Raspberry Pi OS ⚠️ 偶发崩溃 建议源码编译

文档结束 如有问题,请参考各项目的官方文档或 GitHub Issues。 文档版本: v1.2 最后更新: 2026-04-29