直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

时间:2024-03-31 08:34:54

直播协议

RTMP(Real Time Messaging Protocol)

简介

Time Messaging Protocol,实时消息传送协议

RTMP是Adobe公司为Flash播放器和服务器之间音频、视频和数据传输开发的开放协议。

协议:长连接TCP

原理:每个时刻的数据,收到后立即转发

延迟:1~3秒

优点

  • 实时性高:一般能做到3秒内。
  • 支持加密:rtmpe和rtmps为加密协议。
  • 稳定性高:在PC平台上flash播放的最稳定方式是rtmp,如果做CDN或者大中型集群分发,选择稳定性高的协议一定是必要的。
  • 一般主流编码器都支持该协议。

缺点

  • 协议复杂:开发者写起来累,效率也不行。
  • Cache麻烦:流协议做缓存不方便。

RTSP(Real Time Streaming Protocol)

简介

实时流协议(Real Time Streaming Protocol,RTSP)是一种网络应用协议,专为娱乐和通信系统的使用,以控制流媒体 服务器。该协议用于创建和控制终端之间的媒体会话。媒体服务器的客户端发布VCR命令,例如播放,录制和暂停,以便于实时控制从服务器到客户端(视频点播)或从客户端到服务器(语音录音)的媒体流。

Time Streaming Protocol,实时流传输协议)

优点

●  延迟低,一般都能够做到500ms。

●  带宽好,时效率高。

●  倍速播放,主要是回放的时候提供的功能。

●  控制精准,任意选择播放点。

缺点

●  服务端实现复杂。

●  代理服务器弱:数量少,优化少。

●  无路由器防火墙穿透

●  管流分离:需要1-3个通道。

HLS(HTTP Live Streaming)

简介

HTTP Live Streaming(缩写是HLS)是一个由苹果公司提出的基于HTTP流媒体网络传输协议。是苹果公司QuickTime XiPhone软件系统的一部分。它的工作原理是把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的extended M3U (m3u8) playlist文件,用于寻找可用的媒体流。

协议:短链接HTTP

原理:集合一段时间数据,生成ts切片文件,更新m3u8

延迟:>10秒

优点

●  性能好:和http一样。

●  穿墙:和http一样。

●  原生支持很好:iOS上支持完美,Android上支持差些。PC/flash上现在也有各种as插件支持HLS。

缺点

●  实时性差:与ts切片长度有关,大约3个切片长度时间的延迟,基本上HLS的延迟在10秒以上。

●  文件碎片:若分发HLS,码流低,切片较小时,会导致太多的文件碎片

流媒体服务器

主要介绍

  1. NGINX-rtmp
  2. Node-media-server
  3. livego
  4. SRS

NGINX-rtmp

简介:基于NGINX的流媒体服务器

支持协议:RTMP/HLS/MPEG-DASH

支持平台:Linux/FreeBSD/MacOS/Windows

官网:https://github.com/arut/nginx-rtmp-module

如果是windows平台,可直接下载编译好的文件

https://github.com/illuspas/nginx-rtmp-win32

Node-media-server

简介:A Node.js implementation of RTMP/HTTP-FLV/WS-FLV/HLS/DASH/MP4 Media Server

支持协议:RTMP/HTTP-FLV/WS-FLV/HLS/DASH

支持平台:Windows/Linux/Unix

官网:https://github.com/illuspas/Node-Media-Server/

一分钟部署一个流媒体服务

https://github.com/illuspas/Node-Media-Server/wiki/%E4%B8%80%E5%88%86%E9%92%9F%E9%83%A8%E7%BD%B2%E4%B8%80%E4%B8%AA%E6%B5%81%E5%AA%92%E4%BD%93%E6%9C%8D%E5%8A%A1

livego

简介:纯 Go 写的直播服务器

支持协议:RTMP/AMF/HLS/HTTP-FLV

支持平台:Windows/Linux/MacOS

官网:https://github.com/gwuhaolin/livego

SRS

简介:SRS定位是运营级的互联网直播服务器集群,追求更好的概念完整性和最简单实现的代码。

支持协议:RTMP/RTSP/HSL/HTTP-FLV

支持平台:Linux/MacOS

官网:https://github.com/ossrs/srs

这个功能比较强大,官网文档很详细,具体去官网看吧

如果想在windows体验,可下载网友修改的版本

https://github.com/illuspas/srs-win32

导致延迟因素

网络延时

