视频点播服务器构建(转载)
摘要:LiveMedia已经在VLC和MPlayer等开源的流媒体播放软件中得到应用。文章对LiveMedia的组成和功能进行了分析,并对LiveMedia在视频点播方面的应用进行了详细的阐述。
关键词:流媒体RTPRTSP服务器视频点播
流媒体的市场空间迅速扩大,国内很多公司迅速介入流媒体产品的开发。国内的流媒体产品多借助于国外某些开源的RTP(实时传输协议real-
timetransportprotocol)开发库进行开发,在国外开源的RTP开发库中,LiveMedia不但提供了基于RTP协议的开发库,而且
对于开发库在视频点播,直播等方面的应用也给出相应的参考实例,这对于从事流媒体的开发人员来都具有较高的参考价值。整个库文件都是由标准的C++语言写
成,能够跨平台编译,适合于构建低成本的流媒体应用系统,也适合于嵌入式系统。
1LiveMedia的整体架构
LiveMedia可分为三部分:RTP库、LiveMedia库和流媒体应用实例,RTP库的主要功能是采用RTP协议完成数据的发
送,LiveMedia库主要功能是实现对各种媒体类型和编码格式的支持,应用实例主要用于说明如何应用RTP库开发流媒体应用程序。下面分别对三部分作
详细描述。
1.1RTP库
RTP库又可分为三部分:UsageEnvironment库、Groupsock库和
BasicUsageEnvironment库。为了区分这三部分,在源程序目录中有三个子目录来分别放置这三个库,这三个子目录的名字分别是三个库的名
字,即UsageEnvironment、Groupsock和BasicUsageEnvironment。本文来自中国鸣网论文站点(http://lunwen.mingmw.com)如需转载请声明来源.
UsageEnvironment库中包括了三个主要的类:UsageEnvironment类、TaskScheduler类和HarshTable
类,这些类都是抽象的基类,它们的实现都在其子类中完成。其中HarshTable类定义了通用Hash表的接口,主要为其它类服务。Hash表对象中存
放的是诸如Socket句柄一类的对象,一旦程序需要,能够实现快速查找。UsageEnvironment类和TaskScheduler类主要用来处
理延时事件,异步读取事件和输出错误或警告信息。延时事件处理是指对多媒体文件的传输处理,由于多媒体文件一般都较大,要完全发送到客户端需要经过较长一
段时间,客户端的播放程序要播放完这个文件一般也要经过一段时间。这样,为了实现边传输边播放,在服务器端将文件读出后,根据多媒体文件的播放速度,每隔
一段时间,发送一次数据,这些发送任务都发生在文件播出指令以后,以自动方式进行,不断循环,直到文件发送完毕或遇到停止指令。异步读取事件处理是指程序
通过Socket以异步方式接收指令,并进行相应的处理。输出错误或警告信息是指在整个程序运行过程中,如果出错误或警告信息,该部分负责输出。
Groupsock库中的类封装了网络接口和套接字,在这里完成指令和数据的收发任务。在有些情况下其中的Groupsock类还可以完成多播数据的发送和接收任务。
BasicUsageEnvironment类定义了UsageEnvironment类的一个具体实现,用作配置基本环境。
1.2LiveMedia库
这个库在代码目录中也有对应的子目录,目录名是LiveMedia。这部分是LiveMedia的核心,可以实现RTP和RTSP会话的建立、各种
RTPpayload的打包和解析以及RTSP的控制等。其中定义了一个基类Medium,其它各种与流媒体类型和编码有关的类都从这个类继承。以下是基
类Medium与其部分子类的关系图。在这里,MediaSink用于从其它模块接收数据并进行处理。MediaSource用于自身产生数据或接收其它
模块的数据,并可以将其输出。Mpeg1or2Demux用于将Mpeg1或Mpeg2格式的程序流文件的声音、图像分离。RTSPServer用于建立
基于RTSP协议的RTSP服务器。RTSPClient用于建立基于RTSP协议的客房端。还有其它很多子类可以在源程序和帮助文件中找到。
1.3应用实例
应用实例在源程序目录中对应于TestProgs子目录,这个子目录中的程序用来说明如何使用以上提到的两个库去开发应用程序。其中主要有以下几个程序:
1.3.1使用RTSP协议的客户端
程序名叫openRTSP,是一个命令行程序,用这个程序可打开、接收和记录某一媒体流,这个媒体流一般通过以RTSP开头的URL指定。例
如:RTSP://192.168.0.1/test,test是媒体流的名字。参照该程序,可以建立基于RTSP协议的客户端。
1.3.2使用RTSP协议的服务器端
程序名叫testOnDemandRTSPServer,这个程序能够在程序启动时建立RTSP服务器,并根据指定的文件建立相应的子会话,在接收到点
播命令后能够建立相应的单播流。该程序支持的视频媒体类型主要有MPEG1,MPEG2和MPEG4格式的基本流文件、MPEG1、MPEG2格式的程序
流和传输流文件。在这个程序的基础上,可以建立视频点播服务器,并可对服务器支持的格式进行扩展。
1.3.3MPEG声音+视频程序
程序名叫testMPEG1or2AudioVideoStreamer,这个程序在启动后能不断地读取指定的MPEG1或MPEG2程序流文件,并把
他们分解为独立的声音基本流和视频基本流,然后进行流化,发送数据包到多播组239.255.42.42,端口是6666/6667(声音)和8888
/8889(视频)。在这程序的基础上,可以建立视频直播服务器。
2应用分析
2.1RTP库的应用
RTP库的作用是方便使用者使用RTP协议发送和接收数据,无须考虑SSRC(同步源标识)冲突等一些底层的问题。它是LiveMedia的基础。在实际应用中,也可以只使用RTP库来发送多媒体数据,而不必考虑其它库。
2.2多格式支持库的应用
LiveMedia库的功能强大,不但支持多种格式,而且支持多种功能,包括建立点播服务器、直播服务器和客户端等。该库也有较大的扩展性,要扩展服
务器支持的格式可以通过继承FramedSource,要扩展客户端支持的格式可以通过继承MultiFramedRTPSink,通过以上继承方式来实
现自己的媒体类。
3用LiveMedia开发视频点播服务器
在实例程序testOnDemandRTSPServer的基础上,可建立起基于RTSP协议的视频点播服务器,对建立的视频点播服务器的测试,可采用通用RealPlayer或开源的VLC客户端进行。
3.1基本视频点播服务器分析
一个完整的视频点播服务器应包括点播服务系统和管理系统两大部分。点播服务系统的功能包括建立与客户端的RTSP会话、向客户端发送需要的媒体信息等,
管理系统则担负用户认证,计费等的任务。这其中的核心部分是媒体服务系统,服务器的性能很大程度上决定于它。LiveMedia代码中的实例程序
testOnDemandRTSPServer,能够说明视频点播服务器的建立过程,改进后就能作为我们需要的服务器。下面分析这一服务程序的建立流程:
(1)建立使用环境
通过代码TaskScheduler*scheduler=BasicTaskScheduler::createNew();
env=BasicUsageEnvironment::createNew(*scheduler);来生成BasicUsageEnvironment类的一个对象,建立基本使用环境。
(2)权限控制
利用代码UserAuthenticationDatabase*authDB=NULL;authDB=newUserAuthenticationDatabase;
authDB->addUserRecord(“username1″,”password1”);实现权限控制,可以阻止没有权限的用户进行点播。没有权限控制需要的可以省略此部分。
(3)建立RTSP服务器
利用代码RTSPServer*rtspServer=RTSPServer::createNew(*env,8554,authDB);建立
RTSP服务器,该服务器完成与客户端的交互,实现客户端的VCR操作,即在客户端完成对当前节目的播放、暂停、倒退、快进等操作。8554是RTSP服
务器的端口,也可以改为其它未被占用的端口,服务器的IP地址不用特别设定,它是运行点播服务程序的计算机的IP地址。该服务器只创建一次,一个服务器响
应所有的点播用户。
(4)创建服务器媒体会话
通过创建ServerMediaSession类的对象来创建服务器媒体会话,不
同的文体各自对应一个服务器媒体会话。一个媒体会话对应一个流名字(streamName)。当客户点播时,要输入流名字,告诉RTSP服务器点播的是哪
个流。流名字和文件名的对应关系是通过增加子会话建立起来的。媒体会话对会话描述、会话持续时间、流名字等与会话有关的信息进行管理。
(5)增加子会话
给已经创建的服务器媒体会话增加子会话,子会话可以是视频子会话,也可以是声音会话,或者两者都有。增加子会话通过ServerMediaSession类的addSubsession方法来实现。子会话的功能包括开始流、暂停流和删除流等诸多操作。
(6)执行循环方法
通过代码env->taskScheduler().doEventLoop();来执行循环方法,对套接字的读取事件和对媒体文件的延时发送操作都在这个循环中完成。
3.2视频点播服务器的实现
只要将要点播的文件放入服务器的指定目录,在客户端输入协议名、服务器的地址和文件名即可实现点播,例如在客户端输入
RTSP://192.168.0.1/test.vob,只要服务器的指定目录存在test.vob,即可正常播放。要实现这样的功能,必须对实例程序
进行改进。在testOnDemandRTSPServer程序中,服务器媒体会话是在程序启动的时候创建的,程序一旦启动便不能更改。要实现真正的视频
点播服务器,就必须实现动态的创建服务器媒体会话。
为了方便动态创建服务器媒体会话,可让流名字和文件名保持一致。当有客户端通过RTSP会话告诉服务器点播的文件名时,程序首先查找这个文件对应的服务器媒体会话是否存在。可以通过代码
fOurServer.lookupServerMediaSession(urlSuffix);
来实现,其中fOurServer是类RTSPServer的实例,lookupServerMediaSession是它的一个方法,此时urlSuffix是要查找的服务器媒体会话的名字。若不存在,可用以下代码创建:
fOurServer.createServerMediaSessoin(urlSuffix);
创建完成后加入子会话,最后将媒体会话加入RTSPServer。createServerMediaSessoin不是RTSPServe类本身具有的一个实例,需要自己编写。可以使用以下代码:
voidRTSPServer::createServerMediaSession(charconst*streamName){
charFileName[100];
strcpy(FileName,”D:VCVideoFile”);//点播文件所在目录
strcat(FileName,streamName);//得到完整的文件名
charconst*descriptionString=”TestOnDemand”;//流描述
BooleanreuseFirstSource=False;
BooleaniFramesOnly=False;
char*ExtName=strrchr(streamName,\’.\’);
if(!strcmp(ExtName,”.mpg”)){//如果是mpg类执行以下操作
ServerMediaSession*sms =ServerMediaSession::createNew(envir(),streamName,streamName,descriptionString);//创建媒体会话
MPEG1or2FileServerDemux*demux =MPEG1or2FileServerDemux::createNew(envir(),FileName,reuseFirstSource);
sms->addSubsession(demux->newVideoServerMediaSubsession(iFramesOnly));//添加子会话
sms->addSubsession(demux->newAudioServerMediaSubsession());//添加子会话
RTSPServer::addServerMediaSession(sms);//将媒体会话加入RTSPServer
}
}
若服务器媒体会话存在,就跳过创建流。当客户端通过RTSP会话要求播放媒体文件时,可以直接播放。
4结束语
LiveMedia视频点播服务程序根据需要,还可以进一步改进,例如,可以使之支持更多的格式或者成为直播服务器等。