jekeyhui99 发表于 2016-7-13 18:07:04

丢弃RTMP协议的FLASH视频直播方案所踩过的坑

http://blog.csdn.net/yuanrxdu/article/details/23593035

很久没有写博客了,最近一直在忙FLASH直播相关的事情,终于完成了阶段性工作。先描述下我们的FLASH方案。我们主要用FLASH在浏览器展示实时游戏直播视频,视频可以除了可以再WEB上观看,也可以在语音客户端观看和手机观看。开始我们采用基本的FLASH FMS/RTMP方式。测试下来有以下几个问题:1、上传和观看必须用FLASH,RTMP和FLASH本身很多细节无法掌控。2、带宽问题,FLASH编码的视频带宽过大,视频品质相同的情况下640P的分辨率(70 ~ 90KB/S)与用X264应用程序编码(35 ~ 55KB/S)的同分辨率相比带宽大30KB/S,这是不能接受的。3、传输RTMP承载过于呆板和复杂,无法根据实时直播进行优化。4、其他一些FLASH FMS上的问题。例如:严格时间戳问题、语音丢包问题、延迟问题等。
测试下来,无法跟我们现有的语音视频应用软件做很好的兼容。经过讨论后,我们采用私有协议传输,前端用FLASH做展示。利用FLASH的TCP和FLV做一个仿应用程序的WEB客户端。总体方案描述如下:1.实时上传视频通过语音客户端进行,客户端用X264和HEAAC进行进行媒体编码,通过私有的网络协议上传到媒体服务器上。2.媒体服务器实现语音和视频分离传输,为什么要分离传输呢?语音为了防止延迟,采用的是UDP方式传输,允许丢包,也可以采用语音特有的QOS算法进行控制;视频采用RUDP方式传输,不允许丢包,尽量减少延迟。分离传输还有一个好处就是可以根据语音和视频带宽特性调配具体的机房带宽。3、设计一个falsh gate服务来耦合WEB FLASH的接入。在这个网关上实现语音和视频的合并、协议转译、FLASH的接入协议实现、FLASH的私有协议QOS保证、减少播放缓冲等待等。4、实现一个WEB FLASH播放器。主要实现私有协议的接入、FLV缓冲播放、多路媒体管理、视频JITTER BUFFER/语音JITTER BUFFER、核心C的模块嵌入(SWC方式)、语音视频同步、QOS评估和路线选择、断线重连等。下图是整个流数据的走向图:http://img.blog.csdn.net/20140413113113640?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVhbnJ4ZHU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

整个方案大概用了1个月实现,期间遇到了很多坑。如下:1、在初期的实现的版本中,视频在FLASH端感觉很卡,没有丢包,在模拟客户端中是完全正常的。我们查看FLV播放的帧,发现只有5帧被播放。后来我查看编码器中的参数,发现在640P分辨率下用了H264的B帧编码,从测试模拟程序来看,FLASH好像不支持B帧。把B帧去掉,进行测试,正常了。2、视频分包问题,在我们的客户端传输网络中,为了兼容P2P,我们将一帧视频数据以4K大小进行分包。因为数据包是直接透传到FLASH PLAYER上,必须在FLASH SWC中做组包。开始一直因为组包方式不对,FLV播放无图像或者出现马赛克。后来严格调整时间戳和组包算法,正常了。时间戳一定要严格对齐,至少在FLV播放前是这样的。3、语音叠帧问题,我们采用HEAAC进行编码,1秒钟会产生22 ~ 23帧数据,在客户端为了减少UDP报文的数量,采用了3帧叠成一个语音报文,这样时间戳在报文中是最后一帧数据的时间戳,在FLASH播放端处理的时候,开始以最后时间戳进行播放,声音很钝。后来进行测试和问题查找,发现在时间戳上,进行时间戳完全校验,收到一个语音包后进行拆帧,第一帧的时间戳是TS - 2*44,第二帧的时间戳是TS - 44,第三帧是TS。进行测试,完全正常了。4、语音采样率的坑,我们在客户端都是采用48KHZ的双声道采样编码,在FLASH PLAYER FLV完全无法听到声音。后来查找FLASH支持的采用,才发现只支持11KHZ,22KHZ,44.1KHZ采样。但是我们的HEAAC中好像没有支持44.1KHZ的采样编码。回过头进行HEAAC的改造,把44.1KHZ的采用率编码加上。进行测试,正常通过。5、FLASH PLAYER播放器内存泄露问题。在长时间运行过程中,浏览器的内存越来越大,开始毫无头绪。后来经过仔细查找,发现是SWC(flash 嵌入C模块)有内存泄露。用工具经常排查,修改对应FLASH 嵌入C中的内存泄露问题,进行测试,内存正常。6、FLASH POLICY FILE问题,在FLASH 使用TCP连接外网服务器时,做过网游的同学应该知道有个策略验证。我按照网络上搜索的格式填写回应后,FLASH还是拒绝工作。进行抓包查看,发现POLICY报文完全正确。查找ADOBE网站上的资料,发现在服务端的SOCKET必须用同步SOCKET进行POLICY回应,客户端才会生效。因为我们服务器采用的都是EPOLL ET模式,所以没办法。只好另外起一个监听843端口的同步SOCKET线程进行POLICY响应。进行测试,正常了。
总结,FLASH私有协议视频直播中,由于很多细节FLASH并没有公开,在开发进度上会比FMS RTMP方案慢很多,成本也大很多。但一旦做成了,视频直播的效果和服务器部署不会受FMS和RTMP的限制,可以做更多结合自身业务的优化。带宽成本也小近30%。私有协议还有个一个好处就是可以做到多屏融合,移动端、WEB端、PC客户端任意兼容。这是值得的。
PS:作者有些坑说的是有问题的,比如B帧的坑,FLash对B帧的支持没问题,是作者的服务端程序问题
页: [1]
查看完整版本: 丢弃RTMP协议的FLASH视频直播方案所踩过的坑