DSS(Darwin Streaming Server)任务一:让直播支持拖放
jackyhwei 发布于 2010-12-09 14:22点击:957次 |
|
DSS,全称Darwin Streaming Server,一个开源的流媒体服务器,来自于Apple公司。
功能一,点播,指点播文件,可以拖放。
功能二,直播,指接收直播节目源,不支持拖放。
现在的需求是:希望在直播过程中,可以允许终端用户查看半小时内的历史视频;即,允许终端用户拖放,或者说快进快退。
从8月17日到8月22日,经过12天的开发,已将现有的Darwin流媒体服务器改造成为支持直播过程中前后拖放,具备时移功能的流媒体服务器,拖放范围:30分钟的缓存。并已完成针对QuickTime的自测,功能可用。VLC的测试显示,支持向后拖放,不支持向前拖放,因为VLC不支持seq_num变小、timestamp变小。
现在,需要客户端和服务器端协同开发,完成时移电视功能开发,需要做的工作如下:
1. 服务器端,提供响应含有UTC时间的RTSP指令,推送RTP数据,定期发送合适的RTCP数据;(已完成实现)
2.客户端,根据用户操作,发出含有UTC时间的RTSP指令,接收RTP数据,根据收到的RTCP数据,校正视频和音频的同步。
主要目标:客户端需要8655和1800开发组进行配合,实现基于UTC请求的RTSP请求(需要终端开发组配合实现)。
1.ReflectorSession,对应于一路直播;在收到RTSP的describe命令的时候,DoDesribe()函数中创建它;
2. ReflectorStream,一个ReflectorSession有两个ReflectorStream;
3.ReflectorSocket,每个ReflectorStream在BindSockets()函数中,GetUDPSocketPair得到fSockets里面放置了两个UDPSocket,你知道,这事实上会指向ReflectorSocket;每个Socket会AddSender,于是RTP的socket关联了fRTPSender,而RTCP的socket关联了fRTCPSender;
4. RTPSessionOutput,在收到RTSP的setup命令的时候,DoSetup()函数中找到ReflectorSession,AddOutput(),该函数会调用ReflectorStream::AddOutput(),RTPSessionOutput的指针也就保存在ReflectorStream中的数组里面了;(每有一个用户请求视频,那么RTPSessionOutput会添加一次Output);
5. ReflectorSender,在上述3中我们提到的fRTPSender,和fRTCPSender,就是它啦。
ReflectorSocket::ProcessPacket()函数中接收Broadcaster的数据;
ReflectorSender::ReflectPacket()函数中给RTPSessionOutput发送数据;你知道,很多Output。
DSS直播时拖放功能的开发过程
搭建环境;前端是Broadcaster,中间是DSS,后面是VLC,或者QuickTime;
1. 引入log类,方便跟踪代码流程,和定位开发中的问题;
2.RTSP命令层,在DoDescribe的时候,回复一个RANGE;在DoPlay的时候,接收到请求的RANGE,根据起始时间,定位到要播放的包,并响应RTSP命令;
3. RTP数据层:
a. 定位到Packet,知道从哪个Packet开始回放;
b. FilterPacket函数,会根据SeqNum,将一些Packet过滤掉;所有要更改过滤条件;
c.PacketAlreadySend函数,会根据PacketID(接收到包之后的一个编码,64位长),将一些Packet认为已经发送过,所以要更改这个判决条件(要发送的PacketID-1);
d.流控机制,不能一下子将队列中所有的包都发过去,要有流程;初步的想法是<=300KB,后来发现这不可行;现在的做法是,开始发送第一个包前,记下播放时间,以后发送每个包的时间为FirstTimeSend+(TimeArrived-FirstTimeArrived),实现了回放该流;
4. RTCP数据层:
如果是直播,那么回放RTCP包,这是毫无问题的;
如果是直播回放,那么历史的RTCP包,已经不能使用了;
正确的做法是:接收包的时候,就将所有的RTCP包过滤掉,回放的时候呢,发送出第一个包之后,发送RTCPSR;以后每个5秒发送RTCPSR;发送RTCPSR这个功能在RTPStream::Write中有,通过flag开关控制,打开即可。