国内应用比较多的开源流媒体服务器nginx-rtmp-module一直存在功能少、集群化难度大等问题。在LiveVideoStack线上分享中,PingOS 开源项目组开发工程师、UCloud RTC研发工程师朱建平详细介绍了基于nginx-rtmp-module的PingOS流媒体服务器在http-flv、http-ts、hls+、多进程、转推、回源以及集群化部署方面的技术实现细节。
文 / 朱建平
整理 / LiveVideoStack
直播回放https://www2.tutormeetplus.com/v2/render/playback?mode=playback&token=006643cdea15499d96f19ab676924e88
1. Nginx流媒体扩展:http-flv、http-ts、hls+
最初始的nginx-rtmp-module相关模型与包括SRS在内的多数流媒体服务器实际上是一样的(1个生产者,n个消费者)。Nginx存一个问题:它仅仅做了RTMP的消费模型,如果想扩展 http-flv或http-ts的形式会较为困难。由于rtmp-session仅供RTMP协议使用,如果想扩展http-flv,首先我们需要了解其基础分发模型(如上图所示):所有的生产者与消费者都会被挂载到同一个stream中,生产者负责从网络端接收数据,消费者从buffer中获取数据对外发送。
如果是发送flv数据,那么可以保留原有rtmp-session,当服务器收到一个HTTP请求时,创建一个rtmp-session,此session与网络不相关,仅仅是逻辑上的session。然后将这个session注入stream当中,如果是以消费者的角色注入进stream当中,则可以实现获取数据并往外分发。假如此时服务器收到的是http-flv的请求,就可以创建一个逻辑上的session,并把它注入stream中,此时理论上我们可以获得的是rtmp的数据。但我们需要的是flv的数据,由于flv数据与rtmp数据相似,我们可以通过tag-header的方式非常简单的将rtmp数据还原成flv数据。根据上述思路,在生产者和消费者模型中,消费者可以通过创建http-fake-session的形式来复用以前的分发流程并实现http-flv协议。我们对其进行扩展,创建一个http-fake-session作为生产者,并让http-fake-session与一个http client进行关联,关联之后http client负责从远程服务器端下载数据传递给生产者,生产者就可以把这些数据通过分发模型分发给下面的rtmp-session。这样也就间接实现了一个http回源的功能。通过上述思路我们就能够快速地实现http-flv的播放与拉流。同样,我们可以根据上述思路继续扩展协议。假如我们在收到一个http请求之后,创建一个同样的rtmp-fake-session(逻辑上的session,与网络不相关),我们把它以消费者的角色插入到 stream当中。这样就可以从stream当中获取到需要向下分发的数据。需要注意的是:stream中最初保存的是rtmp数据而不是ts数据,无法直接获取ts数据。
1.1 http-flv在Nginx中的实现
基于Nginx实现http-flv需要注意以下几点细节:首先该实现复用了Nginx的分发模型以及http功能模块。(Nginx对http协议栈的支持更加完善,包括http1.0、http1.1协议&