新建   文章列表   相册  后台  网摘
 

Kreos

Kreos 无所不能

第三十四章 实战小项目之视频监控(学习笔记)

注意:该项目只适用 OV5640 摄像头和支持 UVC 协议的 USB 摄像头,其他摄像头是没有做适配。
目前常见的视频监控和视频直播都是使用了 RTMP 和 RTSP 流媒体传输协议等。

RTSP RTMP

RTSP(Real-Time Stream Protocol)由 Real Networks 和 Netscape 共同提出的,

基于文本的多媒体播放控制协议。

RTSP 定义流格式,流数据经由 RTP 传输;

RTSP 实时效果非常好,适合视频聊天,视频监控等方向。

 RTMP(Real Time Message Protocol)由 Adobe 公司提出,

用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题,

优势在于低延迟,稳定性高,支持所有摄像头格式,

浏览器加载 flash 插件就可以直接播放。

 

区别:RTSP 虽然实时性最好,但是实现复杂,适合视频聊天和视频监控;

区别:RTMP 强在浏览器支持好,加载 flash插件后就能直接播放,所以非常火,相反在浏览器里播放 rtsp 就很困难了。

  本章我们将向大家介绍如何通过 FFmpeg+Nginx、使用 RTMP 推流实现视频监控或直播。

  本章将会讨论如下主题内容。


⚫ 视频监控简介
⚫ Nginx 简介
⚫ 如何移植 Nginx
⚫ FFmpeg+Nginx 实现 RTMP 推流
⚫ 拉流


34.1 视频监控简介
  本章我们将使用 RTMP 流媒体服务来实现视频监控,RTMP 流媒体服务框架图如下所示:

image

 图 34.1.1 流媒体服务

 

  所以从上图可知,要想实现 RTMP 视频监控,必须要有这三部分:推流客户端、拉流客户端以及流媒体服务器。

那这些需要我们自己去实现吗?当然不需要,譬如:

推流端负责将视频数据通过 RTMP 流媒体协议传输给 RTMP 流媒体服务器,
推流我们可以使用 FFmpeg 来做,
拉流端可以从流媒体服务器中通过 RTMP 协议获取到视频数据;
拉流则可以实现 VLC 播放器来做,
流媒体服务器负责接收推流端的视频数据、当有客户端(拉流端)想要获取视频数据时再将其发给相应的客户端。
流媒体服务端则使用 Nginx 来搭建即可!





34.2 Nginx 移植
  前面也给大家提到了,我们可以使用 Nginx 来搭建 RTMP 流媒体服务器,譬如你可以在一台公网 IP 主机上搭建流媒体服务器,当然,笔者并没有这个条件;

这里我们选择在开发板上搭建流媒体服务器,并且推流端也是开发板,所以在本章的方案中,开发板既是流媒体服务器、也是推断端。
  既然要在开发板上搭建流媒体服务器,首先我们需要将 Nginx 移植到开发板上,事实上,我们的板子出厂系统中就已经移植好了 Nginx,并且板子在启动进入系统时会自动启动 Nginx,也就是启动流媒体服务,所以板子启动之后本身就已经是一台流媒体服务器了。

当然,这里我们不管出厂系统中已经搭建好的流媒体服务,这里只是给大家说明一下,本章我们要自己动手亲自移植 Nginx、然后在板子上搭建流媒体服务。



34.2.1下载 Nginx 源码
进入到 Ubuntu 系统的某个目录下,执行下面这条命令下载 Nginx 源码:

wget http://nginx.org/download/nginx-1.20.0.tar.gz

image

 图 34.2.1 下载 Nginx 源码

这里我们下载的是 1.20 版本,这是比较新的版本了。下载完成之后将得到一个名为 nginx-1.20.0.tar.gz的压缩包文件。

image

 图 34.2.2 nginx-1.20.0.tar.gz 压缩包文件

这就是 Nginx 的源码包。



34.2.2下载 nginx-rtmp-module 模块
事实上,原生的 Nginx 并不支持 RTMP,我们需要安装第三方模块 nginx-rtmp-module 插件使其支持
RTMP。通过下面这条命令下载 nginx-rtmp-module。


git clone https://github.com/arut/nginx-rtmp-module.git

image

 图 34.2.3 下载 nginx-rtmp-module

下载成功之后将得到 nginx-rtmp-module 文件夹。



34.2.3交叉编译 Nginx
将下载得到的 nginx-1.20.0.tar.gz 文件进行解压:

tar -xzf nginx-1.20.0.tar.gz 

image

 图 34.2.4 解压

