首先我们来初步认识一些名词,了解一些流媒体技术相关的基本概念,其次通过一个实例加深对基本概念的理解和记忆。
名词
名词 | 说明 |
---|---|
AVI | Audio Video Interleave,音频视频交错 |
MPEG | Moving Picture Experts Group,现泛指一系列视频编码标准正式审核程序 |
RMVB | RealMedia Variable Bitrate,多媒体封装格式的一种动态比特率扩展 |
MP4 | MPEG-4第14部分的一种标准数字多媒体容器格式 |
MOV | 即QuickTime的影片格式用于存储常用数字媒体类型 |
FLV | FLASH VIDEO,用作流媒体格式 |
WebM | Google提出的开放免费的媒体文件格式 |
WMV | Windows Media Video,微软开发的一组数字影片的编解码格式 |
MKV | Matroska媒体系列中的一种文件格式 |
H.264 | 一种较流行的视频压缩标准 |
MPEG-4 | 一套用于音频、视频信息的压缩编码的国际标准 |
基本概念
概念 | 说明 | 补充说明 |
---|---|---|
帧 | 可以简单理解对于每一张图片或画面都可以理解成是一帧 | 暂无 |
帧率FPS | 每秒钟播放的图片数画面数,比如FPS 120那就是每秒切换播放了120张图片 | 可以理解成每秒传输的帧数 |
像素 | 图片由像素构成,每个像素由RGB组成,每个8位,三原色构图共24位 | 像素便是一个图像中的最小单位 |
视频 | 个人观点单位时间内同一像素下由N帧组成的内容呈现 | 暂无 |
视频编码 | 根据各种算法将视频压缩的一个过程 (视频为何要编码?减小视频占用的容量大小,视频的编码过程本身就是一个压缩的过程。) | 将原始视频格式转换为另一种视频文件格式的形式 |
流派 | 主流俩大类,ITU的VCEG,ISO的MPEG | ITU与MPEG联合制定了H.264/MPEG-4 AVC |
接流 | 使用某一网络协议将编码完毕的视频流从主播端传到服务器端的过程 | 个人理解对服务端来说是接流,对主播端来说是推流操作 |
转码 | 服务器端接到视频流后对视频流进行一定的处理,从一个编码格式转换为另一个编码格式的过程 | 因为客户端存在差异性的原因 |
拉流 | 流处理完毕之后,客户端请求视频资源的过程 | 暂无 |
分发网络 | 如果某一时间段内请求该视屏资源的观众非常多,那么从单一服务器节点上拉流导致节点压力大,所以加入分发网络也就是CDN,将资源预先加载到CDN的边缘节点 | 可以显著降低真实服务器的压力,提升用户质量 |
解码 | 当客户端将视频拉下来后就需要解码才能播放,将二进制文件转换为视频的过程 | 暂无 |
I帧 | Intra-coded picture 关键帧,里面是完整的图片 | 最完整,只需要本帧即可完成解码 |
P帧 | Predictive-coded Picture 前向预测编码帧,表示这一帧和之前一个I帧或P帧的差别 | 解码的时侯需要用之前缓存的画面叠加上和本帧定义的差别才可以生成最终的画面 |
B帧 | Bidirectionally predicted picture 双向预测内插编码帧,记录本帧与前后帧的区别 | 通过前后画面的数据与本帧数据的叠加才能取得最终画面 |
DTS | Decoding Time Stamp 解码时间戳 | 告诉播放器该在什么时候解码这一帧的数据 |
PTS | Presentation Time Stamp 显示时间戳 | 告诉播放器该在什么时候显示这一帧的数据 |
NALU | 网络提取层单元,二进制流的结构是由一个个的NALU组成的 | 这种格式就是为了传输,按照帧和片依次排列 |
NALU Type | 在NALU头里面,0x07表示SPS,序列参数集,包括一个图像序列的所有信息,0x08表示PPS,图像参数集,包括一个图像的所有分片的所有相关信息 | 在传输视频流之前必须传输这俩个参数,否则无法解码 |
推流 | 将二进制数据流打包成网络包传输到对端 | 将NALU放到Message里面发送,这个也被称为RTMP Packet包 |
RTMP | RTMP通过协商版本号,时间戳来建立连接 | 一般RTMP的包会被拆分成Chunk进行传输 |
这里又涉及到直播的三种常见协议,这里简单总结对比下。
常见协议
RTMP | HTTP-HLS | HTTP-FLV | |
---|---|---|---|
协议 | TCP长连接 | HTTP短连接 | HTTP长连接 |
基本原理 | 每个时刻收到的数据立即转发 | 集合一段时间内的数据生成ts切片,更新索引 | 同RTMP相似 |
延时 | 1~3s | 5~20s | 1~3秒 |
web支持 | 网页中需要插件 | 支持网页访问 | 网页中需要插件 |
其它 | 延迟小适合交互强的直播 | 延迟大适合交互较弱的直播 | 延迟小适合交互强的直播 |
简单实例
1.确认系统版本
[root@iZ2ze0a8w2ct7mzctse5r5Z ~]# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
2.安装配置Tengine
1.需要下载nginx的nginx-rtmp-module模块用来支持RTMP协议
git地址:https://github.com/arut/nginx-rtmp-module
编译安装添加参数:--add-module=/path/to/nginx-rtmp-module
Tengine编译安装过程此处省略~
2.修改nginx的配置文件
[root@iZ2ze0a8w2ct7mzctse5r5Z src]# cat /usr/local/tengine/conf/nginx.conf
在配置文件中http的server区域添加如下
location /hls { //配置推流地址
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /data/wwwroot/hls;
expires -1;
add_header Cache-Control no-cache;
}
location /stat { //推流状态查看
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /usr/local/extend_module/nginx-rtmp-module/;
}
在配置文件http区域之后添加rtmp区域
rtmp {
server {
listen 1935; //监听端口1935
chunk_size 4096; //chunk的大小设定
application hls {
live on;
hls on; //实时回访
hls_path /data/wwwroot/hls; //媒体块的存放位置,这个目录是安装完nginx自建的
hls_fragment 3s; //每个ts文件为3秒
}
}
}
3.检测nginx的配置文件并重启
[root@iZ2ze0a8w2ct7mzctse5r5Z ~]# nginx -t
nginx: the configuration file /usr/local/tengine/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/tengine/conf/nginx.conf test is successful
[root@iZ2ze0a8w2ct7mzctse5r5Z ~]# systemctl reload nginx.service
3.使用OBS Studio推流
1.mac下的软件下载
wget https://cdn-fastly.obsproject.com/downloads/obs-mac-24.0.2-installer.pkg
2.使用
操作很简单,但是这里需要注意设置中推流的服务器和串流密钥的设置
举例:
服务器:rtmp://47.94.38.112:1935/hls
串流密钥:ssxx
那么访问的地址就是:http://DomainName(域名)/hls/ssxx.m3u8
总结
希望大家能和我一样通过这个例子对视频直播流媒体技术相关的基础概念有一个基本的认知
也希望我花时间整理的文章能帮到大家。~~~
补充说明
关于H.264
编码名词 | 说明 |
---|---|
空间冗余 | 图像的相邻像素之间有较强的关联性,一张图片相邻的像素基本是渐变的不是突变的,所以没必要每个像素都完整的保留 |
时间冗余 | 视频中相邻图片之间的内容相似,连续出现的图片也不是突变的,可以根据已有的图片进行预测和推断 |
视觉冗余 | 人的视觉系统允许某些细节的丢失也就是允许丢失一些数据 |
编码冗余 | 不同像素值出现的概率不同,概率高的用的字节少,概率低的用的字节多 |
帧内预测 | 去除空间冗余 |
帧间预测 | 去除时间冗余 |
变换 | 去除空间冗余 |
量化 | 去除视觉冗余,通过降低图像质量提高压缩比 |
熵编码 | 去除编码冗余 |
GOP | 关键帧间隔,从I帧开头到下一个I帧结束,是一些按顺序排序的图像帧的组合。GOP值,表示俩个关键帧之间的间隔 |
I帧 | 关键帧里面是完整的图片,只需要本帧数据即可以完成编码 ;帧内编码帧,无需参考其他图像可以进行独立编码,也就是说是不依赖前后帧的独立的一帧图像 |
P帧 | 前向预测编码帧,表示这一帧和前一关键帧的差别,解码时需要用之前缓存的画面叠加和本帧定义的差别生成最终画面;需要参考I帧才能进行编码,采用运动预测的方式进行帧间编码,基于帧间预测计算得到的帧 |
B帧 | 双向预测内插编码帧,记录本帧与前后帧的差别,要解码B帧需要前后画面的数据与本帧数据的叠加取得最终画面;采用运动预测的方式进行帧间双向预测编码 |
NALU | Network Abstraction Layer Unit,网络提取层单元,H264的基本结构,由起始标志符和NALU头和Palyload承载的数据构成 |
原始码流 | 由一个接一个的NALU组成,我的理解NALU序列 |
片 | 在一帧中分成多个片 |
宏块 | 在一片中分成多个宏块 |
子块 | 在一个宏块中分成多个子块,这样做的目的是为了方便进行空间上的编码 |
NALU头 | 0x07表示SPS序列参数集,包含一个图像序列的所有信息;0x08表示PPS图像参数集,包含一个图像的所有分片的所有信息 |
pts | 表示该帧播放的相对时间戳 |
dts | 表示该帧解码的相对时间戳 |
在字节大小方面,P帧,B帧远小于I帧,GOP太大会导致首屏播放时间变长,GOP太小会导致I帧的比例增大,压缩比降低,同码率下视频播放的质量降低。理论上pts是单调递增的,推流源流时间戳异常会导致pts突变。也会导致录制的时长有问题,导致转码水印异常,花屏等问题。
如何修复录制文件:
1.剔除异常帧。
2.对记录的每个视频帧重新设置pts。
常用测试命令
1.查看一个视频中关键帧的分布情况:
ffprobe -v error -show_frames "rtmp://rtstest.kivensu.club/rtstest0211/rtstest0211?auth_key=1644576853-0-0-635196d1093d1d1f980e427c9bd7af76" | grep pict_type
2.查看pts,dts。
ffprobe -show_frames https://cloud.video.taobao.com/play/u/null/p/1/e/6/t/1/d/ud/344704485848.mp4
pkt_pts=1945600
pkt_dts=1945600
3.视频截取
use stream copying & input seeking
ffmpeg -ss 00:01:01 -i gemfield.mp4 -t 4 -c copy cut1.mp4
use stream copying & output seeking
ffmpeg -i gemfield.mp4 -ss 00:01:01 -t 4 -c:v copy cut2.mp4
use transcoding & input seeking
ffmpeg -ss 00:01:01 -i gemfield.mp4 -t 4 -c:v libx264 cut3.mp4
use transcoding & output seeking
ffmpeg -i gemfield.mp4 -ss 00:01:01 -t 4 -c:v libx264 cut4.mp4