跳到主要内容

Deploy-ZLMediaKit-And-WVP-GB28181-Pro-Offline

一、相关链接​

二、环境介绍​

编译机器:

  • centos 8.6
  • gcc version 8.5.0 (GCC)
  • cmake version 3.20.2
名称版本备注
CentOS8.5.2111
ZLMediaKit7.0
WVP-Pro2.7.2
gcc8.5.0
g++8.5.0
cmake3.20.2
nasm2.14.02
yasm1.3.0
x2640.165.x
libmp4v2
faac1.29.9.2
perlv5.32.1
openssl1.1.1w
libsrtp2.5.0
FFmpeg7.1.1

三、准备工作​

本文档所有操作在一台与内网服务器同版本的虚拟机上执行,在内网机器部署时,只需要执行标题包含【离线】字样的内容

3.1 系统安装​

系统安装与CentOS7之前有较大区别,可以参考这篇文章 重点是在安装信息摘要页面,按照以下顺序设置

  1. Root用户密码
  2. 网络和主机名 此处的MAC地址需要和虚拟机设置-网络页面的MAC地址一致
  3. 安装目的地
  4. 安装源 http://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/
  5. 软件选择 最小安装(yum ssh curl ping ip)
  6. 时间和日期 将时区改为 Asia/Shanghai

安装配置顺序 配置安装源

3.2 设置静态IP​

如果要设置固定IP,可以修改网络配置文件,手动设置IP、MAC地址、网关、子网掩码、DNS等信息

# 查看网络配置
cat /etc/sysconfig/network-scripts/ifcfg-enp0s3

# 修改网络配置
vi /etc/sysconfig/network-scripts/ifcfg-enp0s3
BOOTPROTO=static
IPADDR=192.168.137.101
# MACADDR=08:00:27:D7:88:87
HWADDR=08:00:27:D7:88:87
GATEWAY=192.168.137.1
NETMASK=255.255.255.0
DNS1=114.114.114.114

# 重启网络服务
systemctl restart NetworkManager

# 测试与宿主机 公网的网络互通
ping -c4 192.168.137.1
ping -c4 jd.com

3.3 修改yum源​

Errors during downloading metadata for repository 'appstream':
- Curl error (6): Couldn't resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=stock [Could not resolve host: mirrorlist.centos.org]
错误:为仓库 'appstream' 下载元数据失败 : Cannot prepare internal mirrorlist: Curl error (6): Couldn't resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=stock [Could not resolve host: mirrorlist.centos.org]

由于 CentOS 团队已于 2021 年 12 月 31 日对 CentOS Linux 8 停止更新和维护,并从官方镜像中移除 CentOS 8 的所有包,因此导致在使用 yum 源安装或更新会报上述错误,解决方案可参考这篇文章,下面直接用阿里云软件源替换

  1. 备份软件源
# 进入仓库源文件目录下
cd /etc/yum.repos.d/

