文章目录
- [1 概要](#1 概要)
- [2 移植 Nginx](#2 移植 Nginx)
-
- [2.1 准备Nginx所需包](#2.1 准备Nginx所需包)
-
- [2.1.1 准备nginx-rtmp-module依赖](#2.1.1 准备nginx-rtmp-module依赖)
- [2.1.2 准备openssl依赖](#2.1.2 准备openssl依赖)
- [2.1.3 准备zlib依赖](#2.1.3 准备zlib依赖)
- [2.1.4 准备pcre依赖](#2.1.4 准备pcre依赖)
- [2.1.4 下载Nginx](#2.1.4 下载Nginx)
- [2.2 交叉编译Nginx](#2.2 交叉编译Nginx)
- [2.2.1 更改1 auto/cc/name](#2.2.1 更改1 auto/cc/name)
- [2.2.2 更改2 ./objs/Makefile](#2.2.2 更改2 ./objs/Makefile)
- [2.2.3 更改3 objs/ngx_auto_config.h](#2.2.3 更改3 objs/ngx_auto_config.h)
- [2.3 编译](#2.3 编译)
- [3 总结](#3 总结)
1 概要
目前常见的视频监控和视频直播都是使用了 RTMP 和 RTSP 流媒体传输协议等。
RTSP(Real-Time Stream Protocol)由 Real Networks 和 Netscape 共同提出的,基于文本的多媒体播放控制协议。RTSP 定义流格式,流数据经由 RTP 传输;RTSP 实时效果非常好,适合视频聊天,视频监控等方向。
RTMP(Real Time Message Protocol)由 Adobe 公司提出,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题,优势在于低延迟,稳定性高,支持所有摄像头格式,浏览器
加载 flash 插件就可以直接播放。
RTSP 和 RTMP 的区别:
RTSP 虽然实时性最好,但是实现复杂,适合视频聊天和视频监控;RTMP 强在浏览器支持好,加载 flash插件后就能直接播放,所以非常火,相反在浏览器里播放 rtsp 就很困难了。
本章我们将向大家介绍如何通过 FFmpeg+Nginx、使用 RTMP 推流实现视频监控或直播。 本章将会讨论如下主题内容。
- 视频监控简介
- 如何移植 Nginx
- FFmpeg+Nginx 实现 RTMP 推流
- 拉流
2 移植 Nginx
我们将会在STM32MP157上移植Nginx,其中会遇到一些bug,需要我们一步步去修正。
2.1 准备Nginx所需包
首先我们需要准备四个依赖包 nginx-rtmp-module,openssl,zlib,pcre:

其中:
- nginx-rtmp-module:
原生的 Nginx 并不支持 RTMP,我们需要安装第三方模块 nginx-rtmp-module 插件使其支持RTMP。 - openssl(安全保镖):
它是 Nginx 的"加密通信基石",核心职责是实现 SSL/TLS 协议。它负责在客户端与你的开发板之间建立加密通道(包括握手、证书验证、数据加解密),是你实现 HTTPS 安全访问、启用 HTTP/2 高效协议以及 RTMPS 加密直播流的强制性依赖;没有它,你的所有数据传输都将是明文裸奔,且无法适配现代浏览器的安全标准。 - PCRE (路由调度员):
它是 Nginx 的"逻辑大脑",核心职责是提供正则表达式匹配能力。在 Nginx 中,无论是通过 location 指令区分不同的 URL 路径(如区分 /video 和 /image),还是使用 rewrite 实现地址重写(伪静态),甚至是你 RTMP 模块中对推流密钥的解析,全都要靠它来识别和分发;没有它,Nginx 就无法灵活地处理复杂的请求路由。 - Zlib (流量压缩机)
它是 Nginx 的"传输优化器",核心职责是提供 Gzip 压缩算法。当 Nginx 需要向浏览器发送 HTML、CSS、JS 等文本文件时,Zlib 会在发送前对数据进行实时压缩(体积通常能减小 60%-80%),这对 STM32MP157 这种嵌入式设备至关重要,因为它能大幅节省宝贵的网络带宽,让网页加载更快,减轻 CPU 发送数据的 I/O 压力。
我们首先创建目录:
c
/home/lbh/RTMP_Project/nginx_cross/src

之后将会在这个目录之下进行我们的交叉编译。
2.1.1 准备nginx-rtmp-module依赖
在/home/lbh/RTMP_Project/nginx_cross/src运行如下命令:
c
git clone https://github.com/arut/nginx-rtmp-module.git

2.1.2 准备openssl依赖
c
wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz
tar -zxvf openssl-1.1.1w.tar.gz

2.1.3 准备zlib依赖
c
# 下载 zlib
wget https://zlib.net/fossils//zlib-1.2.13.tar.gz
tar -zxvf zlib-1.2.13.tar.gz
2.1.4 准备pcre依赖
c
# 下载 PCRE (注意不是 pcre2,Nginx 1.20 默认用 pcre)
wget https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz/download -O pcre-8.45.tar.gz
tar -zxvf pcre-8.45.tar.gz
2.1.4 下载Nginx
c
wget http://nginx.org/download/nginx-1.20.0.tar.gz
tar -xzf nginx-1.20.0.tar.gz
下载完成后目录如下:

2.2 交叉编译Nginx
这一部分稍微有一点复杂,因为Nginx在编译过程中同时也会去依赖里面生成其对应的Makefile文件,但是传递交叉编译工具的过程中会出现问题,因此会出现大大小小的编译bug,接下来我们选哟改一下代码以使其可以正常编译。
首先我们要设置交叉编译工具:这里输入你自己的交叉编译工具路径
c
export PATH=$PATH:/usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/bin \
export CROSS_COMPILE=arm-none-linux-gnueabihf- \
export CC=${CROSS_COMPILE}gcc \
export CXX=${CROSS_COMPILE}g++ \
随后进入到nginx目录中
c
cd /home/lbh/RTMP_Project/nginx_cross/src/nginx-1.20.0
随后开始更改代码。
2.2.1 更改1 auto/cc/name
首先第一步是配置源码,在配置之前,需要进行一个简单的修改,否则配置通不过;首先打开 nginx 源码目录下的 auto/cc/name 文件,将 21 行处的"exit 1"给注释掉!如下所示:
修改完成之后保存退出。接着打开 auto/types/sizeof 文件,将 15 行处的" ngx_size="修改为" ngx_size=4",并且将 36 行处的"$CC"修改为"arm-none-linux-gnueabihf-gcc",如下所示:

随后在/home/lbh/RTMP_Project/nginx_cross/src/nginx-1.20.0目录下运行如下编译指令:
c
./configure --prefix=/home/lbh/RTMP_Project/nginx_cross/src/nginx-1.20.0/install \
--with-http_ssl_module \
--with-http_mp4_module \
--with-http_v2_module \
--with-openssl=../openssl-1.1.1w \
--with-openssl-opt="no-asm no-tests linux-generic32" \
--without-http_upstream_zone_module \
--add-module=../nginx-rtmp-module \
--with-cc=${CROSS_COMPILE}gcc \
--with-cpp=${CROSS_COMPILE}cpp \
--with-pcre=../pcre-8.45 \
--with-zlib=../zlib-1.2.13 \
之后会在./objs/目录下生成Makefile文件,我们需要对齐进行修改。
2.2.2 更改2 ./objs/Makefile
蓝色为改动的地方,主要是为了解决传入的交叉编译工具链不对问题,蓝色的区域为改动处,其中openssl原本所示config,这里直接调用其底层文件Configure来进行编译

c
../pcre-8.45/Makefile: objs/Makefile
cd ../pcre-8.45 \
&& if [ -f Makefile ]; then $(MAKE) distclean; fi \
&& CC="$(CC)" CFLAGS="-O2 -fomit-frame-pointer -pipe" \
./configure --disable-shared --host=arm-linux-gnueabihf
c
../openssl-1.1.1w/.openssl/include/openssl/ssl.h: objs/Makefile
cd ../openssl-1.1.1w \
&& if [ -f Makefile ]; then $(MAKE) clean; fi \
&& ./Configure --prefix=/home/lbh/RTMP_Project/nginx_cross/src/nginx-1.20.0/../openssl-1.1.1w/.openssl no-shared no-threads no-asm no-tests linux-generic32 \
&& $(MAKE) CC=arm-none-linux-gnueabihf-gcc \
&& $(MAKE) install_sw LIBDIR=lib
2.2.3 更改3 objs/ngx_auto_config.h
加入如下宏定义,不然因为PC机是x86-64,会导致出现某某变量undefined报错。
c
#ifndef NGX_HAVE_SYSVSHM
#define NGX_HAVE_SYSVSHM 1
#endif

2.3 编译
之后执行如下指令即可:
c
make -j8
make install
成功界面如下:

3 总结
本章节讲述了如何移植Nginx。