最近要做一个视频系统,目前需求是开发一个编解码服务器,先熟悉一下流媒体一些专有名词。
标准的PCM编码的立体声音乐(采样速率44.1kHz,采样脉冲16位编码)信号的比特率超过了1.4Mbit/s。分辨率1280×720,每个像素采用24位RGB编码,帧率24fps,则其比特率将超过60Mbit/s。因此网络传输多媒体信息都无一例外地采用各种压缩技术,如MP3(128kbit/s),MP4(40Mbit/s).
数字化后的多媒体数据,在发送端其分组往往是等时地发送的,但互联网本身并非等时的,而接收端只有按照原视频文件的规定速率读取帧才能正常播放,因而又是等时的。解决该问题的一个可行方法是在接收端设置适当大小的缓存。当缓存中的分组达到一定数量时再以恒定速率取出分组进行还原播放。缓存使得所有不定时到达的分组都经受了时延,导致了固定的播放时延,但在很大程度上消除了时延抖动。
互联网传输实时数据的分组有可能差错或丢失,如果利用TCP协议对这些丢失分组进行重传,那么延时就会大大增加。因此实时数据的传输在运输层就当采用用户数据报协议UDP而不是TCP协议。也就是说我们宁可丢失分组,也不要太晚到达的分组。另外,分组到达不一定按序,而分组播放又需要按序,因此分组中应当含有序号。分组还应当增加一个时间戳以使接收端知道分组是何时产生的。这些都需要新的协议支持才行。

RTSP是一种应用层协议,用于控制流媒体服务器的多媒体会话,支持播放、暂停等VCR式操作。它不直接传输媒体数据,而是通过RTP/RTCP实现数据传输,默认使用TCP端口554。RTSP在视频监控、点播系统中广泛应用,但移动端浏览器支持较差。
尽管RTSP协议也支持推流/拉流,且支持TCP、UDP切换以及其他诸多优点。但是泛用性不足,特别是现在的浏览器都不支持RTSP的播放。
RTSP一般不用作直播场景,RTSP一般用作摄像头、监控等硬件设备的实时视频流观看与推送上。
RTSP包含以下特色:
RTMP 是 Adobe 公司开发的用于音视频和数据实时传输的协议,最初用于 Flash 播放器,后成为流媒体领域的常用协议。它既传输控制消息,也直接传输媒体数据,基于 TCP(默认端口 1935)保证可靠性。
RTMP协议是既可以推流、也可以拉流的协议。RTMP地址是rtmp:// 开头的,且推流地址与播放地址是一样的。
RTMP具有以下特色:
由IETF AVT小组开发,已成为正式标准,同时也是ITU-T的标准[RFC 3550, 3551]。RTP为实时应用提供端到端的运输,但不提供对服务质量的保证,需要RTCP来保证质量。RTP类似于一个协议框架,它只包含实时应用所需的共同功能,其本身并不对多媒体数据做任何处理,而只是在应用层数据前追加了一些附加信息,让应用层知道该如何处理。
另外,应用层数据被封装成的RTP分组只包含RTP数据,而控制是由另一个配套使用的协议RTCP提供的。RTP没有分发机制,它必须与UDP一起使用。RTP必须为偶数端口号,而下一奇数UDP端口留给同一会话中的RTCP使用。
默认情况,RTP端口为5004,RTCP端口为5005。

地址是http:// 开头的,是基于HTTP协议的HTTP-FLV可以简单地理解为RTMP的HTTP协议版本。功能和工作原理上是相似的,上面提到的RTMP切片数据功能HTTP-FLV也是有的。但是,HTTP-FLV协议一般只能用作拉流观看。HTTP-FLV协议的延迟也是比较低的,大概在1-3秒左右,但实际体验下来 HTTP-FLV延迟会略高于RTMP,但是HTTP-FLV相对RTMP适配更多的播放场景。
现在比较流行的方案是,直播源推流是RTMP协议,直播拉流观看是HTTP-FLV协议。
HLS协议一般只用作拉流观看,但是从严格意义上讲,HLS协议并不是流式协议。它工作原理很简单,就是通过HTTP协议下载静态文件。不同的是,HLS协议的文件由两部分组成,一是多个只有几秒长度的.ts碎片视频文件,另一个是记录这些视频文件地址的.m3u8索引文件,且这些静态文件都是直接写入磁盘的。更具体的说,HLS观看地址是以http:// 开头、.m3u8结尾的,实际上这个地址就是索引文件的地址,客户端获取到索引文件后,就可以下载对应的碎片视频文件并开始播放了。由于HLS协议实际上是通过HTTP协议请求文件的,且HLS相关文件是直接写入磁盘的,所以并不需要特殊的流媒体服务软件,使用Nginx等HTTP服务就可以了。
点播的场景下,也就是普通网络视频观看的场景下。.m3u8索引文件会记录所有的碎片视频文件地址,HLS在点播的场景下,优势是更加明显的。由于HLS的相关文件是无状态的静态文件,且每个文件的大小是有限的,所以负载均衡、CDN加速的效果更佳明显。HLS协议的点播视频,会比.mp4、.flv的视频更快地播放出来,且在加载中跳转视频也会更加顺滑。
直播的场景下,转码软件可以直接生成HLS相关文件到磁盘,客户端通过HTTP服务下载文件即可。视频流数据每几秒会打包成一个以.ts为后缀的碎片视频文件,每生成一个新的视频文件都会同步更新.m3u8索引文件。且碎片视频文件的个数是有上限的,当达到上限后,默认会将最旧的视频文件删除且更新.m3u8索引文件。所以在直播的场景下,客户端也需要不断定时重新获取.m3u8索引文件。HLS协议在直播的场景下是没什么优势的。虽然HLS协议的直播流也可以适配很多播放场景,但是由于需要生成静态文件,直播延迟很大,大概在5-30秒左右,使用直播CDN的话,由于边缘节点同步等问题,直播延迟甚至可能会达到1分钟左右。
当然HLS协议也有一定的优势,在直播时移,也就是直播转点播,或者录播,也就是点播转直播的场景, 理论上只需要修改索引文件就可以了。另外,HLS协议的.m3u8索引文件支持二级索引,就是高清、标清、流畅等多个观看地址可以整合到一个索引文件。播放器可以根据当前带宽自动切换不同的观看地址,大部分网页播放器的“自动”也是因为这个。
WebRTC协议其实并不是为了直播场景而设计的,WebRTC是一种点对点的视频/语音通话协议。由于WebRTC是基于UDP的,建立通信后,会不断以流式发送数据,所以延迟会比RTMP还要低。在一些交互性较高的直播场景,如直播带货等场景,会使用WebRTC作为推流和观看协议 WebRTC的延迟理论上可以达到1秒内。