# 备份
mkdir /etc/yum.repos.d/backup
mv /etc/yum.repos.d/* /etc/yum.repos.d/backup/

  1. 使用阿里云软件源
# 如果没有wget,可以用curl下载 
# wget http://mirrors.aliyun.com/repo/Centos-8.repo -O /etc/yum.repos.d/CentOS-Linux-BaseOS.repo

curl http://mirrors.aliyun.com/repo/Centos-8.repo -o /etc/yum.repos.d/CentOS-Linux-BaseOS.repo

  1. 安装epel源、rpmfusion源
# 下载阿里云epel源、rpmfusion源
mkdir -p /root/lib/{epel,rpmfusion}
curl https://mirrors.aliyun.com/epel/epel-release-latest-8.noarch.rpm -o ./local-repo/yum-repo/epel-release-latest-8.noarch.rpm
curl https://mirrors.aliyun.com/rpmfusion/free/el/rpmfusion-free-release-8.noarch.rpm -o ./local-repo/yum-repo/rpmfusion-free-release-8.noarch.rpm
curl https://mirrors.aliyun.com/rpmfusion/nonfree/el/rpmfusion-nonfree-release-8.noarch.rpm -o ./local-repo/yum-repo/rpmfusion-nonfree-release-8.noarch.rpm

# 安装
rpm -ivh ./local-repo/yum-repo/*.rpm

# 查看
ll /etc/yum.repos.d/epel*
ll /etc/yum.repos.d/rpmfusion*

# 刷新源
dnf repolist epel -v
dnf repolist rpmfusion -v

  1. 更新软件源
# 清空原有缓存并重新生成
yum clean all && yum makecache

# 更新软件包(可选)
yum update -y

3.4 创建操作用户​

如果没有专门的操作用户,可以按下面的操作创建新的用户,后续操作均使用此新用户来执行

# 1. 创建用户
sudo useradd -m diginn

# 2. 设置密码
sudo passwd diginn

# 3. 赋予root权限
sudo visudo
# 添加如下内容
diginn ALL=(ALL) ALL

# 4. 测试权限
su - diginn
sudo whoami

# 显示 root 即表示diginn用户有 sudo 权限

3.5 安装基础依赖​

由于离线安装时无法在线安装依赖包,故需要提前准备好相关的依赖包,如何查询并安装依赖包可以参考这篇文章

3.5.1 【在线】在线下载和安装​

  1. 安装依赖
# 1. 下载 yum-utils https://mirrors.aliyun.com/centos/8.5.2111/BaseOS/x86_64/os/Packages/
mkdir -p ./local-repo/base-deps
curl https://mirrors.aliyun.com/centos/8.5.2111/BaseOS/x86_64/os/Packages/yum-utils-4.0.21-3.el8.noarch.rpm -o ./local-repo/base-deps/yum-utils-4.0.21-3.el8.noarch.rpm

# 2. 安装 yum-utils
rpm -ivh ./local-repo/base-deps/*.rpm

# 3. 下载RPM包
# yumdownloader --arch=x86_64 --resolve --destdir=/root/lib/tar tar
mkdir ./local-repo/base-repo/
dnf download --archlist=x86_64,noarch --resolve --destdir=./local-repo/base-deps/ \
tar unzip bzip2 vim wget net-tools yum-utils

# 4. 安装RPM包
dnf install tar bzip2 unzip wget net-tools yum-utils

  • --resolve 下载依赖包
  • --arch 指定平台架构 x86_64 aarch64
  • --releasever指定系统版本 CentOS7 的 7 或 CentOS8 的 8
  • --destdir 指定保存路径
  1. 查看提供某个命令/value的rpm包
yum provides unzip

  1. 查看 rpm 包所需的全部依赖
yum deplist unzip-6.0-45.el8_4

3.5.2 【离线】离线安装​

# 1. 安装解压工具
rpm -ivh tar-1.30-5.el8.x86_64.rpm

# 2. 解压离线安装包
tar -zxvf local-repo.tar.gz # RPM依赖包
tar -zxvf resource.tar.gz # 源码安装包
tar -zxvf ZLMediaKit.tar.gz # ZLMediaKit源码包

# 3. 安装基础依赖
dnf localinstall --disablerepo=* --skip-broken -y ./local-repo/base-deps/*.rpm

# 如果安装了本地仓库,可以直接安装
dnf --disablerepo=* --enablerepo=local install tar bzip2 unzip wget net-tools yum-utils

四、安装编译依赖​

按照快速开始和zlm启用webrtc编译指南来准备编译环境

4.1 开发工具包依赖安装​

4.1.1 【在线】在线下载和安装​

# 1. 查看开发工具包所包含的依赖
dnf group info "Development Tools"
# dnf group install "Development Tools"
# dnf group remove "Development Tools"
# dnf install perl-IPC-Cmd perl-Pod-Html

# 2. 下载安装包及依赖
dnf download --archlist=x86_64,noarch --resolve --destdir=./local-repo/develop-deps/ \
autoconf make automake binutils bison flex \
gcc gcc-c++ gdb glibc-devel libtool \
pkgconf pkgconf-m4 pkgconf-pkg-config redhat-rpm-config \
rpm-build rpm-sign strace asciidoc byacc ctags diffstat \
elfutils-libelf-devel git intltool jna ltrace patchutils \
perl-Fedora-VSP perl-Sys-Syslog perl-generators pesign source-highlight \
systemtap valgrind valgrind-devel cmake expect rpmdevtools rpmlint \
perl-IPC-Cmd perl-Pod-Html

# 3. 安装
# 3. 安装基础依赖
dnf localinstall --disablerepo=* --skip-broken -y ./local-repo/develop-deps/*.rpm

# 如果安装了本地仓库,可以直接安装
dnf --disablerepo=* --enablerepo=local autoconf make automake binutils bison flex \
gcc gcc-c++ gdb glibc-devel libtool \
pkgconf pkgconf-m4 pkgconf-pkg-config redhat-rpm-config \
rpm-build rpm-sign strace asciidoc byacc ctags diffstat \
elfutils-libelf-devel git intltool jna ltrace patchutils \
perl-Fedora-VSP perl-Sys-Syslog perl-generators pesign source-highlight \
systemtap valgrind valgrind-devel cmake expect rpmdevtools rpmlint

4.1.2 【离线】离线安装​

# 由于上面步骤已解压离线安装包,这里直接安装即可

# 1. 安装开发工具包
dnf localinstall --disablerepo=* --skip-broken -y ./local-repo/develop-deps/*.rpm

# 如果安装了本地仓库,可以直接安装
dnf --disablerepo=* --enablerepo=local autoconf make automake binutils bison flex \
gcc gcc-c++ gdb glibc-devel libtool \
pkgconf pkgconf-m4 pkgconf-pkg-config redhat-rpm-config \
rpm-build rpm-sign strace asciidoc byacc ctags diffstat \
elfutils-libelf-devel git intltool jna ltrace patchutils \
perl-Fedora-VSP perl-Sys-Syslog perl-generators pesign source-highlight \
systemtap valgrind valgrind-devel cmake expect rpmdevtools rpmlint

4.2 安装基础依赖 gcc gcc-c++ cmake​

4.2.1 【在线】在线下载和安装​

# 在线安装
# yum -y install gcc gcc-c++ cmake

# 1. 下载安装包
mkdir -p /root/lib/{gcc,gcc-c++,cmake}
# dnf download --archlist=x86_64,noarch --resolve --destdir=/root/lib/gcc gcc
dnf download --archlist=x86_64,noarch --resolve --destdir=./local-repo/media-deps/ \
gcc gcc-c++ cmake libstdc annobin

# 2. 安装
rpm -ivh /root/lib/gcc/*rpm
dnf localinstall --disablerepo=* --skip-broken -y ./local-repo/media-deps/*.rpm
# yum localinstall *.rpm

# 如果安装了本地仓库,可以直接安装
dnf --disablerepo=* --enablerepo=local gcc gcc-c++ cmake libstdc

# 3. 检查版本
gcc --version
g++ --version
cmake --version

# 如果g++找不到命令,手动安装,缺少g++编译ZLMediaKit会报错:No CMAKE_CXX_COMPILER could be found.
rpm -ivh /root/lib/gcc-c++/libstdc++-devel-8.5.0-4.el8_5.x86_64.rpm
rpm -ivh /root/lib/gcc-c++/gcc-c++-8.5.0-4.el8_5.x86_64.rpm

4.2.2 【离线】离线安装​

# 1. 安装
dnf localinstall --disablerepo=* --skip-broken -y ./local-repo/media-deps/*.rpm

# 如果安装了本地仓库,可以直接安装
dnf --disablerepo=* --enablerepo=local gcc gcc-c++ cmake libstdc annobin

# 2. 检查版本
gcc --version
g++ --version
cmake --version

# 3. 如果g++找不到命令,手动安装
# 缺少g++编译ZLMediaKit会报错:No CMAKE_CXX_COMPILER could be found.
rpm -ivh /root/lib/gcc-c++/libstdc++-devel-8.5.0-4.el8_5.x86_64.rpm
rpm -ivh /root/lib/gcc-c++/gcc-c++-8.5.0-4.el8_5.x86_64.rpm

4.3 安装 Nasm Yasm​

4.3.1 【在线】在线下载和安装​

  1. 安装Nasm
# 1. 下载
wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.bz2 -O ./local-repo/binary/nasm-2.14.02.tar.bz2
tar -jxvf nasm-2.14.02.tar.bz2
cd nasm-2.14.02/

# 2. 编译安装
./configure --prefix=/usr/local/nasm
make -j$(nproc) && make install

# 3. 检查版本
/usr/local/nasm/bin/nasm -version

  1. 安装Yasm
# 1. 下载
wget https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz -O ./local-repo/binary/yasm-1.3.0.tar.gz
tar -zxvf yasm-1.3.0.tar.gz
cd yasm-1.3.0

# 2. 编译安装
./configure --prefix=/usr/local/yasm
make -j$(nproc) && make install

# 3. 检查版本
/usr/local/yasm/bin/yasm --version

4.3.2 【离线】离线安装​

  1. 安装Nasm
# 1. 解压
cd /root/resource
tar -jxvf nasm-2.14.02.tar.bz2
cd nasm-2.14.02/

# 2. 编译安装
./configure --prefix=/usr/local/nasm
make -j$(nproc) && make install

# 3. 检查版本
/usr/local/nasm/bin/nasm -version

  1. 安装Yasm
# 1. 解压
cd /root/resource
tar -zxvf yasm-1.3.0.tar.gz
cd yasm-1.3.0

# 2. 编译安装
./configure --prefix=/usr/local/yasm
make -j$(nproc) && make install

# 3. 检查版本
/usr/local/yasm/bin/yasm --version

4.3.3 设置环境变量​

# 设置环境变量
vim /etc/profile

# 加入以下内容
NASM_HOME=/usr/local/nasm
YASM_HOME=/usr/local/yasm
PATH=$PATH:$NASM_HOME/bin:$YASM_HOME/bin
export NASM_HOME YASM_HOME PATH

# 刷新配置
source /etc/profile

# 测试
nasm --version
yasm --version

4.4 安装 x264 libmp4v2 faac​

4.4.1 【在线】在线下载和安装​

  1. 安装x264
# 1. 下载
wget https://code.videolan.org/videolan/x264/-/archive/master/x264-master.tar.bz2 -O ./local-repo/binary/x264-master.tar.bz2
tar -jxvf x264-master.tar.bz2
cd x264-master

# 2. 编译安装
./configure --prefix=/usr/local/x264 --enable-shared --enable-static
make -j$(nproc) && make install

# 3. 检查版本
/usr/local/x264/bin/x264 --version

# 4. 配置动态链接库
vim /etc/ld.so.conf

# 加入以下内容
/usr/local/x264/lib/

# 加载动态链接库
ldconfig -v

# 5. 配置 pkgconfig
# ERROR: x264 not found using pkg-config
# pkg-config会搜索指定路径下的.pc文件,所以将.pc文件移动到指定目录下即可
cp /usr/local/x264/lib/pkgconfig/x264.pc /usr/share/pkgconfig/
  1. 设置环境变量
# 设置环境变量
vim /etc/profile

# 加入以下内容
NASM_HOME=/usr/local/nasm
YASM_HOME=/usr/local/yasm
X264_HOME=/usr/local/x264
PATH=$PATH:$NASM_HOME/bin:$YASM_HOME/bin:$X264_HOME/bin
export NASM_HOME YASM_HOME X264_HOME PATH

# 刷新配置
source /etc/profile

# 检测
x264 --version

  1. 安装libmp4v2、faac
# 1. 下载
mkdir -p /root/lib/{libmp4v2,faac}
dnf download --archlist=x86_64,noarch --resolve --destdir=./local-repo/media-deps/ \
libmp4v2 libmp4v2-devel faac faac-devel

# 2. 安装
dnf localinstall --disablerepo=* --skip-broken -y ./local-repo/media-deps/*.rpm

# 如果安装了本地仓库,可以直接安装
dnf --disablerepo=* --enablerepo=local libmp4v2 libmp4v2-devel faac faac-devel

4.4.2 【离线】离线安装​

  1. 安装x264
# 1. 解压
cd /root/resource
tar -jxvf x264-master.tar.bz2
cd x264-master

# 2. 编译安装
./configure --prefix=/usr/local/x264 --enable-shared --enable-static
make -j$(nproc) && make install

# 3. 检查版本
/usr/local/x264/bin/x264 --version

# 4. 配置动态链接库
vim /etc/ld.so.conf

# 加入以下内容
/usr/local/x264/lib/

# 加载动态链接库
ldconfig -v

# 5. 配置 pkgconfig
# ERROR: x264 not found using pkg-config
# pkg-config会搜索指定路径下的.pc文件,所以将.pc文件移动到指定目录下即可
cp /usr/local/x264/lib/pkgconfig/x264.pc /usr/share/pkgconfig/

  1. 设置环境变量
# 设置环境变量
vim /etc/profile

# 加入以下内容
NASM_HOME=/usr/local/nasm
YASM_HOME=/usr/local/yasm
X264_HOME=/usr/local/x264
PATH=$PATH:$NASM_HOME/bin:$YASM_HOME/bin:$X264_HOME/bin
export NASM_HOME YASM_HOME X264_HOME PATH

# 刷新配置
source /etc/profile

# 检测
x264 --version

  1. 安装libmp4v2、faac
# 1. 安装
rpm -ivh /root/lib/libmp4v2/*.rpm
rpm -ivh /root/lib/faac/*.rpm

4.5 编译安装Openssl(perl zlib)​

4.5.1 目前 CentOS 8.5.2111 自带的Openssl版本为 1.1.1k,满足ZLMediaKit的要求(> 1.1.0),不建议安装升级高版本的OpenSSL,可能会导致一些意外的错误,例如 openssl yum openssh 不可用等​

经测试,安装openssl 3.0.12 不替换默认的 openssl 1.1 ,在后续也会报错

4.5.2 【在线】【RPM安装】RPM安装 OpenSSL​

# 1. 下载YUM仓库的Openssl
dnf download --archlist=x86_64,noarch --resolve --destdir=./local-repo/media-deps/ \
openssl openssl-libs openssl-devel SDL-devel

# 2. 安装
dnf localinstall --disablerepo=* --skip-broken -y ./local-repo/media-deps/*.rpm

# 如果安装了本地仓库,可以直接安装
dnf --disablerepo=* --enablerepo=local openssl openssl-libs openssl-devel SDL-devel

4.5.3 【在线】【手动编译】在线下载和安装​

  1. 安装zlib(编译openssl需要)
# 1. 下载
dnf download --archlist=x86_64,noarch --resolve --destdir=./local-repo/media-deps/ \
zlib zlib-devel

# 2. 安装
dnf localinstall --disablerepo=* --skip-broken -y ./local-repo/media-deps/*.rpm

# 如果安装了本地仓库,可以直接安装
dnf --disablerepo=* --enablerepo=local zlib zlib-devel


# 如果openssl编译报错,单独安装 zlib zlib-devel
rpm -ivh /root/lib/zlib/zlib-1.2.11-17.el8.x86_64.rpm
rpm -ivh /root/lib/zlib/zlib-devel-1.2.11-17.el8.x86_64.rpm

  1. 手动编译 perl5 (编译openssl需要)
# 1. 下载
wget https://www.cpan.org/src/5.0/perl-5.32.1.tar.gz -O ./local-repo/binary/perl-5.32.1.tar.gz
tar -zxvf perl-5.32.1.tar.gz
cd perl-5.32.1

# 2. 编译安装
./Configure -des -Dprefix=/usr/local/perl
make -j$(nproc) && make install

# 3. 检查版本
perl --version

# 下面两个命令是由这两条安装的
# dnf install -y /root/lib/perl-ipc/*.rpm
# dnf install -y /root/lib/perl-pod/*.rpm
pod2man --help
pod2html --help

  1. 手动编译 openssl (openssl版本要求1.1.0以上)
# 1. 下载
# wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz -O ./local-repo/binary/openssl-1.1.1w.tar.gz
wget https://www.openssl.org/source/openssl-3.0.16.tar.gz -O ./local-repo/binary/openssl-3.0.16.tar.gz
tar -xvzf openssl-3.0.16.tar.gz
cd openssl-3.0.16

# 2. 编译安装
./config shared zlib --openssldir=/usr/local/openssl --prefix=/usr/local/openssl
make depend && make -j$(nproc) && make install

# 3. 配置和更新动态链接器运行时绑定
ldconfig

# 4. 检查版本
/usr/local/openssl/bin/openssl version -a

4.5.4 【离线】【手动编译】离线安装​

  1. 安装zlib(编译openssl需要)
# 1. 安装
rpm -ivh /root/lib/zlib/*.rpm

# 如果openssl编译报错,单独安装 zlib zlib-devel
rpm -ivh /root/lib/zlib/zlib-1.2.11-17.el8.x86_64.rpm
rpm -ivh /root/lib/zlib/zlib-devel-1.2.11-17.el8.x86_64.rpm

  1. 手动编译 perl5 (编译openssl需要)
# 1. 解压
cd /root/resource
tar -zxvf perl-5.32.1.tar.gz
cd perl-5.32.1

# 2. 编译安装
./Configure -des -Dprefix=/usr/local/perl
make -j$(nproc) && make install

# 3. 检查版本
perl --version

# 下面两个命令是由这两条安装的
# dnf install -y /root/lib/perl-ipc/*.rpm
# dnf install -y /root/lib/perl-pod/*.rpm
pod2man --help
pod2html --help

  1. 手动编译 openssl (openssl版本要求1.1.0以上)
# 1. 解压
cd /root/resource
tar -xvzf openssl-3.0.16.tar.gz
cd openssl-3.0.16

# 2. 编译安装
./config shared zlib --openssldir=/usr/local/openssl --prefix=/usr/local/openssl
make depend && make -j$(nproc) && make install

# 3. 配置和更新动态链接器运行时绑定
ldconfig

# 4. 检查版本
/usr/local/openssl/bin/openssl version -a

4.5.5 配置动态链接库和环境变量​

  1. 配置动态链接库
# 配置动态链接库
vim /etc/ld.so.conf

# 加入以下内容
/usr/local/lib64/
/usr/local/openssl/lib/
/usr/local/openssl/lib64/

# 加载动态链接库
ldconfig -v

  1. 设置环境变量
# 设置环境变量
vim /etc/profile

# 加入以下内容
NASM_HOME=/usr/local/nasm
YASM_HOME=/usr/local/yasm
X264_HOME=/usr/local/x264
OPENSSL_HOME=/usr/local/openssl
PATH=$PATH:$NASM_HOME/bin:$YASM_HOME/bin:$X264_HOME/bin:$OPENSSL_HOME/bin
export NASM_HOME YASM_HOME X264_HOME OPENSSL_HOME PATH

# 刷新配置
source /etc/profile

# 检测
openssl version -a

  1. 替换原Openssl

redhat8自己开发了一套函数,会打包在自己的libopenssl rpm包里,有些redhat提供的应用使用到这些函数; 在official的openssl源代码里没有这些函数; 所以如果是用redhat提供的openssl 最好不要自己build openssl

替换会导致部分依赖openssl的程序不可用,例如yum openssh等

# 备份原openssl
mv /usr/bin/openssl /usr/bin/openssl_bak
mv /usr/include/openssl /usr/include/openssl_bak
mv /usr/lib64/openssl /usr/lib64/openssl_bak
mv /usr/lib64/libssl.so /usr/lib64/libssl.so_bak

# 创建软链接
ln -sf /usr/local/openssl/bin/openssl /usr/bin/openssl # 替换系统openssl,非必须
ln -sf /usr/local/openssl/include/openssl /usr/include/openssl
ln -sf /usr/local/openssl/lib/libssl.so /usr/lib64/libssl.so
ln -sf /usr/local/openssl/lib/libssl.so.1.1 /usr/lib64/libssl.so.1.1
ln -sf /usr/local/openssl/lib/libcrypto.so /usr/lib64/libcrypto.so
ln -sf /usr/local/openssl/lib/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1


rm -rf /usr/lib64/libcrypto.so.1.1
ln -sf /usr/local/openssl/lib64/libcrypto.so.3 /usr/lib64/libcrypto.so.3

ll /usr/lib64/libssl*
ll /usr/lib64/libcrypt*

[root@centos openssl-1.1.1w]# ll /usr/lib64/libssl*
lrwxrwxrwx. 1 root root 16 12月 3 2021 /usr/lib64/libssl.so.1.1 -> libssl.so.1.1.1k
-rwxr-xr-x. 1 root root 615704 12月 3 2021 /usr/lib64/libssl.so.1.1.1k
[root@centos openssl-1.1.1w]# ll /usr/lib64/libcrypt*
lrwxrwxrwx. 1 root root 19 12月 3 2021 /usr/lib64/libcrypto.so.1.1 -> libcrypto.so.1.1.1k
-rwxr-xr-x. 1 root root 3079664 12月 3 2021 /usr/lib64/libcrypto.so.1.1.1k
lrwxrwxrwx. 1 root root 23 2月 19 2021 /usr/lib64/libcryptsetup.so.12 -> libcryptsetup.so.12.6.0
-rwxr-xr-x. 1 root root 510096 2月 19 2021 /usr/lib64/libcryptsetup.so.12.6.0
lrwxrwxrwx. 1 root root 17 5月 6 2021 /usr/lib64/libcrypt.so -> libcrypt.so.1.1.0
lrwxrwxrwx. 1 root root 17 5月 6 2021 /usr/lib64/libcrypt.so.1 -> libcrypt.so.1.1.0
-rwxr-xr-x. 1 root root 136040 5月 6 2021 /usr/lib64/libcrypt.so.1.1.0

# 检查版本
openssl version -a

4.6 安装 libsrtp FFmpeg​

4.6.1 【在线】在线下载和安装​

  1. 手动编译 libsrtp
# 1. 下载
# wget https://github.com/cisco/libsrtp/archive/refs/tags/v2.3.0.tar.gz -O ./local-repo/binary/libsrtp-2.3.0.tar.gz
# wget https://github.com/cisco/libsrtp/archive/refs/tags/v2.7.0.tar.gz -O ./local-repo/binary/libsrtp-2.7.0.tar.gz
wget https://github.com/cisco/libsrtp/archive/refs/tags/v2.5.0.tar.gz -O ./local-repo/binary/libsrtp-2.5.0.tar.gz
tar -xvzf libsrtp-2.5.0.tar.gz
cd libsrtp-2.5.0

# 2. 编译配置
# 默认openssl,需要安装 openssl-devel
./configure --enable-openssl

# 手动编译的openssl
# ./configure --enable-openssl --with-openssl-dir=/usr/local/openssl

# 3. 编译安装
make -j$(nproc) && make install

  1. 安装FFmpeg
# 1. 下载  
# ffmpeg-4.4 是最后一个支持openssl 1.1.1的版本,ffmpeg-4.4.5开始需要openssl 3.0
# wget https://ffmpeg.org/releases/ffmpeg-4.3.tar.gz -O ./local-repo/binary/ffmpeg-4.3.tar.gz
# wget https://ffmpeg.org/releases/ffmpeg-6.1.2.tar.gz -O ./local-repo/binary/ffmpeg-6.1.2.tar.gz
# wget https://ffmpeg.org/releases/ffmpeg-7.1.1.tar.gz -O /root/resource/ffmpeg-7.1.1.tar.gz
wget https://ffmpeg.org/releases/ffmpeg-4.4.tar.gz -O ./local-repo/binary/ffmpeg-4.4.tar.gz
tar -xvf ffmpeg-4.4.tar.gz
cd ffmpeg-4.4

# 2. 编译安装
# ./configure --prefix=/usr/local/ffmpeg
./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-libx264 --enable-static --disable-shared --extra-libs=-ldl --enable-encoder=libx264 --enable-openssl --enable-nonfree
# ./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-libx264 --enable-static --disable-shared --extra-libs=-ldl --enable-openssl --extra-cflags="-I/usr/local/openssl/include" --extra-ldflags="-L/usr/local/openssl/lib" --enable-encoder=libx264 --extra-ldflags="-L/usr/local/x264/lib" --enable-nonfree
make -j$(nproc) && make install

# 3. 检查版本
/usr/local/ffmpeg/bin/ffmpeg -version

4.6.2 【离线】离线安装​

  1. 手动编译 libsrtp
# 1. 解压
cd /root/resource
tar -xvzf libsrtp-2.5.0.tar.gz
cd libsrtp-2.5.0

# 2. 编译配置
# 默认openssl,需要安装 openssl-devel
./configure --enable-openssl

# 手动编译的openssl
# ./configure --enable-openssl --with-openssl-dir=/usr/local/openssl

# 3. 编译安装
make -j$(nproc) && make install

  1. 安装FFmpeg
# 1. 解压
cd /root/resource
tar -xvf ffmpeg-4.4.tar.gz
cd ffmpeg-4.4

# 2. 编译安装
./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-libx264 --enable-static --disable-shared --extra-libs=-ldl --enable-encoder=libx264 --enable-openssl --enable-nonfree
make -j$(nproc) && make install

# 3. 检查版本
/usr/local/ffmpeg/bin/ffmpeg -version

4.6.3 配置动态链接库和环境变量​

  1. 配置动态链接库
# 配置动态链接库
vim /etc/ld.so.conf

# 加入以下内容
/usr/local/ffmpeg/lib/

# 加载动态链接库
ldconfig -v

  1. 设置环境变量
# 设置环境变量
vim /etc/profile

# 加入以下内容
NASM_HOME=/usr/local/nasm
YASM_HOME=/usr/local/yasm
X264_HOME=/usr/local/x264
FFMPEG_HOME=/usr/local/ffmpeg
PATH=$PATH:$NASM_HOME/bin:$YASM_HOME/bin:$X264_HOME/bin:$FFMPEG_HOME/bin
export NASM_HOME YASM_HOME X264_HOME FFMPEG_HOME PATH

# 刷新配置
source /etc/profile

# 检查版本
ffmpeg -version

五、安装ZLMediaKit​

5.1 下载ZLMediaKit源码​

# 国内用户推荐从同步镜像网站gitee下载 
git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit

cd ZLMediaKit

# 千万不要忘记执行这句命令
git submodule update --init

5.2 编译安装ZLMediaKit​

  1. 检查依赖
# 检查依赖
gcc --version
g++ --version
cmake --version
openssl version
ffmpeg -version

  1. 编译
mkdir -p /root/ZLMediaKit/build
cd /root/ZLMediaKit/build

# 不启用webrtc编译
# cmake .. && make -j4

# 启用webrtc编译
cmake .. -DENABLE_WEBRTC=true -DOPENSSL_ROOT_DIR=/usr/local/openssl -DOPENSSL_LIBRARIES=/usr/local/openssl/lib
cmake --build . --target MediaServer

5.3 修改配置文件​

配置文件在 /root/ZLMediaKit/release/linux/Debug/config.ini

5.3.1 WVP集成配置​

[api]
apiDebug=1
defaultSnap=./www/logo.png
# 修改和记录秘钥,与WVP中匹配
secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc
snapRoot=./www/snap/

[general]
check_nvidia_dev=1
enableVhost=0
enable_ffmpeg_log=0
flowThreshold=1024
maxStreamWaitMS=15000
# 修改和记录MediaServerId,与WVP中匹配
mediaServerId=FQ3TF8yT83wh5Wvz
mergeWriteMS=0
resetWhenRePlay=1
streamNoneReaderDelayMS=20000
unready_frame_cache=100
wait_add_track_ms=3000
wait_track_ready_ms=10000

5.3.1 WebRTC配置​

由于webrtc协议需要告知播放器服务器所在ip,如果该ip对播放器不可见,会导致webrtc无法联通。请修改配置文件中rtc.externIP为播放器可见ip,如果不设置该配置项,zlmediakit将获取网卡ip(一般是内网ip),那么将无法跨域nat使用webrtc。

[rtc]
#rtc播放推流、播放超时时间
timeoutSec=15
#本机对rtc客户端的可见ip,作为服务器时一般为公网ip,置空时,会自动获取网卡ip
externIP=192.168.137.126
#rtc udp服务器监听端口号,所有rtc客户端将通过该端口传输stun/dtls/srtp/srtcp数据,
#该端口是多线程的,同时支持客户端网络切换导致的连接迁移
#需要注意的是,如果服务器在nat内,需要做端口映射时,必须确保外网映射端口跟该端口一致
port=8000
#设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
rembBitRate=1000000

5.4 防火墙配置​

# 开放端口
firewall-cmd --permanent --zone=public --add-port=80/tcp # http (hls http-ts)
firewall-cmd --permanent --zone=public --add-port=443/tcp # https
firewall-cmd --permanent --zone=public --add-port=1935/tcp # rtmp
firewall-cmd --permanent --zone=public --add-port=10000/tcp # rtp_proxy
firewall-cmd --permanent --zone=public --add-port=10000/udp # rtp_proxy
firewall-cmd --permanent --zone=public --add-port=30000-35000/udp # rtp 推送端口,至少36个端口
firewall-cmd --permanent --zone=public --add-port=8000/tcp # rtc
firewall-cmd --permanent --zone=public --add-port=8000/udp # rtc
firewall-cmd --permanent --zone=public --add-port=9000/udp # srt
firewall-cmd --permanent --zone=public --add-port=554/tcp # rtsp
firewall-cmd --permanent --zone=public --add-port=554/udp # rtsp
firewall-cmd --permanent --zone=public --add-port=18080/tcp # WVP http端口
firewall-cmd --permanent --zone=public --add-port=18081/tcp # 录像管理端口

# 刷新配置
firewall-cmd --reload

# 查看开放的端口
firewall-cmd --list-port

# 查看所有防火墙规则
firewall-cmd --list-all

5.4 运行​

cd /root/ZLMediaKit/release/linux/Debug

# 通过-h可以了解启动参数
./MediaServer -h

#以守护进程模式启动
./MediaServer -d &

# 将编译后的文件复制到 /usr/local
mkdir /usr/local/zlmedia
cp /root/ZLMediaKit/release/linux/Debug/* /usr/local/zlmedia

# 安装为服务
cat >> /etc/systemd/system/zlmedia.service << 'EOF'
[Unit]
Description=ZLMedia Service
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/usr/local/zlmedia
ExecStart=/usr/local/zlmedia/MediaServer -d
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

EOF

# 重载 systemd
systemctl daemon-reload

# 验证服务状态
systemctl list-unit-files | grep zlmedia

# 诊断错误原因
systemd-analyze verify /etc/systemd/system/zlmedia.service

# 启动服务
systemctl start zlmedia

5.5 测试​

最新的zlmediakit源码自带有效的ssl证书default.pem,对应的域名是default.zlmediakit.com,该域名解析到的ip为127.0.0.1,用户在浏览器中打开测试链接 即可开始测试。请先推流后,再测试播放。如果webrtc无法播放, 请参考此issue

六、编译安装WVP-Pro​

6.1 前端编译安装​

  1. 拉取代码
# 1. 拉取代码
git clone http://113.57.121.225:3001/Pi-Diginn/wvp-front.git
cd wvp-front

# 2. 安装依赖
npm --registry=https://registry.npmmirror.com install

  1. 修改环境配置 config/prod.env.js
'use strict'
module.exports = {
NODE_ENV: '"production"',
// pi-diginn-web地址
PI_DIGINN_WEB_URL: '"diginn.pisx.local:9096"',
// PI_DIGINN_WEB_URL: '"113.57.121.225:9096"',
// PI_DIGINN_WEB_URL: '"114.55.234.250:9096"',
WVP_WEB_URL: '"diginn.pisx.local:9096"'
// WVP_WEB_URL: '"113.57.121.225:9096"'
// WVP_WEB_URL: '"114.55.234.250:9096"'
}

测试地址需要修改主机hosts文件 192.168.137.1 diginn.pisx.local

  1. 打包静态文件
# 打包静态文件
npm run build

  1. 将得到的dist目录放到nginx下 html/wvp

添加配置文件 conf.d/diginn.conf

upstream diginn_nginx {
server 192.168.137.1:9096;
}

upstream diginn_oauth {
server 192.168.137.1:31888;
}

upstream diginn_system {
server 192.168.137.1:31112;
}

upstream diginn_thing {
server 192.168.137.1:31111;
}

upstream diginn_message {
server 192.168.137.1:31890;
}

upstream diginn_plugin {
server 192.168.137.1:31116;
}

upstream diginn_workflow {
server 192.168.137.1:31113;
}

upstream diginn_usability {
server 192.168.137.1:31789;
}

upstream diginn_wvp {
server 192.168.137.1:31117;
}

upstream diginn_demo {
server 192.168.137.1:31112;
}

# websocket
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
listen 9096;
listen [::]:9096;
server_name diginn.pisx.local;

#access_log /var/log/nginx/host.access.log main;

location / {
root html/diginn;
index index.html index.htm;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.html?s=$1 last;
break;
}
}

location /monitor {
alias html/wvp;
index index.html index.htm;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.html?s=$1 last;
break;
}
}

location ^~ /oauth/ {
proxy_pass http://diginn_oauth/oauth/;
proxy_http_version 1.1;
proxy_read_timeout 30s;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}

location ^~ /system/ {
proxy_pass http://diginn_system;
proxy_http_version 1.1;
proxy_read_timeout 30s;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}

location ^~ /thing/ {
proxy_pass http://diginn_thing;
proxy_http_version 1.1;
proxy_read_timeout 30s;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}

location ^~ /message/ {
proxy_pass http://diginn_message;
proxy_http_version 1.1;
proxy_read_timeout 30s;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}

location ^~ /plugin/ {
proxy_pass http://diginn_plugin;
proxy_http_version 1.1;
proxy_read_timeout 30s;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}

location ^~ /workflow/ {
proxy_pass http://diginn_workflow;
proxy_http_version 1.1;
proxy_read_timeout 30s;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}

location ^~ /usability/ {
proxy_pass http://diginn_usability;
proxy_http_version 1.1;
proxy_read_timeout 30s;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}

location ^~ /wvp/ {
proxy_pass http://diginn_wvp;
proxy_http_version 1.1;
proxy_read_timeout 30s;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}


# 使用捕获组 $1 来传递剩余路径 /demo/123 -> /123
location ~ ^/demo(/.*)$ {
proxy_pass http://diginn_demo$1;
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

# 图片防盗链
location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked 192.168.9.21; # 只允许本机IP外链引用
if ($invalid_referer){
return 403;
}
}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

6.2 运行 wvp-pro 后端服务​

修改 application-wvp-local.yaml 配置,设置 media.ip media.hook-ip media.sdp-ip 等

spring:
# [可选]上传文件大小限制
servlet:
multipart:
max-file-size: 10MB
max-request-size: 100MB
# # REDIS数据库配置
# redis:
# # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
# host: 127.0.0.1
# # [必须修改] 端口号
# port: 6379
# # [可选] 数据库 DB
# database: 6
# # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
# password: 62g@A71u2sx
# # [可选] 超时时间
# timeout: 10000
# # mysql数据源
# datasource:
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
# username: root
# password: pisx@mysql
# druid:
# initialSize: 10 # 连接池初始化连接数
# maxActive: 200 # 连接池最大连接数
# minIdle: 5 # 连接池最小空闲连接数
# maxWait: 60000 # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
# keepAlive: true # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。
# validationQuery: select 1 # 检测连接是否有效sql,要求是查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
# testWhileIdle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
# testOnBorrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
# testOnReturn: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
# poolPreparedStatements: false # 是否開啟PSCache,並且指定每個連線上PSCache的大小
# timeBetweenEvictionRunsMillis: 60000 # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒
# minEvictableIdleTimeMillis: 300000 # 配置一個連線在池中最小生存的時間,單位是毫秒
# filters: stat,slf4j # 配置监控统计拦截的filters,监控统计用的filter:sta, 日志用的filter:log4j
# useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据
# # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
# connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000
# #stat-view-servlet.url-pattern: /admin/druid/*

#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
server:
port: 31117

# 作为28181服务器的配置
sip:
# [必须修改] 本机的IP
ip: 0.0.0.0
# [可选] 28181服务监听的端口
port: 30405
# 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
# 后两位为行业编码,定义参照附录D.3
# 4201110000标识湖北省武汉市洪山区 信息行业接入
# [可选]
domain: 3402000000
# [可选]
id: 34020000002000000001
# [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
password: pisx@2023

#zlm 默认服务器配置
media:
id: FQ3TF8yT83wh5Wvz
# [必须修改] zlm服务器的内网IP
ip: 192.168.9.30
# [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip
hook-ip: 192.168.8.119
# [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
sdp-ip: 192.168.8.119
# [可选] 返回流地址时的ip,置空使用 media.ip
stream-ip: 192.168.9.30
# [必须修改] zlm服务器的http.port
http-port: 80
# [可选] zlm服务器的hook.admin_params=secret
secret: GVuK9EAuuNujz6xU5DzQOKexFvblb0YV
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
rtp:
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
enable: true
# [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功
port-range: 30000,30500 # 端口范围
# [可选] 国标级联在此范围内选择端口发送媒体流,
send-port-range: 30000,30500 # 端口范围
# 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
record-assist-port: 18081
# [自定义] ZLM 映射的IP地址
public-stream-ip: 192.168.9.30
# [可选] 日志配置, 一般不需要改
logging:
config: classpath:logback-spring-local.xml


# 作为oauth客户端接入第三方登录
oauth:
clients:
# 创新平台登录配置
pi-diginn:
client-id: wvp
client-secret: 7mevh7atoq23f9xcqgqsmr4ny8v2ufp0rsg7z2p2bidnvj7tsq
redirect-uri: http://diginn.pisx.local:9096/monitor/
authorize-url: http://diginn.pisx.local:9096/oauth/oauth/authorize
token-url: http://diginn.pisx.local:9096/oauth/oauth/token
userinfo-url: http://diginn.pisx.local:9096/oauth/user
scope: all
pi-diginn-test:
client-id: wvp-local
client-secret: 7mevh7atoq23f9xcqgqsmr4ny8v2ufp0rsg7z2p2bidnvj7tsq
redirect-uri: http://diginn.pisx.local:9006/
authorize-url: http://diginn.pisx.local:9096/oauth/oauth/authorize
token-url: http://diginn.pisx.local:9096/oauth/oauth/token
userinfo-url: http://diginn.pisx.local:9096/oauth/user
scope: all

pd:
wvp:
# wvp的访问地址
url: http://diginn.pisx.local:9096/wvp

七、OBS推流​

1. 新建场景​

2. 新建媒体源​

新建源

选择本地MP4文件

3. 设置推流信息​

生成推流链接 MD5在线加密/解密/破解—MD5在线 需要修改的地方 ip 端口(默认1935) sign(用户表里找pushkey然后MD5小写加密)

  • 服务器: rtmp://192.168.137.126:1935/obs。 ZLM的IP + rtmp端口 + APP名称
  • 推流码: push_mp4?sign=41db35390ddad33f83944f44b8b75ded wvp_user表查pushKey。 流ID + sign=md5(pushKey)

开始推流

4. 播放视频流​

Jessibuca播放

WebRTC播放

PortPlayer播放

八、接入国标摄像头​

8.1 摄像头配置​

参数示例值对应wvp配置属性属性说明
SIP服务器ID34020000002000000001sip.id
SIP服务器域3402000000sip.domain
SIP服务器地址192.168.8.119sip.ip多个网卡时要指定为摄像头可访问的ip
SIP服务器端口30405sip.port
SIP用户名34020000001320000013自定义
SIP用户认证ID34020000001320000013自定义
密码••••••sip.password
密码确认••••••sip.password
注册有效期3600 秒自定义
注册状态在线自定义
心跳周期10 秒自定义
28181码流索引主码流(定时)自定义
注册间隔60 秒自定义
最大心跳超时次数3自定义

8.2 启动wvp​

启动WVP,可以看到主动连接ZLM,并接收到了设备的注册信息

查看ZLM的日志,可以看到先调用了 /index/api/getServerConfig /index/api/getMediaList 获取ZLM的配置信息

再调用了 /index/api/setServerConfig 设置hook回调地址信息

8.3 WEB端查看摄像头信息​

可以看到自动注册的设备信息

打开通道列表

点击播放按钮

切换WenRTC播放

查看ZLM日志,可以看到收到两个请求 /index/api/getRtpInfo /index/api/webrtc?app=rtp&stream=34020000001320000013_34020000001320000013&type=play,分别对应Jessibuca和webrtc播放

常见问题​

一、点播收流超时 Github issue#289​

故障原因​

这通常是摄像头网络无法联通ZLMediaServer导致的

解决方案​

在摄像头配置中开启SSH

测试摄像头与ZLM WVP的网络互通情况

然后检查ZLM的防火墙是否关闭(或者端口放行规则是否配置)

二、WebRTC播放报错​

Chrome浏览器升级到123版本后,zlmediakit的webrtc无法播放,无法建立连接问题

报错信息如下

 [RTCPusherPlayer] OperationError: Failed to execute 'setRemoteDescription' on 'RTCPeerConnection': Failed to parse SessionDescription.  Duplicate a=msid lines detected
at e.RTCPeerConnection.setRemoteDescription (liveplayer-lib.min.js:1:1198473)
at RTCPeerConnection.setRemoteDescription (common_shim.js:214:39)
at endpoint.js:119:29

故障原因​

这是因为Chrome浏览器升级到123版本后更改了rtp机制导致的。(https://issues.webrtc.org/issues/42226210)

webrtc 返回的sdp中的msid是相同的,chrome更新完后会有这个问题,在WebRtcTransport.cpp修改 ssrc.msid = RTP_MSID + to_string(i++); 这一行,使msid不一样就好了

解决方案:​

  1. 合并fix代码:Commit 1e39594
  2. 更新编译zlmeidakit版本到最新版本

WebRTC播放失败,转圈​

故障原因​

一般是因为网络不通,如设备(摄像头)及服务(wvp zlm)部署通过内网IP通讯,通过公网访问视频页面时会出现WebRTC一直转圈的情况

解决方案​

这时可以将zlm rtc配置改为内网ip测试

[rtc]
bfilter=0
datachannel_echo=1
#externIP=113.57.121.225 # 将此处的公网IP改为内网
externIP=192.168.1.213
maxRtpCacheMS=5000
maxRtpCacheSize=2048
max_bitrate=0
min_bitrate=0
nackIntervalRatio=1.0
nackMaxCount=15
nackMaxMS=3000
nackMaxSize=2048
nackRtpSize=8
port=8000
preferredCodecA=PCMA,PCMU,opus,mpeg4-generic
preferredCodecV=H264,H265,AV1,VP9,VP8
rembBitRate=0
start_bitrate=0
tcpPort=8000
timeoutSec=15

如果可以正常播放,需要将公网IP防火墙规则对应的8000/tcp 8000/udp 开放出来

语音对讲报错 navigator.mediaDevices is undefined​

报错信息如下

TypeError: Cannot read properties of undefined (reading 'getUserMedia')

当时的场景是公司搭建的内部服务网站没有测试环境(有点鸡肋,说是因为需要线上成员信息认证登录),也因为跨域问题,所以需要制定线上环境的域名,本地localhost用不了,协议是http的,导致接入一个语音需求的时候本地调试出现了问题。

故障原因​

主要原因是浏览器的安全策略导致了这个问题

// 兼容性处理
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;

if (navigator.getUserMedia) {
// 支持
console.log('支持');
console.log(navigator.getUserMedia);
} else {
// 不支持
console.log('navigator.getUserMedia - 不支持');
}

// 新版 API 优先
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
// 现代浏览器
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(handleSuccess)
.catch(handleError);
} else if (navigator.getUserMedia) {
// 旧版浏览器兼容
navigator.getUserMedia({ video: true, audio: true }, handleSuccess, handleError);
} else {
console.log("当前浏览器不支持媒体设备访问");
}

<!DOCTYPE html>
<html>
<body>
<button onclick="startCapture()">获取媒体设备</button>
<video id="video" autoplay></video>

<script>
// 兼容性处理
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;

if (navigator.getUserMedia) {
// 支持
console.log('支持');
console.log(navigator.getUserMedia);
} else {
// 不支持
console.log('navigator.getUserMedia - 不支持');
}

// 新版 API 优先
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
// 现代浏览器
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(handleSuccess)
.catch(handleError);
} else if (navigator.getUserMedia) {
// 旧版浏览器兼容
navigator.getUserMedia({ video: true, audio: true }, handleSuccess, handleError);
} else {
console.log("当前浏览器不支持媒体设备访问");
}

function handleSuccess(stream) {
console.log("成功获取媒体流");
const video = document.getElementById('video');
video.srcObject = stream;
}

function handleError(error) {
console.error("获取媒体失败:", error.name, error.message);
}

function startCapture() {
// 通过按钮触发(浏览器要求用户主动交互)
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(handleSuccess)
.catch(handleError);
}
}
</script>
</body>
</html>

navigator.mediaDevices在目前以下三种情况下可以获取到

  1. 地址为localhost:// 访问时
  2. 地址为https:// 时
  3. 为文件访问file://

解决方案有三种

1. 采用https方案​

由于线上环境都是https协议的,所以这个不用考虑,只是本地调试是一个大问题,所以忽略

2. 采取修改chrome浏览器的安全策略​

  1. 浏览器地址栏输入 edge://flags/#unsafely-treat-insecure-origin-as-secure chrome://flags/#unsafely-treat-insecure-origin-as-secure
  2. 将该 Disabled 切换成 Enable 状态;
  3. 在输入框中填写需要开启的域名或地址(带上端口号),如果有多个,则以逗号分隔;
    • http://aio.pisx.com:9092
  4. 重启浏览器后生效

3. 在本地做了一次proxy,我的项目是vue的,在vue.config.js中添加:​

devServer: {
port: 8000,
disableHostCheck: true,
host: 'aio.pisx.com',
https: true
}

采用第2、3套方案可以解决本地调试问题,如果线上不是https协议,那就要申请证书了