我之前有篇文章介绍过如果实现一个C/S模式的Flv点播系统,Flv格式简单,处理起来也比较轻松,不过,实际工作中,需要点播的影片,岂会只有Flv这一种格式。我们常见的几种视频格式,随便哪一个都要比Flv复杂的多,尤其是本身设计的时候就没有考虑到要通过网络观看的格式,要实现点播,自然要比Flv难的多。当然,你可以把所有影片都转成Flv格式来处理,可是,当你拥有成千上万部影片的时候,不但得一个个转换,还要一个个检查是否转换成功、转换质量如何等,那工作量可不是一点半点。从这点考虑出发,做一个支持多种视频格式的点播系统,就显得很有必要了。
可是,视频格式有很多,千差万别,有的格式里面,描述视频信息的字段一大堆,而有的格式里却几乎没什么描述的字段,这么个情况下,怎么能把它们揉合到一个系统中去呢?本人不才,做了这个尝试,目前已经支持AVI、TS、FLV、F4V格式在同一个点播系统中的播放和拖动,而且不存在拖动后花屏的现象。下面我介绍一下这个点播系统的设计方案和架构。
一、设计方案
点播系统,最重要的考虑因素就是“拖动”的处理,关键点就是要在客户端播放器“拖动”进度条的时候,服务器给客户端返回以关键帧起始的视频流,否则,播放器很有可能会出现花屏,甚至无法播放的情况。用户不是神仙,看影片的人才不会去关注一个片子里哪些时间点是关键帧的位置,用户拖动进度条的位置,是非常随意的,而视频并非每一秒都是关键帧,所以,播放器必须要把拖动后进度条的位置,重新定位到离它关键帧之处(想想看,大家平时看片,都是这种体验吧)。
在点播系统中,播放器想要实现上面所说的定位关键帧的技术,就要知道影片的关键帧列表,可是“点播”嘛,视频在服务器上,是边下边看的,没法自己解析,只能让服务器告诉它。具体的获知方式,我觉得,可以设计成以下3种方案,这3中方案,针对AVI, TS, FLV等很多格式,都可以适用:
1. 每次拖动之后时,先发起一个请求,将拖动位置告诉服务器,由服务器返回最近关键帧对应的位置,然后播放器再以这个位置发起请求,服务器返回数据,播放。
2. 将方案1的两个请求合并为1个,服务器返回关键帧位置+数据,播放器播放。
3. 在开始点播一个视频之前,先发起一个请求,服务器返回所有关键帧的位置,拖动时,播放器先定位到关键帧位置,然后直接请求数据,播放。
这个系统中,我选择了方案三,原因就是处理简单~~
二、处理逻辑
这里,以f4v文件为例。(其中,XVideoKFrame是视频格式解析程序,作用是读取AVI TS等视频,并生成关键帧列表。)
三、程序架构
1. Client端
相对比较简单,当然,原因是我采用了libvlc作为播放器内核,vlc对于播放网络流的支持,恐怕是最好的,这省去了你自己写播放器的工作。libvlc的接口比较简单,我就直接上代码,大家一看就明白了。
私有成员变量:
操作libvlc进行播放的方法:
2. Server端
点播Server端,就是一个比较特殊的HttpServer,“特殊”主要是指在处理拖动的请求上。
四、视频格式解析器
XVideoKFrame,负责读取并分析输入的视频格式,然后Video.kframe文件,这里面包含了关键帧列表和其他媒体信息,是一个非常重要的程序/模块,点播系统的工作基础。在上面的处理逻辑图里面,我把视频解析这部分放在了单独的程序当中,主要是方便平时调试和增加格式解析的代码。当然也可以放到Server中,在视频文件第一次被访问时,生成.kframe文件。
目前,该解析器已经支持AVI格式解析、TS格式解析、FLV格式解析和F4V格式解析,正在写ASF格式解析,往后也还会增加。视频格式解析,是点播系统中工作量最大的部分之一,除了要读取数不清的字段,还要针对不同的编码,做不同的处理。例如TS格式,是不是H264编码,对于关键帧的查找方法是完全不一样的。我就不把所有格式的解析方法写出来了,将来有机会再写文章介绍这些格式。
五、效果图
最后,让大家看一下效果图,这个是点播ts文件的效果