解压之后生成 nginx-1.20 文件夹,进入到该目录下。

在进行交叉编译之前,先对交叉编译工具进行初始化操作:

source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi

 

大家根据自己的实际安装位置填写路径。


首先配置源码、接下执行 make 编译源码,最后执行 make install 安装即可!总共的就这三个步骤,但事实上在编译的过程中会出现一些问题,我们稍后再看!



配置源码
首先第一步是配置源码,在配置之前,需要进行一个简单的修改,否则配置通不过;首先打开 nginx 源码目录下的 auto/cc/name 文件,将 21 行处的”exit 1”给注释掉!如下所示:

image

 图 34.2.5 修改 name 文件

修改完成之后保存退出。接着打开auto/types/sizeof文件,

15行处的” ngx_size=”修改为” ngx_size=4”并且

36 行处的”$CC”修改为”gcc”,如下所示:

image

 图 34.2.6 修改 sizeof 文件

同样,修改完成之后保存退出即可!接着执行下面这条命令进行配置:

./configure --prefix=/home/dt/tools/nginx-1.20.0/install \
--with-http_ssl_module \
--with-http_mp4_module \
--with-http_v2_module \
--without-http_upstream_zone_module \
--add-module=/home/dt/tools/nginx-rtmp-module

 

上述命令中,

--prefix 指定了 nginx 的安装路径,笔者为了方便直接将其安装到 nginx 源码目录下的 install目录中;

--add-module 用于添加第三方模块,譬如我们前面下载的 nginx-rtmp-module,所以

--add-module 需要指向 nginx-rtmp-module 源码路径,大家根据自己的实际路径填写。
如下所示:

image

 图 34.2.7 nginx 配置

配置成功打印信息如下所示:

image

 图 34.2.8 配置完成

编译源码
配置完成之后,接着我们执行 make 编译:

image

 图 34.2.9 执行 make 编译

本次编译并不会成功,将会出现如下错误打印信息:

image

 图 34.2.10 编译报错

这个时候我们需要修改 nginx 源码目录下的 objs/ngx_auto_config.h 文件,将如下内容添加到该头文件
中:

#ifndef NGX_HAVE_SYSVSHM
#define NGX_HAVE_SYSVSHM 1
#endif

image

 图 34.2.11 添加内容

添加完成之后保存退出,再次执行 make 编译,这样就会编译成功了。
图 34.2.12 编译成功

image

 安装

编译成功之后,接着我们进行安装,执行 make install

image

 图 34.2.13 安装

笔者将 nginx 安装到了 nginx-1.20.0 目录下的 install 目录中,进入到 install 目录下:

image

图 34.2.14 安装目录下的文件夹

conf 目录下有很多的配置文件,如下所示:

image

 图 34.2.15 conf 目录下的配置文件

其中 nginx.conf 配置文件很重要,后续我们会对该配置文件进行相应的配置。
sbin 目录下有一个可执行程序 nginx:

image

 图 34.2.16 nginx 可执行程序

这个可执行文件是一个“not stripped”文件,说明该文件包含了很多的调试信息,所以导致该文件特别
大 7.5MB,可以执行下面这条命令去掉调试信息、减少文件的大小:

arm-poky-linux-gnueabi-strip --strip-debug nginx 

image

 图 34.2.17 去除调试信息

nginx 可执行程序用于启动流媒体服务。
现在我们需要将安装目录下的这些文件拷贝到开发板 Linux 系统上,再进行拷贝之前,需要先将开发板出厂系统中已经移植好的 nginx 给移除,进入到开发板 Linux 系统中,执行下面这些命令移除出厂系统自带的 nginx 程序和相应的配置文件:

