开始研读SRS项目源码,自然就是先从wiki和架构开始。wiki的第一部分是其支持的一些协议,以及协议的核心配置项。在项目实战的时候应该针对具体的业务场景,针对专门的业务需求进行配置层面,甚至源码层面的优化。

第二部分是核心功能,也就是本篇文章想要聊的部分。这个部分会随着源码的阅读不断进行更新-纠错等。

设计思想

源服务器-边缘服务器-客户端

在这种架构分解中,边缘本身并不会维护流的状态,只负责转发数据,而真正的状态都由源站维护。同时边缘又支持向下级联扩展在任意的Origin或edge拉流或推流,有以下几条规则:

  • 边缘服务器,就是边缘直播缓存服务器,边缘edge服务器就是源站的缓存。
  • 播放边缘上的流时,edge会回源拉流,推流到edge上时,edge会直接将流转发给源站。
  • 配置多个源站,在故障时会切换到下一个源站。

并且edge在拉流的时候origin集群会通过轮询加通知的方法提高效率,以及edge的高负载实现分发功能

另外SRS中引入Vhost机制,我的理解它类似于虚拟机,是一个较为独立的系统。能够实现配置隔离,多租户,按需应用不同的功能,

基于协程单线程架构

与之前聊过的回调地狱以及多线程巨大开销不同,基于state-thread协程库的开发,能够使编码方式更像同步。同时阅读代码的难度也是真的降低了很多(相比于恶心的回调函数方式).

层级结构

  • 接入层:负责处理底层的IO请求,协议解析等。
  • 核心逻辑层:
    • srscource:将推送到服务器的音视频流抽象成一个对象。负责缓存最近的GOP、管理消费者、并且实现数据的分发,
    • srsconsumer:每个客户端都对应一个实例,从Srssource中拉去音视频数据,并根据客户端协议进行打包发送。
    • 功能模块:诸如录制,转码、HLS切片等操作。
  • 扩展层:
    • HTTP-API: 提供了一套完整的RESTful API,用于外部系统查询服务器状态、管理流、配置热更新等。

    • HTTP-Callback (Webhook):这是SRS扩展性的关键。在, , 等关键业务节点,SRS会主动向您配置的业务服务器发送HTTP请求,从而可以轻松实现推流鉴权、流量统计、与业务系统深度集成等定制化需求。on_publishon_playon_done

    • Prometheus Exporter: 内置了对Prometheus监控的支持,可以方便地将SRS纳入云原生的可观测性(Observability)体系。

核心功能

HTTP服务器

SRS主服务框架是一个基于协程的,事件驱动的网络服务器框架。其内嵌了HTTP服务器,完成诸多功能:

  • 流媒体分发(接入层):例如hlv hls DASH的分发,都是通过HTTP的API实现的。
  • 管理与控制(扩展层):例如HTTP RESTful API,可以通过简单的HTTP GET\POST请求来查询所有流、所有客户端的状态,并且能够实现控制客户端,控制DVR,动态热加载等等功能。
  • HTTP callback: 可以利用这个API实现回调功能,实现流媒体核心与复杂的业务逻辑之间的解耦。例如SRS接收到on_play命令时会回调立刻HTTP的API,同理接收到on_stop的时候也会回调api实现业务上的计时收费等功能。

DVR(digital video recording)

我认为在具体聊这个功能之前首先要明白设定这个功能的意义,为什么需要服务器来实现一个录制功能呢?

  1. 应用场景:直播领域。一方面是为了对即时性的直播的保存,通过录制直播将其转化为长久的点播内容。另一方面是为了满足监管机构对于直播内容需要存档的要求。
  2. 为什么要在服务器端完成这件事?第一自然是效率问题,作为服务器,流本身就会在其内部进行流转,过程中将其写入本地文件自然不难。第二可以降低客户端对于带宽,设备等的要求,简化了推流端的流程与配置。
  • DVR的工作流程
    当一个流推送到SRS时,SRS会在核心SrsSource结构体上挂载一个额特殊的消费者,即DVR,这个消费者将接收到的流数据写入到文件中,实现录制效果。

Stream Converter(Ingest)

  1. 应用场景
  • 用于主动去拉取那些不支持向SRS主动推流的外部源,然后将这些拉取到的流注入(Ingest)到SRS内部。例如安防领域,摄像头(IP camera)通常是不支持主动推流的,于是便可以在SRS中配置一个ingest项,启动ffmpeg,并主动像一个IP进行拉流,并以RTMP协议推送到SRS自己的RTMP端口上。
  • 实时转码:通过Ingest使用ffmpeg独立进程完成协议的转换编解码,能够实现解耦,以及实时性的要求。毕竟SRS的核心在于分发,而不是编解码,将这一功能外包给独立的ffmpeg进程,能够保证SRS核心的轻量化。
  1. 工作流程
    这就与FFmpeg紧密相关了,这里不再赘述了

Forward For Small Cluster

这是一个服务器端的,主动的,流复制和推送功能。当一台SRS服务器(我们称之为“主服务器”)接收到一路直播推流后,如果配置了Forward功能,这台主服务器会立即、主动地将这路流原封不动地转发到一台或多台其他的服务器上。通过这样的做法一是实现服务器的备份。实现当主服务器产生故障时,能够热切换到备用服务器上。二是实现跨地区的分发,例如亚洲和北美的两台主服务器。三是能够对转发的这一路流做更多处理而不影响到主服务器的流。

但是主服务器每增加一个Forward目标,就需要消耗一份额外的CPU和上行带宽来推送这份流的拷贝。如果有1路流,要转发给10台服务器,主服务器就需要承担1路推流进入和10路推流出去的网络负载。当目标服务器数量很多时(例如几十上百台),主服务器的带宽和CPU会迅速成为瓶颈,整个集群的扩展性会很差。

基本的客户端安全配置

例如踢掉连接用户等。

截图

有多个API可以调用,例如HTTP(提供回调,最终是使用ffmpeg进程来截图),Transcoder


本站由 Edison.Chen 创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

undefined