流服务器srs初探

Posted by BY Blog on December 2, 2019

流服务器SRS初探

首先介绍SRS是什么,SRS(Simple-RTMP-Server)是一个简单的流媒体直播集群,简单的快乐。它的GITHUB地址为:https://github.com/ossrs/srs

而更详细一点的描述是:

SRS定位是运营级的互联网直播服务器集群,追求更好的概念完整性和最简单实现的代码。SRS提供了丰富的接入方案将RTMP流接入SRS,包括推送RTMP到SRS推送RTSP/UDP/FLV到SRS拉取流到SRS。SRS还支持将接入的RTMP流进行各种变换,譬如将RTMP流转码流截图转发给其他服务器转封装成HTTP-FLV流转封装成HLS转封装成HDS录制成FLV。SRS包含支大规模集群如CDN业务的关键特性,譬如RTMP多级集群源站集群VHOST虚拟服务器无中断服务ReloadHTTP-FLV集群。此外,SRS还提供丰富的应用接口,包括HTTP回调安全策略SecurityHTTP API接口RTMP测速。SRS在源站和CDN集群中都得到了广泛的应用Applications

SRS安装与配置

SRS目前只支持Linux系统,如果你不想自己重新编译的话,可以选择编译好的版本。SRS发布版本提供安装包下载,请访问ossrs.net

在这里则选择下载源码重新编译。

第一步,获取SRS。详细参考GIT获取代码

git clone https://github.com/ossrs/srs
cd srs/trunk

或者使用git更新已有代码:

git pull

第二步,编译SRS。详细参考Build

./configure && make

第三步,编写SRS配置文件。

将以下内容保存为文件,譬如conf/realtime.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/realtime.conf
listen              1935;
max_connections     1000;
vhost __defaultVhost__ {
    tcp_nodelay     on
    min_latency     on;

    play {
        gop_cache       off;
        queue_length    10;
        mw_latency      100;
    }

    publish {
        mr off;
    }
}

第四步,启动SRS。详细参考LowLatency

./objs/srs -c conf/realtime.conf

在上述的配置文件中,主要实现两个功能,一个为打开服务器,另一个配置了低延迟服务,能够满足一般简单的低延迟需求,配置SRS为Realtime模式,使用RTMP可以将延迟降低到0.8-3秒,可以应用到对实时性要求不苛刻的地方,譬如视频会议(其实视频会议,以及人类在开会的时候,正常时候是会有人讲,有人在听在想,然后换别人讲,其实1秒左右延迟没有问题的,除非要吵架,就需要0.3秒左右的延迟)。

下面就是官方给出低延迟配置的原理。

GOP-Cache

什么是GOP?就是视频流中两个I帧的时间距离,如果问什么是I帧就去百度。

GOP有什么影响?Flash(解码器)只有拿到GOP才能开始解码播放。也就是说,服务器一般先给一个I帧给Flash。可惜问题来了,假设GOP是10秒,也就是每隔10秒才有关键帧,如果用户在第5秒时开始播放,会怎么样?

第一种方案:等待下一个I帧,也就是说,再等5秒才开始给客户端数据。这样延迟就很低了,总是实时的流。问题是:等待的这5秒,会黑屏,现象就是播放器卡在那里,什么也没有,有些用户可能以为死掉了,就会刷新页面。总之,某些客户会认为等待关键帧是个不可饶恕的错误,延时有什么关系?我就希望能快速启动和播放视频,最好打开就能放!

第二种方案:马上开始放,放什么呢?你肯定知道了,放前一个I帧。也就是说,服务器需要总是cache一个gop,这样客户端上来就从前一个I帧开始播放,就可以快速启动了。问题是:延迟自然就大了。

有没有好的方案?有!至少有两种:

  • 编码器调低GOP,譬如0.5秒一个GOP,这样延迟也很低,也不用等待。坏处是编码器压缩率会降低,图像质量没有那么好。
  • 服务器提供配置,可以选择前面两个方案之一:SRS就这么做,有个gop_cache配置项,on就会马上播放,off就低延迟。
# the listen ports, split by space.
listen              1935;
vhost __defaultVhost__ {
    # for play client, both RTMP and other stream clients,
    # for instance, the HTTP FLV stream clients.
    play {
        # whether cache the last gop.
        # if on, cache the last gop and dispatch to client,
        #   to enabled 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;
    }
}

备注:参考conf/full.conf的min.delay.com配置。

累积延迟

除了GOP-Cache,还有一个有关系,就是累积延迟。SRS可以配置直播队列的长度,服务器会将数据放在直播队列中,如果超过这个长度就清空到最后一个I帧:

    # 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__ {
    tcp_nodelay     on
    min_latency     on;

    play {
        gop_cache       off;
        queue_length    10;
        mw_latency      100;
    }

    publish {
        mr off;
    }
}

当然,服务器的性能也要考虑,不可以让一个SRS进程跑太高带宽,一般CPU在80%以下不会影响延迟,连接数参考性能

由于目前只需要用到这两个功能,其它东西就先Mark下,有需要再看。

Deployment Guides:

Cluster Guides:

  • RTMP Cluster: 如何部署RTMP分发集群,譬如CDN支持RTMP分发。
  • 源站集群: 如何支持源站集群,扩展源站能力。
  • FLV Cluster: 如何部署HTTP-FLV分发集群,譬如CDN支持HTTP-FLV分发。
  • VHOST: 如何一个集群支持多个用户,即Vhost。
  • Reload: 如何不中断服务的前提下应用新的配置,即Reload。
  • Tracable Log: 如何在集群中追溯错误和日志,基于连接的日志,排错日志。
  • Log Rotate: 如何切割服务器的日志,然后压缩或者清理。

Integration Guides: