日期:2014-05-16  浏览次数:20413 次

NetStream appendBytes 一点经验

最近在做基于 NetStream 的 appendBytes() 方法的快速搜索(seek)。

?

由于渐进式下载不能直接seek到未下载完成的部分,而用FMS成本又比较高,因此采用了如下方法:

根据seek的时间点,获取距离最近的关键帧位置的字节数,然后请求从该帧到下一关键帧的字节,作为一个切片appendBytes到NetStream中。之后继续请求下一帧的切片并添加到NetStream中播放。由于每次请求两帧之间的数据,返回速度很快,响应也就快。

?

条件:

1,FLV文件的所有关键帧信息(例如 ?... <bytes=392013 time=13.293/> ...),可以用FFMPEG获得;

2,准备一个Nginx插件,用来返回指定flv文件的指定字节片段;

?

?有几个需要注意的地方:

?

1,需要先添加文件最开始的两个切片,然后才能seek到其他位置。

第一个片一般是FLV文件头以及metadata数据,第二个片是一个关键帧,包含一个video tag和一个audio tag,字节数都很小;

最开始的时候我以为只要添加了第一个切片就行了,实验的结果似乎表明第二个片是NetStream用来初始化byte parser所必须的。

本来最早想的是直接请求任意位置的切片就播放。

?

2,解析字节需要时间。这个发现的依据是,本来为了简化逻辑,把前两片作为第一片来请求,这样的话添加了第一片后,就可以认为NetStream准备好了。但是如果在添加这第一片后马上seek到其他片,发现播放会出现问题,比如有画面没声音。因此尝试了推迟添加后面seek的片,问题没有再现。

?

3,在seek时需要先用seek(0)清空NetStream的两个缓存,这样time属性和buffer属性才能归零。

A NetStream object has two buffers: the FIFO from?appendBytes()?to the NetStream, and the playout buffer.

并且需要调用appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK)?来告诉NetStream这是个seek操作。

?

4,NetStreamAppendBytesAction的三个参数都可能用到,需要好好看看文档。

?

5,无法截图!使用appendBytes之前需要netStream.play(null),也就没有地方去加载crossdomain文件。网上也没搜到解决办法。