网络延时这里指的是从主播端采集,到观众端播放,之间的时间差。这里不考虑主播段采集对视频进行编码的时间,以及观众端观看对视频进行解码的时间,仅考虑网络传输中的延时。例如说下图中的网络延时:

直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

假设在该链路上有缓存,时间为Tmax_cache ,那么从主播到观众的延时Tdelay为:

 

另外,数据传输过程中还涉及到逻辑上的交互,例如包的重传以及确认,以及缓存上的一些逻辑等,会在这个基础上又增加很多。

那么来简单估算一下大概的网络延时。众所周知,光在真空中的速度约为300,000km/s,而在其他介质中光速会大大降低,所以在普通光纤中,工程上一般认为传输速度是200,000km/s。从现实上来说,可以参考如下:

路线

距离(km)

往返时延(ms)

北京到上海

1,200

12

北京到纽约

11,000

110

赤道周长

40,000

400

所以说,在节点较少、网络情况较好的情况下,那么网络延时对应也是最小,加上一定的缓存,可以控制延时在1s~2s左右。但是节点多、网络差的情况下,网络延时会对应增大,经验来说延时可以达到15s以上。

网络抖动

网络抖动,是指数据包的到达顺序、间隔和发出时不一致。比如说,发送100个数据包,每个包间隔1s发出。结果第27个包在传输过程中遇到网络拥塞,造成包27不是紧跟着26到达的,而是延迟到87后面才达。在直播中,这种抖动的效果实际上跟丢包是一样的。因为你不能依照接收顺序把内容播放出来,否则会造成失真。

网络抖动,会造成播放延时对应增大。如果网络中抖动较大,会造成播放卡顿等现象。

直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

如上图所示,主播端t3和t5发出的包,分别在t3'和t5'到达,但是中间延时增大,即发生了网络抖动。这样造成观众端观看视频的延时会不断增大。

网络丢包

CDN直播中用到的RTMP、HLS、HTTP FLV等协议都是在TCP的基础之上。TCP一个很重要的特性是可靠性,即不会发生数据丢失的问题。为了保证可靠性,TCP在传输过程中有3次握手,见下图。首先客户端会向服务端发送连接请求,服务端同意后,客户端会确认这次连接。这就是3次握手。接着,客户端就开始发送数据,每次发送一批数据,得到服务端的“收到”确认后,继续发送下一批。TCP为了保证传到,会有自动重传机制。如果传输中发生了丢包,没有收到对端发出的“收到”信号,那么就会自动重传丢失的包,一直到超时。

直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

由于互联网的网络状况是变化的,以及主播端的网络状况是无法控制的。所以当网络中丢包率开始升高时,重传会导致延时会不断增大,甚至导致不断尝试重连等情况,这样不能有效的缓存,严重情况下会导致观众端视频无法观看。

RTMP累积延迟

此延迟只发生在RTMP协议中

RTMP有个弱点就是累积误差,原因是RTMP基于TCP,而TCP不会丢包,(可能丢包,但是利用TCP的重传机制避免)。

所以当网络状态差时,服务器会将包缓存起来,导致累积的延迟;

待网络状况好了,就一起发给客户端。

这个的对策就是,当客户端的缓冲区很大,就断开重连。

GOP-Cache

图像群组Group opictures,GOP)

原理比较复杂,这里就不班门弄斧了,具体可以Google

RTMP延迟

直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

图片来自:https://www.processon.com/view/56ebb341e4b01c9aeb5f137f

看完上图你大概就能明白了,rtmp的延迟是和gop挂钩的。

那么,为什么rtsp延迟会比rtmp低呢?因为,它是精确控制的,可以跳出这个以gop组为单位的控制。

视频基本属性

帧率(frame rate)

帧指的是码流中的单张画面,帧率指单位时间内码流的帧数,单位fps(frame per second)。我们看到的视频是由一帧帧的画面,也就是一张张的图片构成;如果一秒钟跑过去的图片有24张,帧率就是24帧/秒(fps);只有8张,帧率就是8帧/秒(fps);帧率越大,画面就越流畅,当然大到一定程度,也不需要过大了,一方面肉眼也看不出有毛区别,另一方面电脑吃不消啊!

直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

 

常见帧率

电影:23.976fps

电视(PAL):25fps

电视(NTSC):29.97fps

CRT显示器:60Hz-85Hz

液晶显示器:60Hz-75Hz

3D显示器: 120Hz

分辨率(resolution)

分辨率指的是画面的尺寸大小,分辨率越高,图像越大。

