多协议、性能稳定、丰富API的流媒体服务器软件
关于直播流录制API几个细节参数的解释
Wowza Streaming Engine支持用API去控制对直播流的录制,例如启动录制和停止录制以及分段录制等。

这些API包括两类:

1. Java API : 这类API允许你用Java 代码去实现录制的逻辑控制,并将编译好的Jar文件放在Wowza安装目录的/lib下,然后添加Module或ServerListener或者Http Provider。Wowza Streaming Engine重启后就可以生效。关于这些自定义功能的开发请 参考     http://www.ttstream.com/wowza/administrate/howToExtendWowzaUsingWowzaIde

2. Http REST API : 这类API允许你用http请求去控制录制的启动、停止、分段等。显而易见,这种方式下你可以用任何开发语言(PHP、ASP、Java、C#、NodeJs等)开发您的Http 客户端。

需要说明的是,这两种API可以实现的功能是类似的,只是适用于不同的业务流程,Java API一般适合于直播流进入Wowza后自动进行相关录制动作的业务流程;而Http REST API更适合随时、随地的远程控制。

此外,最重要的是,这两种API都提供统一的的录制参数,这个很容易理解,比如录制为MP4还是FLV?录制文件所在路径和文件名是什么?是否分段录制(5分钟一个,还是50Mbytes一个?)等等,诸如此类。

这些录制参数将会影响Wowza的录制行为,有些参数,你根据参数名就知道它的作用,但是有些参数不太好理解。这篇文章就重点介绍几个细节的录制参数,有助于您排查录制中遇到的问题。

一、startOnKeyFrame

通常,录制为MP4或FLV文件时,既包括音频,也包括视频。对于视频的录制,是否要从一个关键帧开始呢?通常是这样的,但Wowza Streaming Engine依然提供了这个参数,让你可以控制这个逻辑。 startOnKeyFrame 为true时,录制的视频从关键帧开始; startOnKeyFrame 为false时,录制的视频不需要从关键帧开始。当然了,它的默认值是true。

所以,通常情况,您可以忽略这个参数,也就是说让Wowza使用默认值true,从关键帧开始录制。



二、backBufferTime

从字面意思也比较容易猜测它的含义,显然任何一个类似于Wowza Streaming Engine的流媒体Server,针对每一路注入的直播流,在server内部肯定是有一个"最新"音视频数据的缓存队列。 有的Server说为了低延时,没有一点缓存(余粮),那几乎是不可能的,没有缓存,肯定会出现播放卡顿的情况。那么Wowza Streaming Engine内部的这个缓存队列有多长呢?大概8秒左右(它不可能是个绝对精确的值 因为队列都是由各个数据包组成的,怎么可能这些数据包刚好是8秒呢?)。 但是您要注意,缓存队列有多长,并不意味着直播延时就有这么多。因为将数据缓存起来不仅仅是为了让播放更流畅, 还有其它可能的作用,比如说录制,好,终于回到正题上了。

backBufferTime的意思就是说当Wowza Streaming Engine收到录制请求后,是从已有的缓存队列里面某一个位置开始寻找音视频数据去开始录制,还是说压根就不管现有的缓存队列,而是去等待新的音视频数据到达后再开始录制。

backBufferTime的单位是毫秒,默认是0。比如4000就是从队列最新的位置向后回退4秒,从这个位置开始向前(有最新数据的方向)寻找音视频数据,找到后再开始录制。 如果backBufferTime是0,就是上面说的,压根就不管现有的缓存队列,要等待新的音视频数据到达后开始录制,注意:这是默认策略。

针对这个参数,我的建议是你要根据您的具体应用场景设置适当的值,比如你的场景是作为监控方/管理方看着直播,觉得需要录制时通过控制台发起一个http REST请求去录制。那么一般就要给这个backBufferTime设置几秒钟时间。 因为你看的这一帧画面肯定是落后于最新的直播点的,如果你要从这个点开始录制,就应该让录制起始点往后挪一挪了。

总之,这个参数是挺有用的,你要根据具体场景设置一个合适的值。



三、defaultAudioSearchPostion

注意:这个参数只针对录制MP4文件时有效!并不适用于FLV文件的录制。


这个参数的含义不太好理解,但也是挺重要的。它是一个Boolean类型的值,true或false。 默认是true。

true的意思是说,在Wowza Streaming Engine 要寻找“可以录制(写入文件)的音视频数据”时,如果遇到第一个视频关键帧,就开始录制。此时,不用考虑有没有遇到音频数据。

false的意思是说,在Wowza Streaming Engine 要寻找“可以录制(写入文件)的音视频数据”时,如果遇到第一个视频关键帧,还不能马上开始录制,还要看看有没有音频数据,如果还没有 音频数据,就把这个视频关键帧跳过去(丢弃掉),继续寻找下一个视频关键帧(这个地方,我理解有一个前提就是startOnKeyFrame为true),如果找到了下一个视频关键帧了,但是还是没有音频数据,就继续跳过这个视频关键帧。 直到有了音频数据。但是,这里就有个疑问,如果一直没遇到音频数据呢?难道一直等下去?请继续看下面的参数。



四、skipKeyFrameUntilAudioTimeout

注意:这个参数只针对录制MP4文件时有效!并不适用于FLV文件的录制。


如果理解了前面的defaultAudioSearchPostion,那么skipKeyFrameUntilAudioTimeout就很容易理解了。

skipKeyFrameUntilAudioTimeout是一个毫秒数,默认值是10000,也就是10秒钟。只有当defaultAudioSearchPostion为false时,它才有意义。 也就是说,它是等待音频数据的最大时间,只要到了这个时间就不再往下继续等了。即使没有音频,只要有了视频关键帧就开始录制。 你也可以说不想等待音频数据,就把这个参数设置为0。但这没有意义,你直接把defaultAudioSearchPostion设置为true就行了。



以上几个参数都可以在Wowza Streaming Engine的API文档中找到说明,除此之外,还有另外几个参数并没有出现在API文档中,下面也说一下:



1. 自定义参数liveStreamRecordMinimumKeyFramesInPacketList

这个参数是数值类型(Integer),默认值是2。 它同时适用于录制MP4和FLV文件。

它的作用很类似参数defaultAudioSearchPostion,也就是在Wowza Streaming Engine 要寻找“可以录制(写入文件)的音视频数据”时,遇到几个视频关键帧 后才开始录制。据Wowza技术支持工程师介绍好像是有些编码器在发送音频包前集中发了一些过多的视频包,Wowza就尝试在内部多检测几个视频关键帧后再开始录制。

你可以试试将这个参数设置为0或1,看看有什么变化:

编辑您的Application.xml文件,在文件的最后部分的中添加下面的配置:
<Property>
  <Name>liveStreamRecordMinimumKeyFramesInPacketList</Name>
  <Value>0</Value>
  <Type>Integer</Type>
</Property>
		


2. 自定义参数liveStreamRecorderWaitForVideoFrameCount

这个参数是数值类型(Integer),默认值是20。 它同时适用于录制MP4和FLV文件。

它的作用很类似参数skipKeyFrameUntilAudioTimeout,在Wowza Streaming Engine 要寻找“可以录制(写入文件)的音视频数据”时,如果遇到20个音频包,但还没有遇到一个视频帧,就不再等视频帧了,直接开始录制。

你可以试试调整参数,看看有什么变化:

编辑您的Application.xml文件,在文件的最后部分的中添加下面的配置:
<Property>
  <Name>liveStreamRecorderWaitForVideoFrameCount</Name>
  <Value>20</Value>
  <Type>Integer</Type>
</Property>
		


好,至此,关于Wowza Streaming Engine中录制的几个细节参数就说清楚了。我们结合一个案例来看看有什么问题。




XXX客户的直播流是rtmp push 进入Wowza Streaming Engine的,在确认流已经注入成功后,客户用Http REST API 去启动录制。要求录制的文件格式是flv。 比如这是一堂在线教育的课程,可能要录制30分钟到1个小时。

录制完成后,客户将flv文件下载下来,再用ffmpeg转换为mp4后提供给老师,用于事后本地观看(当然Wowza也支持录制为mp4,只是在这个案例中客户将它录制为flv了)。 例如用Windows Media player播放视频文件,但发现音视频不同步,声音落后于画面的播放进度(大概迟了1秒)。 同时,发现用VLC本地播放或者用H5网络播放(HLS)并没有音视频不同步的现象。

然后客户用flvAnalyser软件对这个flv做了分析,如下图所示:

flv

根据这个软件的分析,在flv的script信息之后紧跟着视频(H.264)的AVC Sequence Header,里面包含SPS和PPS信息,而在1秒多以后才有了第一个视频关键帧。

另外,据客户介绍,这个情况只是偶尔发生,特别是针对GOP比较大的情况下(比如GOP大于8秒)。而且只要这个视频关键帧滞后了,在Windows Media player下一定会出现音视频不同步的情况。

当然,你可以说这可能是Windows Media Player的兼容性问题,因为毕竟VLC、QQ影音、H5网络播放都是正常的。
但是,客户还是希望能让Wowza Streaming Engine在录制时避免这个问题。

根据前面的录制参数,我们大体清楚了Wowza Streaming Engine在开始录制时的几种可能的策略,再结合这个案例的情况,应该可以推测出来Wowza Streaming Engine在开始录制时确实等了至少1秒后才 检测到了视频关键帧。那么解决的方法/思路大致如下:

1. 让编码端(比如主播端)采用更小的GOP,比如2秒。这样检测到(遇到)关键帧的速度会更快。

2. 设定2-3倍GOP大小的backBufferTime,这样至少可以让Wowza Streaming Engine快速找到2-3个关键帧。如果说找到一个关键帧还不足以开始录制的话,2-3个总是可以启动录制了吧? 不至于在视频关键帧前录了过多的音频。

3.其它Wowza Streaming Engine的录制参数,采用默认值即可,即startOnKeyFrame为true, defaultAudioSearchPostion为true。


其实,大家可以看出来,问题的关键还是在于编码端的GOP设置。如果GOP设置过大,对于直播业务,无论如何也是不可取的。



其实也没有太复杂。还是得多做测试。