直播应用中,RTMP和HLS基本上可以覆盖所有客户端观看(参考:DeliveryHLS),HLS主要是延时比较大,RTMP主要优势在于延时低。
低延迟的部署实例参考:Usage: Realtime
低延时应用场景包括:
RTMP的特点如下:
主要有人老是问这个问题,如何降低HLS延迟。
HLS解决延时,就像是爬到枫树上去捉鱼,奇怪的是还有人喊,看那,有鱼。你说是怎么回事。
我只能说你在参与谦哥的魔术表演,错觉罢了。
如果你真的确信有,请用实际测量的图片来展示出来,参考下面延迟的测量。
如何测量延时,是个很难的问题,不过有个行之有效的方法,就是用手机的秒表,可以比较精确的对比延时。参考:RTMP延时测量
经过测量发现,在网络状况良好时:
什么是GOP?就是视频流中两个I帧的时间距离,如果问什么是I帧就去百度。
GOP有什么影响?Flash(解码器)只有拿到GOP才能开始解码播放。也就是说,服务器一般先给一个I帧给Flash。可惜问题来了,假设GOP是10秒,也就是每隔10秒才有关键帧,如果用户在第5秒时开始播放,会怎么样?
第一种方案:等待下一个I帧,也就是说,再等5秒才开始给客户端数据。这样延迟就很低了,总是实时的流。问题是:等待的这5秒,会黑屏,现象就是播放器卡在那里,什么也没有,有些用户可能以为死掉了,就会刷新页面。总之,某些客户会认为等待关键帧是个不可饶恕的错误,延时有什么关系?我就希望能快速启动和播放视频,最好打开就能放!
第二种方案:马上开始放,放什么呢?你肯定知道了,放前一个I帧。也就是说,服务器需要总是cache一个gop,这样客户端上来就从前一个I帧开始播放,就可以快速启动了。问题是:延迟自然就大了。
有没有好的方案?有!至少有两种:
SRS的配置项:
# the listen ports, split by space.
listen 1935;
vhost __defaultVhost__ {
# whether cache the last gop.
# if on, cache the last gop and dispatch to client,
# to enable fast startup for client, client play immediately.
# if off, send the latest media data to client,
# client need to wait for the next Iframe to decode and show the video.
# set to off if requires min delay;
# set to on if requires client fast startup.
# default: on
gop_cache on;
}
备注:参考conf/full.conf的min.delay.com配置。
除了GOP-Cache,还有一个有关系,就是累积延迟。SRS可以配置直播队列的长度,服务器会将数据放在直播队列中,如果超过这个长度就清空到最后一个I帧:
vhost your_vhost {
# the max live queue length in seconds.
# if the messages in the queue exceed the max length,
# drop the old whole gop.
# default: 30
queue_length 10;
}
当然这个不能配置太小,譬如GOP是1秒,queue_length是1秒,这样会导致有1秒数据就清空,会导致跳跃。
有更好的方法?有的。延迟基本上就等于客户端的缓冲区长度,因为延迟大多由于网络带宽低,服务器缓存后一起发给客户端,现象就是客户端的缓冲区变大了,譬如NetStream.BufferLength=5秒,那么说明缓冲区中至少有5秒数据。
处理累积延迟的最好方法,是客户端检测到缓冲区有很多数据了,如果可以的话,就重连服务器。当然如果网络一直不好,那就没有办法了。
考虑GOP-Cache和累积延迟,推荐的低延时配置如下(参考min.delay.com):
# the listen ports, split by space.
listen 1935;
vhost __defaultVhost__ {
# whether cache the last gop.
# if on, cache the last gop and dispatch to client,
# to enable fast startup for client, client play immediately.
# if off, send the latest media data to client,
# client need to wait for the next Iframe to decode and show the video.
# set to off if requires min delay;
# set to on if requires client fast startup.
# default: on
gop_cache off;
# the max live queue length in seconds.
# if the messages in the queue exceed the max length,
# drop the old whole gop.
# default: 30
queue_length 10;
}
当然,服务器的性能也要考虑,不可以让一个SRS进程跑太高带宽,一般CPU在80%以下不会影响延迟,连接数参考性能。
SRS: 0.9.55
编码器:FMLE, video(h264, profile=baseline, level=3.1, keyframe-frequency=5seconds), fps=15, input=640x480, output(500kbps, 640x480), 无音频输出(FMLE的音频切片HLS有问题)
网络:推流为PC在北京公司内网,观看为PC北京公司内网,服务器为阿里云青岛节点。
服务器配置:
listen 1935;
vhost __defaultVhost__ {
enabled on;
gop_cache off;
hls {
enabled on;
hls_path ./objs/nginx/html;
hls_fragment 5;
hls_window 20;
}
}
结论:RTMP延迟2秒,HLS延迟24秒。
参考:
SRS集群不会增加延迟。这个是Edge模式比ingest要高级的地方,ingest需要启动进程,延迟会大。ingest主要适配多种协议,也可以主动从源站采集流,但Edge是专业的边缘模式。
参考:
Winlin 2014.2
原文:https://www.cnblogs.com/dongguolei/p/12821499.html