韦东山视频监控方案学习笔记

1.总体方案

1.1所需要的软件

a. Ubuntu(可以用虚拟机安装Ubuntu);

b. Buildroot(Buildroot会自动下载其他软件: MJPG-streamer, ffmpeg, nginx);

c. 内网穿透软件: 花生壳5.0

1.2视频监控的作用

在这里插入图片描述

1.3方案1

如果只是想在客厅查看房间的情况,不需要什么复杂的协议
在这里插入图片描述
作为程序员,我们需要写2个程序:

在连接摄像头的ARM板子上,实现一个服务器程序:它一边读取摄像头数据,一边等待客户端连接并发送数据

在手机或电脑上,编写客户端程序,它会从ARM板上获得数据并显示出来

这2个程序之间,并不需要实现复杂的协议

约定数据格式
传输一帧帧的数据

实际上,我们可以使用现成的程序:

mjpg-streamer,它运行在ARM板上

在手机上使用浏览器直接观看视频

优点:

程序简单,所有源码一目了然,便于学习

对ARM板的性能要求不高,主频200MHz的ARM芯片也能实现

缺点:

只能实现局域网内的视频监控

要实现互联网视频监控,需要另外实现内网穿透

mjpg-streamer没有实现声音传输

mjpg-streamer项目已经不再维护,仅仅建议用于学习

1.4方案二

使用流媒体
在这里插入图片描述
作为程序员,我们需要写3个程序:

在连接摄像头的ARM板子上,实现一个推送程序:它一边读取摄像头数据,一边把数据推送给服务器

在服务器上,实现“流媒体服务器”程序:它接收ARM板发来的数据,并把数据转换格式后发给手机等客户端

在手机等客户端上,实现拉取程序:它从服务器上拉取数据,并显示出来

实际上,我们可以把互联网功能去掉:

把“推送程序”、“流媒体服务器”程序,都在ARM板上运行;手机等客户端只能在同一个局域网里观看视频

或者也使用内网穿透技术实现互联网视频监控

我们并不需要从头实现这些功能:

推送程序:ffmpeg

流媒体服务器程序:Nginx

客户端程序:VLC浏览器

我们需要了解一些协议:

程序一多,大家都遵守一些协议才好协同工作

有很多流媒体协议

STMP、HTTP-FLV、HLS

1.5几种流媒体协议

参考资料:

HTTP-FLV直播初探

https://www.cnblogs.com/saysmy/p/7851911.html

理解RTMP、HttpFlv和HLS的正确姿势

https://www.jianshu.com/p/32417d8ee5b6
在这里插入图片描述
RTMP:

Real Time Messaging Protocol

Adobe公司出品,需要Flash player才能观看

延时小,适合直播

HttpFlv:

在HTTP上实现RTMP,传输的数据跟RTMP一样都是flv文件

B站开源了flv.js,实现了纯HTML5观看直播,不再需要Flash player

延时小,适合直播

HttpFlv只能做直播,而RTMP可以实现更多操作

但是HttpFlv通过Http 80端口传输,穿透性强

HLS:

HTTP Live Streaming

Apple出品

延时大,适合看视频,不适合直播
在这里插入图片描述

1.6流媒体服务

流媒体服务:两端加一服
在这里插入图片描述
注意:

RTMP可以用在双端

HTTPFLV 、HLS 只能用在拉流端

2.MJPG-Stream方案实现

在这里插入图片描述
编译安装MJP-streamer,使用Buildroot编译(原作者修改了buildroot,否则没有生成img文件,只有根文件系统)
在100ASK_IMX6ULL上安装、运行
使用chrome浏览器,观看摄像头拍摄的视频
讲解MJP-streamer框架
在这里插入图片描述

JPEG与MJPG区别
简称JPG
上过美术课的人都知道一个象素的颜色可以用RGB三原色来表示,其实还可以用YUV格式来表示
使用RGB、YUV的格式编码的照片,文件都很大,比如常见的BMP文件就是用RGB编码
把一个BMP文件转换为JPEG文件,可以发现图片质量没发生变化,但是文件变小了很多
JPEG是根据人体视觉的特点采用了YCbCr格式,大大压缩了照片的大小
MJPG
Motion JPEG,简称MJPG
JPEG是静态图片的编码格式,MJPG是动态的视频编码格式
可以简理解:MJPG就是把多个JPEG图片连续显示出来
MJPG的优点
很多摄像头本身就支持JPEG、MJPG,所以处理器不需要做太多处理
一般的低性能处理器就可以传输MJPG视频流
MJPG的缺点
MJPG只是多个JPEG图片的组合,它不考虑前后两帧数据的变化,总是传输一帧帧图像:传输带宽要求高
H264等视频格式,会考虑前后两帧数据的变化,只传输变化的数据:传输带宽要求低