一般的,在码率一定的情况下,分辨率越高,视频质量越差。

分辨率有图像分辨率与显示分辨率两种,图像分辨率指图像的尺寸大小,显示分辨率指屏幕分辨率。

对于视频而言,有一些固定尺寸的分辨率标准,如D1(720×576)、4CIF(704×576)、VGA(640×480)、SVGA(800×600)、VXGA(1600×1200)等,后来对于固定比例(16:9)的画面,分辨率的的表示方法为纵向高度加扫描方式,如720P(1280×720,逐行扫描)、1080P(1920×1080,逐行扫描)、1080I(1920×1080,隔行扫描),再到后面,使用横向像素描述,如2K(2048×1536或2560×1440或2560×1600)、4K(4096×2160或3840×2160)、8K(7680×4320)。

码率(bit rate)

码率即比特率,指单位时间内产生的数据位,单位bps(bit per second),1Mbps=1024kbps=1048576bps。一般的,分辨率一定的情况下,码率越高,视频质量越好。

(*注意bps与B/s的区别,1B/s=8bps。)

通常,720P的码流码率在2~4Mbps左右,1080P的码流码率在4~8Mbps左右,对于用户来说则是宽带要求,要看720P的视频需要至少2M的带宽,要看1080P的视频需要至少4M的带宽,当前国内的网络环境下,上下行速率不对等,如果主播要使用高清视频,还得确保主播上行带宽足够。

直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

编码方式

平常我们总在想,如何让视频文件更小,让视频更清晰呢?答案就在码率上,对码率进行处理,就叫做编码方式,一般有CBR/ABR/VBR三种方式.

直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

 

CBR全称constant bitrate,意思是固定码率,就是在整个视频当中,码率固定不变;

VBR全称Variable Bitrate,意为可变码率。其实在视频当中,画面内容越丰富,所需码率越高,成像质量也会越好,画面内容不怎么丰富的地方用高码率就是浪费,所以可变码率根据画面内容的丰富程度自动调节,保证成像质量的同时,让文件变得更小。所以要让视频文件更小,内容更清晰,采用VBR的编码方式,并设定科学的数值,就是解决问题的关键。

ABR全称average bitrate ,意为平均码率,是一种介于CBR和VBR之间的折中方式。

Codec 视频编码方式

直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

其中,MPEG-1的编码用于老VCD,MPEG-2的编码用于DVD,之后的MPEG-4被用于更多更广泛的平台,这里的MPEG-4就是传说中的MP4;

直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

另外呢,还有一个叫做国际电传视讯联盟(ITU)主导的另一套编码方式,称为H.26X系列,之后与MPEG合作弄出了H.264编码方式,成为如今最热门的编码方式。

直播技术学习笔记(直播协议+流媒体服务器+音视频处理+FFmpeg)

Container format视频封装格式

参考:https://en.wikipedia.org/wiki/Comparison_of_video_container_formats

主要封装格式一览

名称

推出机构

流媒体

支持的视频编码

支持的音频编码

目前使用领域

AVI

Microsoft Inc.

不支持

几乎所有格式

几乎所有格式

BT下载影视

MP4

MPEG

支持

MPEG-2, MPEG-4, H.264, H.263等

AAC, MPEG-1 Layers I, II, III, AC-3等

互联网视频网站

TS

MPEG

支持

MPEG-1, MPEG-2, MPEG-4, H.264

MPEG-1 Layers I, II, III, AAC,

IPTV,数字电视

FLV

Adobe Inc.

支持

Sorenson, VP6, H.264

MP3, ADPCM, Linear PCM, AAC等

互联网视频网站

MKV

CoreCodec Inc.

支持

几乎所有格式

几乎所有格式

互联网视频网站

RMVB

Real Networks Inc.

支持

RealVideo 8, 9, 10

AAC, Cook Codec, RealAudio Lossless

BT下载影视

 

如何降低延迟时间

参考:

FFEMPEG方面

wiki:StreamingGuide

https://trac.ffmpeg.org/wiki/StreamingGuide

Low-Latency Live Streaming your Desktop using ffmpeg

http://fomori.org/blog/?p=1213

ffmpeg的转码延时测试与设置优化

https://blog.csdn.net/fireroll/article/details/51902018

FFmpeg推流延迟10秒问题记录

https://blog.csdn.net/vanjoge/article/details/79545490

ffplay播放视频源延时的参数设置

