欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  运维

如何理解基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module

程序员文章站 2022-04-26 16:29:46
...
本篇文章给大家带来的内容是关于如何理解基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

目前已经有很多个人和厂商准备将本模块商用,据网友反馈,国外已经有直播网站在用这个模块。准备商用的厂商中最著名的是华为,网友和厂商陆续反馈过不少bug,修复后功能已经越来越稳定,在此表示感谢。

2018-06-04:一家CDN厂商正式上线nginx-http-flv-module,使用RTMP方式,开gop_cache配置(关闭interleave配置,打开会卡顿或者没有声音,目前暂时不知如何修复),他们的客户包括映客和微吼。

2018-06-28:一家网络视频厂商正式上线nginx-http-flv-module,使用HTTP-FLV方式,不开gop_cache配置,目前还没开全量,等待观察稳定性。

2018-07-28:应一部分网友的需求,已经提供RHEL6(CentOS 6)和RHEL7(CentOS 7)的rpm安装包,见nginx-http-flv-module-packages。

nginx-http-flv-module与nginx-rtmp-module的功能对比:

功能 nginx-http-flv-module nginx-rtmp-module 备注
HTTP-FLV × nginx-http-flv-module支持HTTPS-FLV
GOP缓存 ×
vhost ×
省略listen配置 x

JSON风格的stat x
RTMP 302 Beta × nginx-http-flv-module作为服务器或者客户端

2018-03-09更新:

最近这段时间主要在不同平台测试模块的稳定性,目前播放这一块没发现问题,由于条件限制,除了FreeBSD平台没测试过,Windows 7,Debian 7.x和macOS Sierra都测试过了,由于Nginx官方对Windows支持不太好,没用Windows平台最强大的IOCP接口(使用的select),所以导致Windows平台上运行效率不太高,表现在推流等待时间长,3s+,首屏时间很长,4s+,select本身原因限制客户端个数,默认是1024。推流等待时间和首屏时间最短的是macOS Sierra,本机上测试时基本上是秒推秒开。昨晚专门注意了一下,在macOS Sierra下编译时,SO_REUSEPORT和TCP_FASTOPEN两项都支持,前者让Nginx的每个子进程都可以listen,都有一个专门的accept队列,解决了惊群效应;后者则是在发起SYN时就已经携带实际数据,而不是握手完毕后再传输实际数据。秒推秒开可能跟这两个选项有关。但是macOS Sierra并不支持将某个进程绑定到某个CPU上,所以可能进程上下文切换会有开销,系统负载较大时可能效率不如Linux。由于macOS Sierra是公司的电脑,所以未做压力测试。我的笔记本装的是Debian 7.x,因为内核版本较低,所以macOS Sierra上支持的两个选项都不支持。测试时推流等待时间和首屏时间都介于Windows 7和macOS Sierra之间,在服务器上测试时(系统CentOS 6.4,支持SO_REUSEPORT但是不支持TCP_FASTOPEN)跟macOS Sierra上差不多,但是考虑到服务器的CPU性能强大得多,所以负载不高情况下,macOS Sierra的表现是最好的。由于macOS Sierra是从Mac OS X更新来的,而Mac OS X的底层最初是在FreeBSD基础上开发的,所以推测在FreeBSD上的表现应该也不错。

另外最近在尝试添加RTMP 302重定向转HTTP 302重定向的功能,由于很多播放器不支持RTMP 302重定向,但是支持HTTP 302重定向的功能基本上是标配,实测VLC是支持的。目前功能基本上已经完成,但是困扰的地方还是使用HTTP框架的发送接口时,链表在长时间播放后会形成环,所以进展不下去了,没有更新到github上。下面是nginx的rtmp主要配置片段和VLC播放时的HTTP 302重定向截图:其中推流是在名为hls的application上推的(FFmpeg也不支持RTMP 302重定向,所以只能往hls推)。

application myapp {

rewrite '^/myapp/(.*)' '/hsl/$1';

}

1.HTTP 302重定向抓包简略图

如何理解基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module

2.HTTP 302重定向抓包详情图

如何理解基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module

2018-03-15更新:

有网友反馈on_play指令不能使用,经调试,是因为加入的ngx_http_flv_live模块的顺序有问题,现修改为不改变模块顺序的前提下,经过一些状态的修改绕过它,后续再调用其中的一些函数,以保证与原来的nginx-rtmp-module的功能一致。

2018-03-16更新:

部分网友们提出的CORS(跨域)功能已经可用,HTTP-FLV的回复数据不再使用硬编码,而是使用部分HTTP框架的代码重写了。另外,on_connect功能有问题,暂时不能用,等待修复。

2018-03-18更新:

on_connect的问题已经修复。

2018-03-20更新:

