1.音视频模块技术体系结构及功能
实时音视频通信功能,采用B/S结构,分为数据库层、服务应用层、Web服务器层和IE客户端。如图1所示,通过浏览器端访问Web服务器,调用音视频应用服务器的业务逻辑以实现音视频通信,利用访问数据库服务器实现数据存取。模块的核心(服务应用层)是基于公司的Java Framework(JMF)和Java Message Service(JMS)实现的。用户可通过该模Message块直接与业务员进行音视频交流,业务员也可通过该模块现场录制一些指导性的音视频内容面向用户播放。还可以在线播放一些录制好的音视频资源,从而更加方便、快捷地解决问题。
图1模块技术体系结构示意图
2音视频模块数据流程
音视频模块的音视频功能是基于JMF实现的,本模块充分利用了JMF所提供的功能。如图2所示,其中编解码处理器(Processor)用于处理音视频的编解码,音视频通路管理器(Session Manager)用于管理所有的音视频通路。
图2模块数据流程示意图
音视频数据传输流程如下:
(1)首先客户端请求音视频交流。
(2)服务器端会初始化一个音视频通路管理器用来控制或者记录即将进行音视频交流的用户,并控制整个音视频传输的通路。
(3)捕捉用户的音频或者视频,利用摄像头和麦克等硬件设备即可完成。
(4)把捕捉的音频或视频数据(Datasource)传给一个处理音视频的处理(Processor),这个处理器是JMF定义的。通过这个处理器可以对源数据编码压缩(Encoding),并且转换成网络传输需要的数据格式一RTP格式。
(5)把处理好的数据通过音视频通路管理器传送给指定的参与者,该传输遵循RTP(Real—time TransProt Protocal)协议。
(6)接收音视频的参与者可以根据其带宽的大小选择音频或视频或两者同时进行播放,将接收的数据变换数据格式、解码(Decoding),然后传给播放器(如JMF中的Player)进行播放,播放音视频的时候要使用同步机制,以实现音视频的同步播放。
3.音视频模块关键技术
3.1实时传输协议
RTP是一种提供端对端传输服务的实时传输协议,用来支持在单目标广播和多目标广播网络服中传输实时数据,而实时数据的传输则由RTCP协议来监视和控制。如图3所示,使用RTP协议的应用程序运行在RTP之上,由多媒体应用程序生成的音频和视频数据块被封装在RTP信息包中,每个RTP信息被封装在UDP消息段中,然后再封装在IP数据包中。本模块中,RTP执行程序是应用程序的一部分。在送端,本模块把执行肿协议的信息包的应用程序中,然后应用程序把RTP信息包发到UDP的套接接口(Socket Interface);在接收息包通过UDP套接接口输入到应用程序,而后执行R1协议的应用程序从R1P信息包中抽出媒体数据。
图3 RTP协议层示意图
本模块是将RTP协议程序封装到JMF中执行的,
要程序代码为:
//得到原始音频数据的数据流tracks
TrackControl track[]。proce8sor.getTrackControls();
AudioFormat audioFormat;
audioFormat=new AudioFormat(AudioFormat.ULAW—R口,8000,8,1);
for(int i=0;i
{
……
//把这些tracks封装成RTP类型
track[i].setFormat(audioFormat)
}
3.2 Java音视频框架
JMF (Java Media Framework)是SUN公司提供音视频服务的一组框架,分为两层,如图4所示。本模块的音视频功能主要是通过JMF的一些核心API实现的。JMF Presentation and Processing API是建立在底层API(JMF Plug—in API)的基础上对音视频进行处理和控制的,Plug—in API提供了整合器(Multiplex—ers)、分解器(DeMultiplexers)、编×××(Codecs)、化器(Effects)和播放(Renders)等摹本功能。模块的应用程序就建立在这层API的基础上,这些API接口封装了底层API复杂的实现,可以直接被应用程序调用,进行音视频信息和音视频控制信息的传输。
图4 JMF框架示意图
本模块调用JMF的主要代码如下:
//捕捉音频数据
AudioFormat format=new AudioFormat(AudioFormat.ULAW,
8000,8,1);
Vector devices=CaptureDeviceManager.getDevieeList(format);
CaptureDevicelnfo di=null;
if(devices.size()>0)
{
di=(CaptureDevicelnfo)devices.elementAt(0);
}
else{
System.exit(一1);
}
//创建音视频的处理器Processor并初始化
try
{
Pmcess”P Manager.createProeessor(di.getLocator())
}catch(IOException e)
{
System.exit(一1);
}
catch(NoProoessorException
{
System.exit(一1);
}
prooessor.configure();
processor.setContentDesc riptor(newContentDeseriptor(
scriptor.RAW));
//得到原始音频数据的数据流tracks,然后把这些tracks封装
RTP类型
TrackControl
track[]2 prooessor.getTrackControls();
boolean
encodillIgOk=false;
AudioFormat
audioFormat;
audioFormat=new
AudioFormat(AudioFormat.ULAW—RTP,
8000,8,1);
for(int
i=0;i
{if(!eneodinsOk&&track[i]instanceof FormatContr01)
{if((track[i]).setFormat(andioFormat)==null)
{track[i].setEnabled(false);
}
else{
encodingOk=true;
}
{else{
track[i].setEnabled(false);
}
}
//创建会话管理器SessionManager。发送数据
DataSource ds=null;
try
{
Ds=processor.getDataOutput();
}catch(NotRealizedError e)
{
System.exit(一1);
}
SessionManager rtpsm=new corn.sun.media.却.
RTPSessionMgr();
rtpsm.initSession(…);
rtpsm.atartSession(…);
try
{
rtpsm.ereateSendStream(ds,0);
}catch(IOException
{
e.printStackTrace();
}
catch(UnsupportedFormatException
{
e.printStackTrace();
}
3.3 Java消息服务
JMS(Java Message Service)是其公司和其他伙伴公司提供的一种消息服务,它提供了一种通用的方式可以使处于消息系统里的应用之间或者软件组件来进行交互(创建、发送、接收、读取彼此所需要信息)。JMS定义了一些通用的接口,最小化了编程者需要了解的消息中间件的一些概念,但是对消息中间件却提供了足够的支持。本模块的消息体系采用了JMS技术,很方便地解决了模块的消息交互问题,例如客户端可以采用JMS中发送消息的方式,告知服务器端增加或者减少一个用户;或者发送消息通知其他用户进行音视频交流等。
音视频模块中JMS应用组件包括提供端(Provid—er)、用户端(Client)、消息(Message)等几部分,如图5所示,其工作流程为:先由标准类库(J2EE SDK)创建连接工厂(Connection Factory)、存放消息的位置(Destination),并且把它们绑定到命名空间上。工厂创建连接,然后连接创建出一个会话。发送端(Client)通过命名空间找到对应的工厂和目标,通过工厂创建连接,后连接创建会话,会话创建消息发送者(Message Producer),把消息发送到目标。接收端(Client)通过命名空间找到工厂和目标,通过工厂创建连接,然后连接创建会话,会话创建消息接收者(Message Receiver),再从目标取得消息。
图5 JMS工作流程图
JMS的消息处理方式有点对点(Point—To—Point)和发布一获取(Publish—Subscribe)两种方式?’。考虑到多用户性,本模块采用“发布一获取”消息机制,即建立在消息话柄(Topic)上,消息被发送到话柄里,然后接收端(Client)从队列中取出消息。但是每一个消息可以被多个接收端(Client)接收,而且发送方和接收方存在时间依赖性。发送消息主要代码如下:
ConnectionFactory topicConnectionFactory;
Context jndiContext;
TopicSession topicSession;
Topic topic;
topicPublisher;TopicPublisher
TextMessage message;
Try
{
jndiContext=new InitialContext();
}catch(NamingException e)
{
e.printStackTrace();
System.exit(1);
}
try
{
//创建
建连接工厂
topicConnectionFactory=(TopicConnectionFactory)jndiCnntext.100kup(”TopicConnec—
tionFactory”);
//创建topic
topic=(Topic)jndiContext.100kup(topicName);
}catch(NalllingException e)
{
e.printStackTrace();
System.exit(1);
}
Try
{
//创建连接
topicConnection=topicConnectionFactory.createTopicConnec-
tion();
//创建会话
topicSession=topicConnection.crealeTopicSession(false,Ses-
sion.AUTO—ACKNOWLEDGE);
//创建发送端
topicPublisher=topicSession.createPublisher(topic);
//创建文本消息(注:还可以创建对象消息,字节消息,流消息,图消息以保存不同的信息)
message=topicSession.createTextMessage();
for(int i=0;i
}
message.setText(”This message”+(i+1));
topiePublisher.publish(message);
{
}catch(JMSException e)
{
e.printStackTrace();
System.exit(1);
}
4.技术难点及解决方案
4.1降低网络带宽占用
网络带宽是网络软件设计中首先需要考虑的问题之一,开发人员必须在带宽消耗和服务质量之间取得一个恰当的平衡点。在本系统中,视频数据和音频数据编码格式的优劣是决定带宽消耗的关键,因此应该在保证一定音视频清晰度的前提下尽可能地采用占用带宽较低的音视频编码格式。考虑到以上要求,本系统在具体实现时分别采用H.263和G.723作为视频和音频编码格式。H.263是ITU在H.261的基础上开发成功的用作低位率传输的视频编码格式,它吸收了MPEG标准的若干概念和思想,非常适合用作网络多媒体传输,因而已为H.323、H.324等视频会议标准所采用。G.723则是ITU制定的适用于IP电话的语音编码格式,因其高质量、低码率而得到广泛应用。其属于双速率语音编码,可工作在5.3kbps和6.3kbps两个方式上,同样已为H.323、H.324等视频会议标准所采用。在系统测试时,笔者发现只要适当凋整H.263的编码质量,就完全可以做到在保证画面足够清晰(分辨率为CIF,即352×288)的同时将单个用户视频数据的带宽占用控制在50kbps左右,即使再加上音频数据,单个用户所产生的总数据流量也不到60kbps,很好地解决了带宽消耗和音视频清晰度之间的矛盾。
4.2用户媒体流管理
由于通信是在多用户环境下进行的,且每个用户都将同时发送音频流和视频流,因此如何高效实现用户管理和用户媒体流管理成为本系统设计中的一个难点。当有新用户加入时,由于网络状态的不确定性,其音频流和视频流最初到达同一远程用户的时间可能会相差很大。考虑到任何远程用户的音频流和视频流都必须同时呈现给本地用户,在只接收到两者之一的情况下,是不能认为该用户已完全加入到通信过程之中的,而是应该等待另一个媒体流的到来,再把该用户的音频流和视频流一并加以呈现。此外,系统还必须对远程用户的退出及时作出反应,例如关闭该用户的媒体播放窗口等。
鉴于以上这些情况,在RTPSender类的远程媒体流接收模块中特别设计了两个Vector类对象,即WaitingList和RunningList。当一新用户的某一媒体流(音频流或视频流)到达时,本地用户将接收到一个NewReceiveStreamEvent(MediaEvent的一种)。通过这个事件的引用可以检索到一个标识媒体流源端的CNAME和一个封装了媒体流本身的DataSource。只要将CNAME和DataSource一并存放到WaitingList中,就可在该远程用户的另一个媒体流到达时,以相同的CNAME为索引,从WaitingList中检索出上一次保存的DataSouree,然后再将之与这次得到的DataSource一并提交给远程媒体流播放模块进行播放。之后,再将两媒体流的共同CNAME(即该远程用户的CNAME)及其播放窗口(一个RTPReceiver实例)的引用存入RunningList中,并删除WaitingList中有关该远程用户的相关信息(即CNAME和DataSource),以此表示该远程用户已正式加入到本通信系统之中。同样。当有远程用户退出时,本地用户也将收到一个事件一ByeEvent(同样是一种MediaEvent)。通过它同样可以检索出一个CNAME,进而从RunningList中检索出对应的播放窗口引用,然后再进行窗口关闭等一系列后续清理工作。最后,删除RunningList中有关该远程用户的相关信息(即CNAME和播放窗口引用),以此表示该远程用户已正式退出本通信系统。综合以上流程不难看出,WaitingList和RunningList能够以较小的系统开销对用户状态进行简单快捷的管理,而且这个过程中丝毫不需要人工干预,非常好地解决了用户媒体流管理的难题。
5.结语
本实时音视频模块的设计研发,借鉴了国内外数字系统的经验,采用了国际先进的音视频技术,符合国际数字系统的标准,系统模块运行状况及测试效果良好。对于该系统模块的未来走向,如下:
图6 3GP、MP4视频转换精灵”主界面
图7 音视频面对面界面
(1)利用网格技术来解决带宽的问题,以保证音视频的质量和跨地域性,可以在每一个地域上布置一个网格服务器。
(2)利用现在的Web服务技术跨平台的特性,可以使目前已经存在的各种音视频咨询系统互通,从而形成一个整体的全球化的合作系统,并且可以通过各种终端进行连接,随时随地利用各种通信工具进行咨询。
(3)从系统的性能上考虑,应加强系统的协同性和即时性,也就是要追求系统的响应速度。
(4)随着网络技术的不断发展,安全问题日益重要,增强系统的稳定性、安全性等应用性能。