rm -rf /usr/sbin/nginx
rm -rf /etc/nginx/*

image

 图 34.2.18 删除出厂系统原有的 nginx

接下我们将 nginx 安装目录下 sbin 中的 nginx 拷贝到开发板 Linux 系统/home/root 目录下,如下所示:

image

 图 34.2.19 将 nginx 拷贝到开发板

接着再将安装目录下的 conf、logs、html 文件夹拷贝到开发板 Linux 系统的/etc/nginx 目录下,如下所示:

image

 图 34.2.20 将 conf、logs、html 文件夹拷贝到开发板



34.3 测试 nginx
上小节我们已经将 nginx 移植到了开发板上,本小节进行测试、验证,看看 nginx 是否能够正常工作。
先重启开发板,重启进入系统后,进入到/home/root 目录下,执行 nginx 程序。

./nginx -V # 查看版本信息

image

 图 34.3.1 查看 nginx 版本信息

执行./nginx -h 查看帮助信息:

image

 图 34.3.2 查看帮助信息

接下来我们要启动 nginx,执行如下命令:

./nginx -p /etc/nginx

 

此时 nginx 服务便在后台运行了,通过 ps 命令可查看到:

ps -aux

image

 图 34.3.3 查看 nginx 服务

此时我们可以打开电脑浏览器,输入开发板的 IP 地址,如下所示:

image

 图 34.3.4 输入开发板 IP 地址

按下回车,如下所示:

image

 图 34.3.5 welcome to nginx

如果显示出上面这个页面,表示我们的 nginx 已经正常工作了。



34.4 配置 nginx
后续我们会使用 FFmpeg 进行推流,将视频流通过 RTMP 推给 nginx 流媒体服务器,在此之前,我们需
要对 nginx 进行配置,打开 nginx 的配置文件/etc/nginx/conf/nginx.conf,添加如下内容:

rtmp {
server {
listen 1935; # 监听 1935 端口
chunk_size 4096;
application live{
allow publish 127.0.0.1;
allow play all;
live on; # 打开直播
record off; # 关闭 record
meta copy;
}
application hls {
live on;
hls on;
hls_path /tmp/hls;
hls_fragment 8s;
}
}
}

 

如下所示:

image

 图 34.4.1 添加内容

添加完成之后保存退出即可!
接着执行如下命令重启 nginx:

./nginx -p /etc/nginx -s reload


34.5 使用 FFmpeg 推流
nginx 重启之后,接着我们便可使用 FFmpeg 进行推流,将视频流数据通过 RTMP 推给 nginx 流媒体服
务器,执行如下命令进行推流:

ffmpeg -re -i /run/media/mmcblk0p1/testVideo.mp4 -c:av copy -f flv rtmp://127.0.0.1/live/mytest

简单地介绍一下这些参数,首先-i 表示输入视频数据,这里我们使用了一个 mp4 视频文件;
rtmp://127.0.0.1/live/mytest 表示将视频流通过 RTMP 推给流媒体服务器,这里因为我们的服务器和推流端都是开发板,所以这个 IP 地址 127.0.0.1 指的就是本机的流媒体服务器。

image

 图 34.5.1 FFmpeg 推流

现在我们可以进行拉流了,可以将我们的 Windows 主机作为拉流端,使用 VLC 软件进行拉流,VLC 软件大家自己下载、安装好。安装好之后打开 VLC,如下所示:

image

 


图 34.5.2 VLC 软件
点击左上角“媒体”--->“打开网络串流”:

image

 图 34.5.3 网络串流

输入流媒体服务器的 IP 地址以及路径,笔者使用的开发板对应的 IP 地址为 192.168.1.114,点击“播放”即可从 RTMP 流媒体服务器拉取视频数据进行播放,如下所示:

image

 图 34.5.4 VLC 拉流播放视频

既有画面也有声音!
接下来我们再使用摄像头进行测试,使用 FFmpeg 采集摄像头视频数据将其发送给 nginx 流媒体服务器,执行如下命令:
ffmpeg -f v4l2 -video_size 320x240 -framerate 15 -i /dev/video2 -q 10 -f flv rtmp://127.0.0.1/live/mytest

image

 图 34.5.5 摄像头监控


这里笔者使用了一个 USB 摄像头进行测试,命令执行之后,接着在 Windows 下使用 VLC 拉流播放摄像头采集到的画面,实现视频摄像头监控。

image

 图 34.5.6 VLC 拉流播放摄像头采集到的画面

测试发现,延迟太高了,导致开发板当前采集到的画面与 VLC 播放到的画面并不同步,笔者实测大概有 5、6 秒的延迟,为什么会这样呢?笔者认为有两方面的原因:
⚫ 我们的 I.MX6U 开发板性能太弱了,虽然我们执行的是一条命令,但是 FFmpeg 内部却进行很多的处理,譬如对视频、音频数据的处理,由于 I.MX6U 本就没有硬件视频解码,完全依赖于软件处理,导致会耗费相当大的时间。
⚫ 在我们本次实验中,由于服务器和推流端都是开发板,本来性能就弱,还做了这么多的工作,必然就会导致延迟大,你可以使用一款高性能的开发板进行测试对比,你就会发现确实是咋们使用开发板性能太弱了!


好了,本章的内容就到此结束了。

 

posted on 2026-03-14 10:44  前沿风暴  阅读(36)  评论(0)    收藏  举报

导航


校内网 © 2004-2026

京公网安备 33010602011771号 京ICP备2021040463号-3