运行mjpg-streamer
在开发板上安装好MJPG-streamer后:
执行命令:mjpg_streamer -i “/usr/lib/mjpg-streamer/input_uvc.so -d /dev/video1 -f 30 -q 90 -n” -o “/usr/lib/mjpg-streamer/output_http.so -w /usr/share/mjpg-streamer/www”
在PC或手机上:
确保PC或手机,跟开发板处于同一个局域网
假设开发板IP为:192.168.1.6
在chrome浏览器中打开:http://192.168.1.6:8080/stream.html
就可以看见视频了

其他用法
查看帮助:
mjpg_streamer -o “/usr/lib/mjpg-streamer/output_file.so --help”
mjpg_streamer -i “/usr/lib/mjpg-streamer/input_file.so --help”
把摄像头数据存为JPG文件:
mjpg_streamer -i “/usr/lib/mjpg-streamer/input_uvc.so -d /dev/video1 -f 30 -q 90 -n” -o “/usr/lib/mjpg-streamer/output_file.so -f /tmp”
把JPG文件输出到浏览器:
mjpg_streamer -i “/usr/lib/mjpg-streamer/input_file.so -e -f /tmp” -o “/usr/lib/mjpg-streamer/output_http.so -w /usr/share/mjpg-streamer/www”

3.ffmpeg

3.1Ffmpeg是什么

一套开源软件,可以记录、转换音视频:可以从摄像头中记录视频,从声卡中记录音频,可以转换为各种格式,保存起来
还可以把各种格式的音视频,转换为流:供在线观看
其他功能:视频截图、加水印、裁剪等等
Mplayer,ffplay,射手播放器,暴风影音,KMPlayer,QQ影音等视频频播放器的内核就是 FFmpeg,格式工厂的内核也是FFmpeg

3.2Ffmpeg简易理解

在这里插入图片描述
误区:我们以为mp4就代表了音频、视频的压缩格式,其实不是
Mp4只是一种封装格式,里面有音频数据、视频数据
音频数据有自己的压缩格式,还不止一种
视频数据也有自己的压缩格式,还不止一种
参考文章
视音频编解码技术零基础学习方法
https://blog.csdn.net/leixiaohua1020/article/details/18893769
在这里插入图片描述
从摄像头得到的原始数据太大,不易传输,需要压缩
压缩的方法有很多种:格式不同,编码器不同,这里对应视频编码器
从声卡得到的原始数据太大,不易传输,需要压缩
压缩的方法有很多种:格式不同,编码器不同,这里对应音频编码器
把这些压缩后,即编码后的视频数据、音频数据合并在一起:复用、MUX,就得到了MP4等文件
参考文章
视音频编解码技术零基础学习方法
https://blog.csdn.net/leixiaohua1020/article/details/18893769
在这里插入图片描述

3.3FFmpeg的组成

参考文章
ffmpeg 基本用法
https://www.jianshu.com/p/3c8c4a892f3c
在这里插入图片描述在这里插入图片描述

3.4FFmpeg处理音视频的过程

在这里插入图片描述
用Filter(过滤器)来处理
旋转、拉伸
添加LOGO、消除LOGO等等
在这里插入图片描述

3.5FFmpeg运行

在开发板上安装好ffmpeg后:
执行命令:ffmpeg -f v4l2 -framerate 10 -i /dev/video1 -q 10 my.mp4
它会把摄像头的数据录制为my.mp4
把my.mp4复制到PC机,播放
更多用法:
ffmpeg基础使用:https://www.jianshu.com/p/ddafe46827b7
给新手的 20 多个 FFmpeg 命令示例:https://zhuanlan.zhihu.com/p/67878761
建议在Windows下练习:
下载static版本:https://ffmpeg.zeranoe.com/builds/
在命令行中练习ffmpeg

4.nginx

4.1nginx是啥