修复因为要查找的application不在第一个server块中造成找不到对应的on_connect和on_play的bug,经查是由于没有匹配到正确的server配置,已修复。

2018-03-22更新:

很久之前有网友提出过设置idle_streams为off(默认为on)时,使用HTTP-FLV方式播pull会失败,现已修复。

2018-03-25更新:

有网友使用flv.js播放nginx-http-flv-module拉的直播流,发现一个bug:当(1)使用的Nginx版本号为1.13.9,(2)播放器为flv.js,(3)播放pull的流时,会出现无法播放的情况,经查是因为flv.js发送了HTTP头“Connection: keep-alive”,nginx-http-flv-module在向上游发起请求时,下游请求一般在上游请求还没有返回时就已经返回,但是Nginx从版本1.13.1起,删除了一个r->blocked判断,而“Connection: keep-alive”导致ngx_http_finalize_request调用ngx_http_set_keepalive,这个函数会调用注册的cleanup函数来关闭下游的请求,导致播放失败。已经修复。也正是在调试这个bug的过程中,发现nginx-http-flv-module在打开gop_cache配置项的情况下,flv.js跟其他主流的播放器(如vlc)相比,首屏时间是最快的,几乎没有延迟,使用的pull源是香港卫视的直播源:rtmp://live.hkstv.hk.lxdns.com/live/hks

2018-03-27更新:

顺手改点代码就有bug,真是恼火。最近为了响应一些网友要求添加定制的HTTP头的功能,修改了发送功能,再次尝试将Nginx的HTTP框架的filter接口引入,还是失败了,所以简单粗暴地把最后一个filter模块和header_filter模块挑出来,删除了很多用不上的代码。github上编译用的是Nginx官方的稳定版本nginx-1.12.2。结果今天有网友反馈编译不过去,经查刚好这几个找不到的宏是在我从修改nginx-rtmp-module就一直使用的nginx-1.11.10中加入的,而网友用的版本低一些就编译不过去,已经修复。

2018-03-29更新:

前几天有网友反馈使用nginx-1.13.1以及以上的版本与nginx-http-flv-module一起编译时,使用flv.js播放pull流会失败,见2018-03-25更新,结果修复了那个问题,又出了先推流,然后使用flv.js播放会失败的问题,真是随手改出bug,问题已经修复,最新版本的Nginx和稍微旧一些的版本(nginx-1.11.10)都已经测试通过。

2018-04-05记录:

这次不是更新:)昨天有网友反馈使用flv.js播放推流时,一直播放不了,我还以为nginx-http-flv-module又出问题了,自己测试了一下,用最新的nginx-1.13.10一起编译,播放推流和拉流都没问题,又用官方的稳定版nginx-1.12.2一起编译,还是没问题,晚上准备看看哪儿出问题的时候,网友反馈是浏览器限制了flv.js的数量,他用的是Chrome,据测试单浏览器只能开6个flv.js,今天中午我用Firefox测试了一下,也是同样的问题,第7个flv.js播放不了,然后开VLC播放,没有问题,由此可以确认不是nginx-http-flv-module的问题。不过这是个很重要的信息,浏览器对flv.js的播放支持是有数量限制的,Chrome和Firefox的限制数量都是6个,其他浏览器未测试。

2018-04-06更新:

之前的统计数据一直没有把http-flv直播的accepted数量和输出计入,现已添加。现在对flv.js的支持已经稳定,下面是使用flv.js播放的截图:

如何理解基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module

一个商用厂商反馈视频源是纯视频时,不管使用什么播放器,播放连接没问题,但是一直接收不到视频数据,经调试发现是因为判断纯音频的逻辑有bug,导致nginx-http-flv-module在发送音视频数据的接口中无限循环了,现已修复。

2018-04-14更新:

有网友昨天反馈开启gop_cache选项时,推流会导致内存泄露,已查明是推流关闭时没有释放gop cache模块分配的内存造成的,已修复。另外,据网友反馈,多进程模式下,on_connect和on_play指令有问题,暂时别在多进程模式下用这两个指令,等待修复。

2018-04-15更新:

一个商用厂商反馈随机闪断测试时,内存会不断增长,怀疑有内存泄露,晚上调试时确认确实有内存泄露,是由于没有释放ngx_http_request_t结构中的内存池造成的,已修复。

2018-04-21更新:

有网友反馈多进程模式下,使用on_play进行鉴权操作,但是在推流的时候,本地relay(接受推流的子进程将流推给别的子进程)也会执行on_play鉴权,这是不太合理的(但是其实并不算bug),因为之前已经进行过鉴权了。现在将本地relay的on_play操作去掉了,nginx-http-flv-module并不关心on_play用来做什么,但是考虑到本地relay不应该再执行on_play操作了,修改的代码也比较简单,恢复也很容易,所以先暂时这样修改。另外网友@qqzzzx 反馈的压测崩溃的问题已经修复一部分,现在还存在的问题是压测群断后会有内存泄露的问题,修复后会更新到github上。

