视频监控解决方案
bilibili UP:达尔闻
视频监控
1 视频监控方案介绍
mjpg-stream安装在linux系统上
协议 | HTTP-FLV | RTMP | HLS | DASH | RTSP |
---|---|---|---|---|---|
传输方式 | HTTP流 | TCP流 | TCP流 | HTTP流 | TCP/UDP |
封装格式 | FLV | FLV Tag | TS文件 | mp4\3gp\webm | mov/asf/wms |
延时 | 低 | 低 | 高 | 高 | 低 |
数据分段 | 连续流 | 连续流 | 切片文件 | 切片文件 | 连续流 |
HTML5播放 | 使用flv.js | 不支持 | 使用hls.js | 可播放mp4、webm | 支持 |
- 推流端:ffmpeg
- rtmp
- 服务器:nginx
- http
- 拉流端:浏览器/VLC播放器
推流端 + 服务器部署在同一主机 => 局域网本地视频监控
2 MJEPG-streamer实现
3 FFmpeg
4 Nginx
安装参考bilibili UP主:三湿地
视频基础
YUV格式分为两大类
planar
和packed
- 对于
planar
的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V - 对于
packed
的YUV格式,每个像素点的YUV是连续交替存储的 - Libyuvku:Google开源的实现各种YUV与RGB之间相互转化、旋转、缩放的库
- YUV存在多种格式,比如YUV420p,YUV420sp等,不同的YUV数据格式在存储时的排序是不一样的,在开发过程中必须非常注意,否则画面会显示不正常,比如花屏、绿屏等
- YUV 4:4:4采样,每个Y对应一组UV分量
- YUV 4:2:2采样,每两个Y对应一组UV分量
- YUV4:2:0采样,每4个Y共用一组UV分量
- 对于
数字图像格式转换,以H264直播为例:
视频基础
- 视频码率:kb/s,是指视频文件在单位时间内使用的数据流量,也叫码流率,码率越大,说明单位时间内取样率越大,数据流精度越高
- 视频帧率:fps,通常说一个视频的25帧,指的是这个视频帧率,即1秒会显示25帧。帧率越高,给人的视觉就越流畅
- 视频分辨率:分辨率就是我们常说的640*480分辨率、1920*1080分辨率,分辨率影响视频图像的大小
I P B帧的概念
- I帧(Intra caoded frames):I帧不需要参考其他画面而生成,解码时仅靠自己就重构完整图像
- I帧图像采用帧内编码方式
- I帧所占数据的信息量比较大
- I帧图像是周期性出现在图像序列中的,出现频率可由编码器选择
- I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量)
- I帧是帧组GOP的基础帧(第一帧),在一组中只有一个I帧
- I帧不需要考虑运动矢量
- P帧:根据本帧与相邻的前一帧(I帧或P帧)的不同点来压缩本帧数据,同时利用了空间和时间上的相关性。
- P帧属于前向预测的帧间编码,它需要参考前面最靠近它的I帧或P帧来解码(多个参考的时候,遇到过11个参考帧)
- B帧:B帧图像采用双向时间预测,可以大大提高压缩倍数
- I帧(Intra caoded frames):I帧不需要参考其他画面而生成,解码时仅靠自己就重构完整图像
常见视频压缩算法
- MPEG阵营
- MPEG2
- H264
- H265
- 中国阵营
- AVS
- Google阵营
- VP8
- VP9
- MPEG阵营
音频
采样定理:2倍,所以CD音质>40khz(ADC器件)
没有经过压缩的音频数据我们叫PCM数据
采样频率:每秒钟采样的点的个数
采样的精度(采样深度):每个“样本点”的常用大小为8bit,16bit,24bit
通道数:单声道、双声道、四声道、5.1声道
- 7.1声道 —— 8个声道
- 5.1声道 —— 6个声道
- 2.1声道 —— 3个声道
比特率:每秒传输的bit数,单位为(bps)
间接衡量声音质量的一个标准
没有压缩的音频数据的比特率 = 采样频率*采样精度*通道数
码率:压缩后的音频数据的比特率
- 常见的码率:
- 96kbps:FM质量
- 128 - 160kbps:一般质量音频
- 192kbps:CD质量
- 256 - 320Kbps:高质量音频
- 码率越大,压缩效率越低,音质越好,压缩后数据越大。
- 码率 = 音频文件大小 / 时长
- 常见的码率:
音频的帧的概念没有视频帧那么清晰,几乎所有的视频编码格式都可以简单的认为一帧就是编码后的一张图像
- 帧长:可以指每帧采样数播放的时间,mp3 48k,1152个采样点,每帧则为24ms;aac(16khz - > 2048 / 48khz - > 1024)则是每帧是1024个采样点。攒够一帧数据才送去做编码
- 也可以指压缩后每帧数据长度,所以讲到帧的时候要注意他适用的场合
- 每帧持续时间(秒) = 每帧采样点数 / 采样频率(HZ)
存储方式
- 交错模式:数字音频信号存储的方式。数据以连续帧的方式存放,即首先记录帧1的左声道样本和右声道样本,再开始帧2的记录(LRLRLRLRLR…… / LRCLRCLRCLRC……)
- 非交错模式:首先记录的是一个周期内所有帧的左声道样本,再记录所有右声道样本(LLLLLL……RRRRRR……)
常用音频格式:
- MP3
- AAC
- OPUS webrtc
- AC3和EAC3杜比公司的方案
封装格式基础
封装格式(也叫容器)就是将已经编码压缩好的视频流、音频流及字幕按照一定的方案放到一个文件中,便于播放软件播放。
一般来说,视频文件的后缀名就是它的封装格式。
封装格式不同,后缀名也就不一样。
FLV(适合直播)和MP4(适合本地播放、多路音轨切换)的区别:
音频同步基础
DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器应该在什么时候解码这一帧的数据
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据
- 音视频同步方式:
- 同步视频到音频 A (人对声音更加敏感)
- 同步音频到视频 B
- 同步音频和视频到外部时钟 C
- A > B > C
开源项目
ffmpeg
ijkplay (手机端)
QMPlayer ( PC端 )
ZLMediaKit(跨平台)
EasyDarwin
SRS(协程写的)
nginx - rtmp - module
常用工具
MediaInfo :视频信息查看工具
VLC :视频流播放工具
wireshark : 网络抓包工具
cooledit pro2 : 音频编辑工具,PCM播放工具
Elecard StreamEye Tools:分析视频帧的工具(需要破解)
音视频算法工程师
流媒体开发服务器工程师
开源TeamTalk
FFMPEG学习
概念
容器
视频文件本身其实是一个容器(container),里面包括了视频和音频,也可能有字幕等其他内容。
- 常见的容器格式有以下几种,一般来说,视频文件的后缀名反映了它的容器格式:
- MP4
- MKV
- WebM
- AVI
1 |
|
编码格式
视频和音频都需要经过编码,才能保存成文件。不同的编码格式(CODEC),有不同的压缩率,会导致文件大小和清晰度的差异。
常用的视频编码格式如下:
- H.262
- H.264
- H.265
上面的编码格式都是有版权的,但是可以免费使用。此外,还有几种无版权的视频编码格式:
- VP8
- VP9
- AV1
常用的音频编码格式
- MP3
- ACC
上面所有这些都是有损的编码格式,编码后会损失一些细节,以换取压缩后较小的文件体积,无损的编码格式压缩出来的文件体积较大,这里就不介绍了。
下面的命令可以查看 FFmpeg 支持的编码格式,视频编码和音频编码都在内:
1 |
|
编码器
编码器(encoders)是实现某种编码格式的库文件。只有安装了某种格式的编码器,才能实现该格式视频/音频的编码和解码。
- 以下是一些 FFmpeg 内置的视频编码器:
- libx264:最流行的开源 H.264 编码器
- NVENC:基于 NVIDIA GPU 的 H.264 编码器
- libx265:开源的 HEVC 编码器
- libvpx:谷歌的 VP8 和 VP9 编码器
- libaom:AV1 编码器
- 音频编码器:
- libfdk-aac
- aac
下面的命令可以查看 FFmpeg 已安装的编码器:
1 |
|
FFMPEG的使用格式
1 |
|
- 上面命令中,五个部分的参数依次如下:
- 全局参数
- 输入文件参数
- 输入文件
- 输出文件参数
- 输出文件
参数太多的时候,为了便于查看,ffmpeg 命令可以写成多行
1 |
|
一个例子:
1 |
|
上面的命令将 mp4 文件转成 webm 文件,这两个都是容器格式。输入的 mp4 文件的音频编码格式是 aac,视频编码格式是 H.264;输出的 webm 文件的视频编码格式是 VP9,音频格式是 Vorbis。
如果不指明编码格式,FFmpeg 会自己判断输入文件的编码。因此,上面的命令可以简单写成下面的样子:
1 |
|
常用命令行参数
FFmpeg 常用的命令行参数如下:
1 |
|
常见用法
下面介绍FFmpeg的几种常见用法
查看文件信息
查看视频文件的元信息,比如编码格式和比特率,可以只使用-i
参数:
1 |
|
上面命令会输出很多冗余信息,加上-hide_banner
参数,可以只显示元信息。
1 |
|
转换编码格式
转换编码格式(transcoding)指的是, 将视频文件从一种编码转成另一种编码。比如转成 H.264 编码,一般使用编码器libx264
,所以只需指定输出文件的视频编码器即可。
1 |
|
下面是转成 H.265 编码的写法:
1 |
|
转换容器格式
转换容器格式(transmuxing)指的是,将视频文件从一种容器转到另一种容器。下面是 mp4 转 webm 的写法:
1 |
|
上面例子中,只是转一下容器,内部的编码格式不变,所以使用-c copy
指定直接拷贝,不经过转码,这样比较快。
调整码率
调整码率(transrating)指的是,改变编码的比特率,一般用来将视频文件的体积变小。下面的例子指定码率最小为964K,最大为3856K,缓冲区大小为 2000K。
1 |
|
改变分辨率(transsizing)
下面是改变视频分辨率(transsizing)的例子,从 1080p 转为 480p:
1 |
|
提取音频
1 |
|
上面例子中,-vn
表示去掉视频,-c:a copy
表示不改变音频编码,直接拷贝。
添加音轨
添加音轨(muxing)指的是,将外部音频加入视频,比如添加背景音乐或旁白。
1 |
|
上面例子中,有音频和视频两个输入文件,FFmpeg 会将它们合成为一个文件。
截图
下面的例子是从指定时间开始,连续对1秒钟的视频进行截图:
1 |
|
如果只需要截一张图,可以指定只截取一帧:
1 |
|
上面例子中,-vframes 1
指定只截取一帧,-q:v 2
表示输出的图片质量,一般是1到5之间(1 为质量最高)。
裁剪
裁剪(cutting)指的是,截取原始视频里面的一个片段,输出为一个新视频。可以指定开始时间(start)和持续时间(duration),也可以指定结束时间(end)。
1 |
|
实际例子:
1 |
|
上面例子中,-c copy
表示不改变音频和视频的编码格式,直接拷贝,这样会快很多。
为音频添加封面
有些视频网站只允许上传视频文件。如果要上传音频文件,必须为音频添加封面,将其转为视频,然后上传。
下面命令可以将音频文件,转为带封面的视频文件。
1 |
|
面命令中,有两个输入文件,一个是封面图片cover.jpg
,另一个是音频文件input.mp3
。-loop 1
参数表示图片无限循环,-shortest
参数表示音频文件结束,输出视频就结束。