Nginx是一套开源软件,纯C语言编写,效率高
HTTP和反向代理web服务器,同时也是一个 IMAP、POP3、SMTP 代理服务器
稳定、高效,支持高并发
即使强如阿里巴巴,也是使用Nginx: http://tengine.taobao.org/,它就是在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。
我们只关注:Nginx可以作为流体服务器,支持RTMP、HTTPFLV、HLS等协议

4.2三种web服务器比较

在这里插入图片描述

4.3Nginx在流媒体方案中的位置

在这里插入图片描述
推流端
FFmpeg使用RTMP协议向Nginx推流
拉流端
VLC播放器使用RTMP或HTTPFLV协议从Nginx拉流
浏览器使用HTTPFLV协议从Nginx拉流(安装flv.js)

4.4 让Ngnix支持RTMP、HTTPFLV协议

Nginux需要第3方模块
nginx-rtmp-module:实现了RTMP协议
nginx-http-flv-module:在nginx-rtmp-module的基础上,实现了HTTPFLV,并覆盖nginx-rtmp-module的所有功能
所以,我们将会在Nginx上使用nginx-http-flv-module
第3方模块源码:
https://github.com/winshining/nginx-http-flv-module/
参考资料
https://github.com/winshining/nginx-http-flv-module/blob/master/README.CN.md

4.5移植nginx

有两种方法:
下载源码,手工编译
使用Buildroot,配置选择Nginx,直接编译生成映象文件
我们使用Buildroot:
设置交叉编译工具链
下载第3方模块:
在Buildroot目录下,创建目录:mkdir dl/nginx
使用git下列载:cd dl/nginx && git clone https://github.com/winshining/nginx-http-flv-module.git
在Buildroot根目录
make menuconfig
把原来的lighttpd去掉,否则板子也会自动启动它,就会有两个HTTP服务了:lighttpd, nginx
如图选择Nginx,建议把所有功能都选上
并且设置额外的参数,在“additional modules”中添加: $(TOPDIR)/dl/nginx/nginx-http-flv-module
最后执行(先删除之前编译的nginx,我发现有时设置的第3方模块不起作用,删除后再make就可以了):rm -rf output/build/nginx-1.15.7 && make
这会在Buildroot的dl/nginx目录下自动下载源码,并编译
结果保存在output/images目录下,有emmc.img, sdcard.img,可以直接烧写到板能的EMMC或SD卡上
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.6运行Ngnix

开发板上烧写好映像文件后,开发板启动时会自动运行Ngnix
为了让它支持RTMP、HTTPFLV,需要修改配置文件/etc/nginx/nginx.conf
注意:rtmp 1935这个端口容易被防火墙拦住。所有用http flv协议好些
在这里插入图片描述
在这里插入图片描述
最后,重启Nginx服务:/etc/init.d/S50nginx restart

4.7测试Ngnix

在开发板上运行了Nginx后,它就已经是一个WEB站点了。
可以在电脑浏览器里输入开发板的IP访问开发板:

4.8测试流媒体

推流
在开发板上执行:

ffmpeg -f v4l2 -framerate 10 -i /dev/video1 -q 10  -f flv rtmp://127.0.0.1/live/wei

拉流
在PC上安装VLC播放器:https://www.videolan.org/
使用RTMP协议拉流:VLC播放器中点击“媒体”->“打开网络串流”,输入:rtmp://192.168.1.6/live/wei ,就可以播放了
使用HTTPFLV协议拉流:VLC播放器中点击“媒体”->“打开网络串流”,输入: http://192.168.1.6/test?app=live&stream=wei ,就可以播放了(这个test对应上面配置文件的test,表示目录)
缺点:
IMX6ULL性能太弱,在VLC播放器里看到的视频很卡,很滞后
我们可以上传一个mp4文件到开发板,把它推到Nginx: ffmpeg -re -i test.mp4 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1/live/wei
然后再用VLC拉流看看,会发现很顺畅
RTMP容易被防火墙挡住

4.9浏览器播放