2018-04-25更新:

压力测试崩溃的问题已经修复,捎带解决了可能出现的CPU使用率过高的问题,已压力测试1个多小时(srs-bench自带的测试视频,500路HTTP-FLV和200路RTMP),暂未发现问题,欢迎反馈bug。

2018-05-12更新:

有网友反馈开启gop_cache选项,某些情况下压力测试会特别耗费内存,不确定是不是有内存泄露。压测多次不能复现,网友提示压测工具和服务器不在同一主机上比较容易复现。按照这种方式压测果然比较容易复现,但是出现耗费内存比较大的情况下,停止压力测试,然后再次压力测试且并发数不变,内存不会增长,证明不是内存泄露的问题。后来反复查看源代码后,猜想是因为发送GOP的时候,一次性将GOP数据放入发送环形数组中,由于Nginx是异步非阻塞的,所以Nginx不一定会马上将数据从环形数组中真正发送到网络(如服务器和客户端之间的网络带宽不足的情况下),造成已分配的内存不能马上循环使用,而且真正发送完GOP后,已分配的内存不再释放(在内存池中,并且与连接无关,只跟配置结构体有关)。后续的数据传输不像GOP数据是一次性全部发送,所以导致回收的内存不能被充分使用,有很大一部分闲置了。现将gop cache模块修改为使用自己独立的内存池,等GOP发送完后,释放这个内存池。

2018-05-14更新:

修复了一个2018-05-12更新引入的内存泄露的bug,属于代码久了看不懂,然后一改就出问题的情况如何理解基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module。修复高版本gcc编译工程失败(在网上查了一下,gcc-7.x.x在添加了某些编译选项时,会检查switch的case是否有fall through)的bug,不过我手头没有很高版本的gcc,所以可能还存在一些没被发现的编译错误,目前正等待网友的回复。

2018-05-16更新:

白天编译安装了gcc-7.2.0,找出了所有的fall through编译警告(Nginx的编译选项中被视为错误),已修复bug。

2018-05-18记录:

这次不是更新,2018-05-12更新中我猜想压力测试(使用的工具是srs-bench)时开启gop_cache选项会特别耗费内存的原因,今晚经过查看日志,发现之前的猜想其实不是主要原因。从日志中可以看到Nginx在接收数据时一直都是128字节,而在配置中如果没有指明chunk_size配置项时,默认是4096个字节,就是说服务器发送Set Chunk Size协议控制消息后,客户端并没有响应Set Chunk Size协议控制消息,所以服务器一直沿用之前的128字节,最糟糕的情况下,会导致nginx-http-flv-module在接收到数据后,分配内存对数据进行打包时,用(4096+RTMP头最大大小)这么多字节的空间来打包128字节的数据,白白浪费了32倍多的数据。使用ffmpeg进行对比测试,ffmpeg是会响应Set Chunk Size协议控制消息的,所以不会造成内存浪费。已经给SRS(Simple-RTMP-Server)的作者提issue了。后续有空我会更新nginx-http-flv-module对这种异常的处理。

2018-05-20更新:

某些情况下特别耗费内存的问题已经修复,如果耗费使用量还很大,那么可能是由上面说的那个次要原因引起的了。

2018-06-14更新:

修复一个网友反馈的问题,ngx_stat_active参数在运行一段时间后值不正确,经查是由于重复减去操作造成的,已修复,不影响正常功能使用。

2018-06-19更新:

同步了几个nginx-rtmp-module的pull requests里的bug修复,基本上都是一些很明显的bug,大的修改没同步过来。另外,目前在nginx-http-flv-module基础上添加了直接推送fmp4的功能,今晚已经实现直接推送纯视频的fmp4到支持MSE(Media Source Extensions,目前iOS上的Safari不支持)的浏览器中播放,后续会将音频一起加上。

2018-06-25更新:

推送fmp4的基本功能已经基本完成。有网友推了支持JSON格式的stat的PR,已经合并,试用了下,感觉非常不错,另外修复了一个小bug。

2018-06-29更新:

将stat中原有的rtmp信息修改为http-flv,鉴于已经有两个厂商分别正式商用RTMP(开启gop_cache)和HTTP-FLV(不开gop_cache),发布了里程碑版本1.2.4。

2018-07-09更新:

修复了3个小bug:开启DASH功能时,有可能因为从文件中读取的数据为0导致无限循环;修复xml方式的stat中不能显示nginx-http-flv-module的版本号的问题(网友的PR);修复HEAD请求没有配置flv_live的locations时返回405(Method Not Allowed)的bug

以上就是如何理解基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module的详细内容,更多请关注其它相关文章!