https://blog.csdn.net/cai6811376/article/details/52637158

Web直播系列4——ffmpeg实时推流+nginx负载均衡降低直播延时_1

https://blog.csdn.net/zzhang_12/article/details/79798027

ffmpeg拉流rtmp音频实时数据有延时的解决方法

https://blog.csdn.net/a1317338022/article/details/78226834

如何实现1080P延迟低于500ms的实时超清直播传输技术

http://windrunnerlihuan.com/2016/09/18/%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B01080P%E5%BB%B6%E8%BF%9F%E4%BD%8E%E4%BA%8E500ms%E7%9A%84%E5%AE%9E%E6%97%B6%E8%B6%85%E6%B8%85%E7%9B%B4%E6%92%AD%E4%BC%A0%E8%BE%93%E6%8A%80%E6%9C%AF/

FFMPEG参数说明

参考:

https://blog.csdn.net/leixiaohua1020/article/details/12751349

https://trac.ffmpeg.org/wiki/Encode/H.264

主要参数

  • -i——设置输入档名。
  • -f——设置输出格式。
  • -y——若输出文件已存在时则覆盖文件。
  • -fs——超过指定的文件大小时则结束转换。
  • -t——指定输出文件的持续时间,以秒为单位。
  • -ss——从指定时间开始转换,以秒为单位。
  • -t从-ss时间开始转换(如-ss 00:00:01.00 -t 00:00:10.00即从00:00:01.00开始到00:00:11.00)。
  • -title——设置标题。
  • -timestamp——设置时间戳。
  • -vsync——增减Frame使影音同步。
  • -c——指定输出文件的编码。
  • -metadata——更改输出文件的元数据
  • -help——查看帮助信息。

视频参数

  • -b:v——设置视频流量,默认为200Kbit/秒。(单位请引用下方注意事项
  • -r——设置帧率值,默认为25。
  • -s——设置画面的宽与高。
  • -aspect——设置画面的比例。
  • -vn——不处理视频,于仅针对声音做处理时使用。
  • -vcodec( -c:v )——设置视频视频编解码器,未设置时则使用与输入文件相同之编解码器。

声音参数

  • -b:a——设置每Channel(最近的SVN版为所有Channel的总合)的流量。(单位请引用下方注意事项
  • -ar——设置采样率。
  • -ac——设置声音的Channel数。
  • -acodec ( -c:a ) ——设置声音编解码器,未设置时与视频相同,使用与输入文件相同之编解码器。
  • -an——不处理声音,于仅针对视频做处理时使用。
  • -vol——设置音量大小,256为标准音量。(要设置成两倍音量时则输入512,依此类推。)

注意事项

  • 以-b:v及-b:a首选项流量时,根据使用的ffmpeg版本,须注意单位会有kbits/sec与bits/sec的不同。(可用ffmpeg -h显示说明来确认单位。)

例如,单位为bits/sec的情况时,欲指定流量64kbps时需输入 -b:a 64k;单位为kbits/sec的情况时则需输入 -b:a 64。

  • 以-acodec及-vcodec所指定的编解码器名称,会根据使用的ffmpeg版本而有所不同。例如使用AAC编解码器时,会有输入aac与libfaac的情况。此外,编解码器有分为仅供解码时使用与仅供编码时使用,因此一定要利用ffmpeg -formats确认输入的编解码器是否能运作。

直播中常见参数

-preset

按编码速度的内置参数,内置的编码设置有:

  1. ultrafast
  2. superfast
  3. veryfast
  4. faster
  5. fast
  6. medium
  7. slow
  8. slower
  9. veryslow
  10. placebo

按快到慢排列,默认为medium级,当然越慢效果越好,但是体积会增大,一般最求高质量用veryslow就够了。

-tune

按不同的源或者不用的应用场景的内置参数

  1. film:电影、真人类型
  2. animation:动画
  3. grain:需要保留大量的grain时用
  4. stillimage:静态图像编码时使用
  5. psnr:为提高psnr做了优化的参数
  6. ssim:为提高ssim做了优化的参数
  7. fastdecode:可以快速解码的参数
  8. zerolatency:零延迟,用在需要非常低的延迟的情况下,比如电视电话会议的编码

在命令行中输入:ffmpeg -h encoder=libx264

参考:

https://my.oschina.net/u/3733374/blog/1581609

https://www.zhihu.com/question/23651189

https://blog.csdn.net/leixiaohua1020/article/details/18893769

https://sdk.cn/news/5556