浏览器无法直接播放,只会下载到本地
无插件web直播解决方案,ffmpeg+nginx-http-flv-module+flv.js(百度搜索flv.js,找现成的别人编译好的,进去那个网址,输入我们的待播放的流地址就可播放)
https://blog.csdn.net/string_kai/article/details/100598268
HTTP-FLV直播初探
https://www.cnblogs.com/saysmy/p/7851911.html
修改/etc/nginx/nginx.conf:
如下:
location /test {
flv_live on;
chunked_transfer_encoding on;
add_header ‘Access-Control-Allow-Origin’ ‘*’;
add_header ‘Access-Control-Allow-Credentials’ ‘true’;
}
在这里插入图片描述
自己编写html文件,播放流
复制链接里面的h5代码,保存到本地,把里面的url改成我们自己的地址,然后把<script src="./flv.js?v=2"></script>把双引号里面的东西改为下载flv.js的地址,因为本地没有flv.js。然后点击这个h5文件就能播放
如何改为开发板播放?

cd /usr/html 
 >index.html #清空
 把我们的代码复制过去,然后电脑浏览器输入开发板地址就可以播放了

5.视频音频

在上图中,FFmpeg怎么去访问摄像头?
Linux中摄像头的驱动称为v4l2:Video for linux2,就是linux下video驱动的第2版接口
在上图中,FFmpeg怎么去访问声卡?
Linux中声卡的驱动称为ALSA: Advanced Linux Sound Architecture
声卡接口比摄像头接口复杂得多
我们一般使用alsa-lib或tinyalsa来访问声卡,FFmpeg使用alsa-lib,安卓使用tinyalsa

5.1V4L2

学习方法:
阅读MJPG-streamer的源码可快速掌握:plugins\input_uvc\v4l2uvc.c
硬件接口:
USB
CMOS等
但是它们的驱动遵守同样的标准:V4L2
所以APP可以使用同样的API访问不用硬件接口的摄像头
摄像头参数:
分辨率
数据格式:RGB,YUV,JPEG,MJPG,H264
帧率

API接口,按顺序列出:
在这里插入图片描述

  1. 摄像头数据在内核中的组织方法
    在这里插入图片描述

  2. 声音的采集
    在这里插入图片描述
    两个参数:
    采样频率:一秒钟内采样越多,声音越逼真;但是太多也没必要,人耳分辨不出更高的采样率
    数据位宽:位数越多,采集的声音精度越高,常用的是16bit
    在这里插入图片描述
    1个参数:
    声道:要声音听起来有空间感,至少要有左、右两声前。
    简单地说,录制声音时,模拟左、右耳朵的位置放置两个ADC采集声音
    播放时,两个耳机的声音不一样

  3. 声卡接口:ALSA
    学习方法:
    A Tutorial on Using the ALSA Audio API:http://www.equalarea.com/paul/alsa-audio.html
    ALSA接口的复杂之处在于,有很多的ioctl来设置很多的参数
    所以一般都是基于alsa-lib来编写APP
    ALSA APP的伪代码:
    在这里插入图片描述

  4. 让FFmpeg录制声音
    编译alsa-utils:
    FFmpeg借助alsa-utils操作声卡
    使用Buildroot,配置选择alsa-utils,直接编译生成映象文件
    rm -rf output/build/ffmpeg-3.4.5
    make

运行FFmpeg:
只是录制声音:
在开发板上执行: ffmpeg -f alsa -ac 1 -i hw:0,0 my.wav
播放:
aplay my.wav
在这里插入图片描述
7. 测试流媒体
推流
在开发板上执行:
只推声音:ffmpeg -f alsa -ac 1 -ar 11025 -i hw:0,0 -acodec aac -f flv rtmp://127.0.0.1/live/wei
视频声音同时推:ffmpeg -f alsa -ac 1 -ar 11025 -i hw:0,0 -acodec aac -f v4l2 -framerate 10 -i /dev/video1 -q 10 -f flv rtmp://127.0.0.1/live/wei
拉流
在PC上安装VLC播放器:https://www.videolan.org/
使用RTMP协议拉流:VLC播放器中点击“媒体”->“打开网络串流”,输入:rtmp://192.168.1.6/live/wei ,就可以播放了
使用HTTPFLV协议拉流:VLC播放器中点击“媒体”->“打开网络串流”,输入: http://192.168.1.6/test?app=live&stream=wei ,就可以播放了

6.内网穿透

在前面的课程,Ffmpeg和Nginx都运行在开发板上
拉流端只能在同一个局域网内
不能通过外网访问Ngnix
想在任何地方,都可以通过互联网访问Nginx,怎么办?
方法1:把Ngnix放到公网服务器上
方法2:使用内网穿透技术,把开发板暴露到公网

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值