WebRTC协议支持推流和拉流,地址一般是以webrtc:// 开头的,且推流和拉流地址一般也是一样的。WebRTC虽然是点对点的协议,但是应用在直播场景的话,是需要搭建WebRTC服务器作为流媒体服务的。
| 流媒体协议 | 传输层 | 延时 | 优势 | 劣势 | 数据 | 支持H.265 | 适合场景 |
|---|---|---|---|---|---|---|---|
| RTMP | TCP | 中低延时1 - 3s | 实时性好,支持多种编码格式 | 依赖Flash,安全性较差 | 流 | 否 | 直播、游戏流媒体 |
| HLS(m3u8) | TCP | 中高延时10 - 30s | 跨平台支持好,兼容性强 | 延时相对较高,启动时间长 | 切片 | 是 | 点播、直播(尤其是苹果设备) |
| WebRTC | UDP | 超低延时0.1 - 0.5s | 实时通信,支持P2P传输 | 浏览器支持不一,网络条件要求高 | 流 | 否 | 视频会议、实时互动 |
| RTSP | TCP/RTP/RTCP | 低中延时0.2 - 1s | 适合实时流媒体,支持多种传输协议 | 兼容性较差,防火墙穿透困难 | 流 | 是 | 监控摄像头、实时视频流 |
| HTTP-FLV | TCP | 中等延时1 - 3s | 简单易用,基于HTTP协议,兼容性强 | 延时较高,流媒体的实时性不足 | 流 | 否 | 直播、点播(尤其是网页应用) |
| RTP | UDP | 低中延时0.2 - 1s | 支持多路分发、可扩展RTCP | 不提供可靠性(不丢包)保证,不提供顺序性和完整性 | 流 | 否 | 直播、单向推送 |
图像,大家都知道,是由很多“带有颜色的点”组成的。这个点,就是“像素点”像素是图像显示的基本单位。我们通常说一幅图片的大小,例如是1920×1080,就是长度为1920个像素点,宽度为1080个像素点。乘积是2,073,600,也就是说,这个图片是两百万像素的。1920×1080,这个也被称为这幅图片的分辨率
帧率简单地说,帧数就是在1秒钟时间里传输的图片的数量,单位为fps。视频压缩中,每帧代表一幅静止的图像。而在实际压缩时,会采取各种算法减少数据的容量,其中IPB就是最常见的:
在视频编码中,有一个概念叫做GOP,就是帧分组,两个关键帧之间有多少个编码帧(P帧和B帧),两个关键帧之间帧的多少直接影响到对图像的解码和编码。如果两个关键帧之间的帧比较多,那么从P帧和B帧的定义我们知道,解码程序就需要缓冲更多的中间解码帧,内存消耗就会比较多,而且GOP越长,那么B帧的帧数会越来越多,这直接影响到图像失真率,所以,不是GOP越长就会越好。那么,如果GOP越短,B帧就会越小,这种情况下图像的失真率就会越小,但是同时压缩率也会越小,对应的比特率就会越大,在网络上传输需要的带宽就会越多,所以,GOP不是越长越好,也不是越短越好,需要找一个合适位置,这个时候就是关键帧发挥作用的关键了。I帧与I帧之间的间隔便为GOP。那GOP的大小影响了什么呢,其实就是时延、带宽,清晰度等问题
帧内压缩:也称为空间压缩(Spatial compression)。当 压缩一帧图像时,仅考虑本帧的数据而不考虑相邻帧之间 的冗余信息,这实际上与静态图像压缩类似。帧内一般采 用有损压缩算法,由于帧内压缩是编码一个完整的图像, 所以可以独立的解码、显示。帧内压缩一般达不到很高的 压缩,跟编码jpeg差不多。帧内压缩是生成I帧的算法。
帧间压缩:相邻几帧的数据有很大的相关性,或者说前后 两帧信息变化很小的特点。也即连续的视频其相邻帧之间 具有冗余信 息,根据这一特性,压缩相邻帧之间的冗余量就 可以进一步提高压缩量,减小压缩比。帧间压缩也称为时 间压缩(Temporal compression),它通过比较时间轴上 不同帧之间的数据进行压缩。帧间压缩一般是无损的。帧 差值(Frame differencing)算法是一种典型的时间压缩 法,它通过比较本帧与相邻帧之间的差异,仅记录本帧与 其相邻帧的差值,这样可以大大减少数据量。 帧间压缩是生成B帧和P帧的算法。
码率就是数据传输时单位时间传送的数据位数,一般我们用的单位是kbps即千位每秒。通俗一点的理解就是取样率,单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件,但是文件体积与取样率是成正比的,所以几乎所有的编码格式重视的都是如何用最低的码率达到最少的失真,围绕这个核心衍生出来的cbr(固定码率)与vbr(可变码率),从音频方面来说,码率越高,被压缩的比例越小,音质损失越小,与音源的音质越接近。
比特率是指每秒传送的比特(bit)数。单位为 bps(Bit Per Second),比特率越高,传送的数据越大。比特率表示经过编码(压缩)后的音、视频数据每秒钟需要用多少个比特来表示,而比特就是二进制里面最小的单位,要么是0,要么是1。比特率与音、视频压缩的关系,简单的说就是比特率越高,音、视频的质量就越好,但编码后的文件就越大;如果比特率越少则情况刚好相反。
码率计算公式,例如19201080 分辨率的话 码率=19201080帧率每个像素的大小,就是对应帧率下1S的码率。
H.264是MPEG-4标准的第十部分,目前国内使用比较多的视频压缩格式, 与其他编码格式相比,同等画面质量,文件体积最小。电脑及部分便携式视频设备都可播放。常见于高清视频中,压缩率高,图像清晰。H.264最大的优势是高性能,因此目前网络资源中的高清视频格式(即MKV、AVI、 MPG,TS)多采用H.264编码的视频流。
在H264中图像以序列为单位进行组织,一个序列是一段图像编码后的数据流,以I帧开 始,到下一个I帧结束。一个序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像。 H.264 引入 IDR 图像是为了解码的重同步,当解码器解码到 IDR 图像时,立即将参考 帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序 列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像 之后的图像永远不会使用IDR之前的图像的数据来解码。 一个序列就是一段内容差异不太大的图像编码后生成的一串数据流。
当运动变化比较少时,一个序列可以很长,因为运动变化少就代表图像画面的内容变动很小,所以就 可以编一个I帧,然后一直P帧、B帧了。当运动变化多时,可能一个序列就比较短了, 比如就包含一个I帧和3、4个P帧。
H264 的优点是成熟、稳定、高效、灵活,缺点是需要付费专利费用,并且难以满足超高清(4K/8K)视频的需求。
H.265是新的编码协议,是H.264的升级版。H.265相比H.264最主要的改变是采用了块的四叉树划分结构,也极大了优化了算法,H.265比H.264占用的存储 空间理论上要少50%。H.265在各方面都碾压了H.264。 H265优点:降低存储空间。比起H.264/AVC,H.265/HEVC提供了更多不同的工具来降低码率,以编码单位来说,H.264中每个宏块(macroblock/MB)大小都是固定的16x16像素,而H.265的编码单位可以选择从最小的8x8到最大的64x64。那么,在相同的图像质量下,相比H.264,通过H.265编码的视频大 小将减少大约39-44%。
优点:压缩率高
缺点:计算复杂,编解码需要更强的计算能力
| 压缩率 | 1080P/24FPS带宽需求 | 编码延迟/帧 | 解码延迟/帧 | 总延迟差/S | |
|---|---|---|---|---|---|
| H264 | 150-250倍 | 4.67MBps-7.78MBps | 0.5ms | 23ms | 180ms-432ms |
| H265 | 300-500倍 | 2.34MBps-3.89MBps | 1.2-1.5ms | 30-40ms |
注:
码率计算:码率(bps) = 分辨率(像素数)× 帧率(fps)× 每像素比特数 × 压缩比;
色深:色深表示每个像素所用的位数,常见的有8位、10位等。色深越高,视频质量越好,但数据量也越大。 RGB三原色中每一个颜色有256个数值,正好是2的8次方,我们知道在计算机里一个数字是1bit, 那么用8位的二进制数来表达,刚好能表达256个数值,那么刚好就是8bit可以表达一个原色, 也就是说RGB三原色每个颜色占用8bit,三个颜色就是24bit,这种方式表达的颜色也被称为24位色。
参考博客:
https://blog.csdn.net/zzhongcy/article/details/131779684
https://blog.csdn.net/qq_25218777/article/details/149755059
本文作者:刘涛
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!