基于JMF RTP的网络传输媒体流
2012-01-03 17:37
330 查看
JMF中可以实现RTP媒体流的回放(playback)和传输(transmission),主要由javax.media.rtp,
javax.media.rtp.event,和javax.media.rtp.rtcp包中定义的API完成。JMF可以通过标准的JMF
plug-in机制来实现支持特定的RTP格式和动态负载。
你可以在本地播放RTP数据流,或将其存储到本地文件。
同样,你可以通过JMF中RTP API实现传输捕获的或存储的媒体流到网上。RTP媒体流可以创建自一个本地文件或捕获自媒体采集设备。这些RTP媒体流同样可以在本地播放或存储。
1. RTP结构
1.1 SessionManager
[align=left]在JMF架构中Session Manager对程序之间的会话进程进行控制和管理。Session Manager主要作用:[/align]
[align=left]①明确每一个会话(session)中的所有参与者(participants)。[/align]
[align=left]②管理每一个RTP会话。[/align]
[align=left]③保存来自每一个发送或接收到的RTP和RTCP包中的统计信息。[/align]
[align=left]JMF RTP Session结构图:[/align]
[align=left]SessionManagr包含2个部分:Session Statistics和Session Streams。[/align]
[align=left] [/align]
1.1.1Session Statistics
统计量(Statistics)是记录基于每一条媒体流上的整个会话的统计信息。它包含:
①GobalReceptionStats:包含此会话的全局接收统计信息。
②GobalTransmissionStats:包含此会话的全局传输统计信息。
③RecetionStats:包含每一个参与者接收统计信息。
④TransmissionStats:包含每一个参与者的传输统计信息。
1.1.2Session Streams
①ReceiveStream:表示一个接收到的来自远端参与者的媒体流。
②SendStream:表示一个来自本地的媒体流。
1.2 RTP事件
[align=left]如下图所示,通过继承JMF中MediaEvent的类,可以创建响应的RTP事件。[/align]
[align=left] [/align]
[align=left]⑴SessionListener:通过它得到一个会话状态的改变。[/align]
[align=left]①NewParticipantEvent:表示一个新的参与者加入会话。[/align]
[align=left]②LocalCollisionEvent:表示参与者请求的同步资源正在使用。[/align]
[align=left] [/align]
[align=left]⑵SendStreamListener:通过它得到一个正在传送的RTP数据流状态的改变。[/align]
①NewSendStreamEvent:表示本地参与者已经创建一个新的发送数据流。
②ActiveSendStreamEvent:表示从DataSource创建的数据流已经开始发送。
③InactiveSendStreamEvent:表示从本地DataSource创建的数据流已经停止。
④LocalPayloadChangeEvent:表示数据流格式已经开始改变。
⑤StreamClosedEvent:表示数据流已经停止。
[align=left]⑶ReceiveStreamListener:通过它得到一个正在接收的RTP数据流状态的改变。[/align]
[align=left]①NewReceiveStreamEvent:表示SessionManager已经创建了一个从新的侦测到的地址传来的接收数据流。[/align]
[align=left]②ActiveReceiveStreamEvent: 表示数据的传送已经开始。[/align]
[align=left]③InactiveReceiveStreamEvent:表示数据的传送已经停止。[/align]
[align=left]④TimeoutEvent:表示数据传送超时。[/align]
[align=left]⑤RemotePayloadChangeEvent:表示接收到的数据流格式已经改变。[/align]
[align=left]⑥ApplicationEvent:表示收到了一个RTCP App数据包。[/align]
⑷RemoteListener:通过它得到远端会话参与者的时间或RTP控制信息。
[align=left]①ReceiverReportEvent:表示接收到一个RTCP的RR包。[/align]
[align=left]②SenderReportEvent:表示收到一个RTCP的SR包。[/align]
[align=left]③RemoteCollisionEvent:表示两个远端的参与者使用了相同的SSRC 出错。[/align]
[align=left] [/align]
[align=left]1.3与RTP事件相对应的RTCP类型表[/align]
[align=center] RTCP的控制类型和JMF事件类的一致性[/align]
[align=center] [/align]
1.4数据传输格式
在RTP传输中,如果还是用传统的AVI,MOV格式的话,将会增加服务器负荷,而且对网络要求特别高,因此需要将传统格式转化至易于传送,网络适应性好,抗丢包性能和抗误码性能好的编码格式。下表是JMF项目支持的视音频在RTP传送的压缩格式,也就是说经过定制后的输出视频流,还得进行一次转换,以便网络发送。
[align=center]表 JMF支持的视音频在RTP传送中的格式[/align]
转化格式的关键代码及其分析(视频):
2.RTP媒体数据流的传输与接收
2.1 RTP媒体数据流的传输过程
上图为Transmit的整个设计架构,Processor处理来自Capture Device的数据后,输入对方IP和Port,将数据传送到网络上等待接收端接收,其中音频的端口为视频的端口加2。
部分代码及分析:
①将转换格式后的数据放入一个DataSource
数据源决定了轨道数的多少,如果数据源中包括视频和音频内容,则有两个轨道,一个轨道分给视频,一个轨道分给音频,在数据源的格式转制完成以后,每个轨道对应着一个RTP会话,这些RTP会话由会话管理器(RTPManager)统一管理。
②以下是建立RTP Session中发送的关键代码和分析:
2.2 RTP媒体数据流的接收过程
接收方式为经由SessionManager到DataSource到Player,然后播放。上图即为Receive的整个设计构架,传送端送出数据后,接收端输入对方IP然后等待接收数据,其中音频的端口为视频的端口加2。
部分代码及分析:
[align=left]2.3基于JMF 的RTP/RTCP 传输模型的整体设计[/align]
3.参考资料
[1]JMF2.0 API Guide
[2]台湾国立中央大学电机工程系通讯专题报告VOIP
本文出自 “子 孑” 博客,请务必保留此出处/article/4381700.html
javax.media.rtp.event,和javax.media.rtp.rtcp包中定义的API完成。JMF可以通过标准的JMF
plug-in机制来实现支持特定的RTP格式和动态负载。
你可以在本地播放RTP数据流,或将其存储到本地文件。
同样,你可以通过JMF中RTP API实现传输捕获的或存储的媒体流到网上。RTP媒体流可以创建自一个本地文件或捕获自媒体采集设备。这些RTP媒体流同样可以在本地播放或存储。
整体流程图示:
1. RTP结构
1.1 SessionManager
[align=left]在JMF架构中Session Manager对程序之间的会话进程进行控制和管理。Session Manager主要作用:[/align]
[align=left]①明确每一个会话(session)中的所有参与者(participants)。[/align]
[align=left]②管理每一个RTP会话。[/align]
[align=left]③保存来自每一个发送或接收到的RTP和RTCP包中的统计信息。[/align]
[align=left]JMF RTP Session结构图:[/align]
[align=left]SessionManagr包含2个部分:Session Statistics和Session Streams。[/align]
[align=left] [/align]
1.1.1Session Statistics
统计量(Statistics)是记录基于每一条媒体流上的整个会话的统计信息。它包含:
①GobalReceptionStats:包含此会话的全局接收统计信息。
②GobalTransmissionStats:包含此会话的全局传输统计信息。
③RecetionStats:包含每一个参与者接收统计信息。
④TransmissionStats:包含每一个参与者的传输统计信息。
1.1.2Session Streams
①ReceiveStream:表示一个接收到的来自远端参与者的媒体流。
②SendStream:表示一个来自本地的媒体流。
1.2 RTP事件
[align=left]如下图所示,通过继承JMF中MediaEvent的类,可以创建响应的RTP事件。[/align]
[align=left] [/align]
[align=left]⑴SessionListener:通过它得到一个会话状态的改变。[/align]
[align=left]①NewParticipantEvent:表示一个新的参与者加入会话。[/align]
[align=left]②LocalCollisionEvent:表示参与者请求的同步资源正在使用。[/align]
[align=left] [/align]
[align=left]⑵SendStreamListener:通过它得到一个正在传送的RTP数据流状态的改变。[/align]
①NewSendStreamEvent:表示本地参与者已经创建一个新的发送数据流。
②ActiveSendStreamEvent:表示从DataSource创建的数据流已经开始发送。
③InactiveSendStreamEvent:表示从本地DataSource创建的数据流已经停止。
④LocalPayloadChangeEvent:表示数据流格式已经开始改变。
⑤StreamClosedEvent:表示数据流已经停止。
[align=left]⑶ReceiveStreamListener:通过它得到一个正在接收的RTP数据流状态的改变。[/align]
[align=left]①NewReceiveStreamEvent:表示SessionManager已经创建了一个从新的侦测到的地址传来的接收数据流。[/align]
[align=left]②ActiveReceiveStreamEvent: 表示数据的传送已经开始。[/align]
[align=left]③InactiveReceiveStreamEvent:表示数据的传送已经停止。[/align]
[align=left]④TimeoutEvent:表示数据传送超时。[/align]
[align=left]⑤RemotePayloadChangeEvent:表示接收到的数据流格式已经改变。[/align]
[align=left]⑥ApplicationEvent:表示收到了一个RTCP App数据包。[/align]
⑷RemoteListener:通过它得到远端会话参与者的时间或RTP控制信息。
[align=left]①ReceiverReportEvent:表示接收到一个RTCP的RR包。[/align]
[align=left]②SenderReportEvent:表示收到一个RTCP的SR包。[/align]
[align=left]③RemoteCollisionEvent:表示两个远端的参与者使用了相同的SSRC 出错。[/align]
[align=left] [/align]
[align=left]1.3与RTP事件相对应的RTCP类型表[/align]
[align=center] RTCP的控制类型和JMF事件类的一致性[/align]
[align=center] [/align]
RTCP类型 | JMF中的事件类 |
SR | SendStreamEvent |
RR | ReceiveStreamEvent |
SDES | SenderReportEvent |
BYE | ByeEvent |
APP | ApplicationEvent: |
在RTP传输中,如果还是用传统的AVI,MOV格式的话,将会增加服务器负荷,而且对网络要求特别高,因此需要将传统格式转化至易于传送,网络适应性好,抗丢包性能和抗误码性能好的编码格式。下表是JMF项目支持的视音频在RTP传送的压缩格式,也就是说经过定制后的输出视频流,还得进行一次转换,以便网络发送。
[align=center]表 JMF支持的视音频在RTP传送中的格式[/align]
多媒体类别 | RTP传输格式 |
音频 | JAUDIO_G711_ULAW/rtp,dvi/rtp ,g723/rtp ,gsm/rtp |
视频 | jpeg/rtp,h261/rtp,h263/rtp |
//从processor获得轨道控制器 TrackControl [] tracks = processor.getTrackControls(); //为每个轨道的格式进行转制 for (int i = 0; i < tracks.length; i++) { //此处省略获得轨道信息格式和支持格式代码 //下面一行为转制函数,需要参数为:轨道格式和轨道支持的格式 chosen = checkForVideoSizes(tracks[i].getFormat(), supported[0]); //此处省略如果不能对轨道格式转变代码 } //转制函数 /* 在传输视频信息时,对于JPEG编码格式,视频图像的宽和高是8像素的整数倍,对于 *H263编码格式,只支持三种图像的大小,即352X288,176X144,128X96像素,只要满 *足了这些条件,才可以正常传输视频信息,所以,需要对视频格式进行转制, *不负荷条件的都需要转化,以满足正常传输。 */ Format checkForVideoSizes(Format original, Format supported) { int width, height; Dimension size = ((VideoFormat)original).getSize();//获取视频图像的尺寸 Format jpegFmt = new Format(VideoFormat.JPEG_RTP); Format h263Fmt = new Format(VideoFormat.H263_RTP); if (supported.matches(jpegFmt)) {//如果是JPEG格式 //调整宽 width = (size.width % 8 == 0 ? size.width :(int)(size.width / 8) * 8); //调整高 height = (size.height % 8 == 0 ? size.height :(int)(size.height / 8) * 8); } else if (supported.matches(h263Fmt)) {//如果是H263格式 if (size.width < 128) { width = 128; height = 96; } else if (size.width < 176) { width = 176; height = 144; } else { width = 352; height = 288; } } else { //对于其他格式不受理 return supported; } return (new VideoFormat(null, new Dimension(width, height), Format.NOT_SPECIFIED, null, Format.NOT_SPECIFIED)).intersects(supported); |
2.1 RTP媒体数据流的传输过程
上图为Transmit的整个设计架构,Processor处理来自Capture Device的数据后,输入对方IP和Port,将数据传送到网络上等待接收端接收,其中音频的端口为视频的端口加2。
部分代码及分析:
①将转换格式后的数据放入一个DataSource
//获得转制后的DataSource dataOutput = processor.getDataOutput(); //将DataSource转化为Push数据流 PushBufferDataSource pbds = (PushBufferDataSource)dataOutput; //获取Push数据流 PushBufferStream pbss[] = pbds.getStreams(); |
②以下是建立RTP Session中发送的关键代码和分析:
rtpMgrs[i] = RTPManager.newInstance();//RTP管理器实例化 ipAddr = InetAddress.getByName("59.64.84.243");//获得目的地址的IP地址 //获取本机IP地址 localAddr = new SessionAddress( InetAddress.getLocalHost(),port); //获取目的机IP地址 destAddr = new SessionAddress( ipAddr, port); //分别将本机和目的机IP地址加入至RTP会话管理器 rtpMgrs[i].initialize( localAddr); rtpMgrs[i].addTarget( destAddr); //产生第N条轨道的传输流 sendStream = rtpMgrs[i].createSendStream(dataOutput, i); //传输流开始 sendStream.start(); |
接收方式为经由SessionManager到DataSource到Player,然后播放。上图即为Receive的整个设计构架,传送端送出数据后,接收端输入对方IP然后等待接收数据,其中音频的端口为视频的端口加2。
部分代码及分析:
/* *目的机建立RTP会话管理器原理和步骤基本与发送端一至,我们主要分析接收多媒体流的事件类。 */ public synchronized void update( ReceiveStreamEvent evt){ if(evt instanceof NewReceiveStreamEvent) {//接收到一个新的数据流 //根据获取的数据流获得一个数据源。这个数据源为播放使用 } else if (evt instanceof StreamMappedEvent) { //数据流映射事件 //如果当前数据源为NULL,根据这个事件获得一个Datasource,否则忽略 }else if (evt instanceof ByeEvent) {//数据接收完毕 //播放结束 } } |
3.参考资料
[1]JMF2.0 API Guide
[2]台湾国立中央大学电机工程系通讯专题报告VOIP
本文出自 “子 孑” 博客,请务必保留此出处/article/4381700.html
相关文章推荐
- 基于JMF RTP的网络传输媒体流
- 基于JMF RTP的网络传输媒体流
- 基于JMF RTP的网络传输媒体流
- 基于JMF RTP的网络传输媒体流
- 基于JMF RTP的网络传输媒体流
- 基于WCF的通道网络传输数据压缩技术的应用研究 推荐
- 基于TCP、UDP网络传输的实例分析
- 基于TCP的网络游戏黑白棋系列(二):数据传输
- JMF RTP的网络传输媒体流的实现
- 基于itop4412在Linux最小系统下的 RTP传输H264视频VLC播放
- 介绍基于ARM的网络图像传输技术
- 网络视频传输协议--RTP/RTCP/RTSP/SIP/SDP 之间关系
- 基于RTP和Android的视频传输的研究实现方法
- 网络编程应用:基于TCP协议【实现对象传输】--练习
- android网络操作---数据传输(基于HTTP协议)
- RTSP/RTP 媒体传输和控制协议
- [置顶] 基于iOS的网络音视频实时传输系统(六)- AudioQueue播放音频,OpenGL渲染显示图像
- c#基于RTP协议开发音频视频传输学习手记一
- 计算机网络笔记二 传输媒体
- JMF介绍之基于时间的媒体