jrtp库使用指南Word格式文档下载.docx
- 文档编号:17348486
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:15
- 大小:28.43KB
jrtp库使用指南Word格式文档下载.docx
《jrtp库使用指南Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《jrtp库使用指南Word格式文档下载.docx(15页珍藏版)》请在冰豆网上搜索。
rtppacket.h"
rtpstructs.h"
rtpdefines.h"
+代表添加,-代表删除相应内容
第二部分JRTPLIB编程
下面先转载一部分网上的指南,红色标记是JRTPLIB-3.7修了后的使用方法
linux下基于jrtplib库的实时传送实现
一、RTP是进行实时流媒体传输的标准协议和关键技术
实时传输协议(Real-timeTransportProtocol,PRT)是在Internet上处理多媒体数据流的一种网络协议
,利用它能够在一对一(unicast,单播)或者一对多(multicast,多播)的网络环境中实现传流媒体数据的
实时传输。
RTP通常使用UDP来进行多媒体数据的传输,但如果需要的话可以使用TCP或者ATM等其它协
议。
协议分析:
每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前12个字节
的含义是固定的,而负载则可以是音频或者视频数据。
RTP是目前解决流媒体实时传输问题的最好办法,要在Linux平台上进行实时传送编程,可以考虑使用
一些开放源代码的RTP库,如LIBRTP、JRTPLIB等。
JRTPLIB是一个面向对象的RTP库,它完全遵循RFC
1889设计,在很多场合下是一个非常不错的选择。
JRTPLIB是一个用C++语言实现的RTP库,这个库使用
socket机制实现网络通讯因此可以运行在Windows、Linux、FreeBSD、Solaris、Unix和VxWorks等多种操
作系统上。
二、JRTPLIB库的使用方法及程序实现
(1)JRTPLIB函数的使用
a、在使用JRTPLIB进行实时流媒体数据传输之前,首先应该生成RTPSession类的一个实例来表示此次RTP
会话,然后调用Create()方法来对其进行初始化操作。
RTPSession类的Create()方法只有一个参数,用
来指明此次RTP会话所采用的端口号。
RTPSessionsess;
sess.Create(5000);
JRTPLIB-3.7中已经修改了Create(prot)方法。
新的Create方法被修改为Crea(sessparams,&
transparams)。
其中的两个参数需要如下先定义:
RTPUDPv4TransmissionParamstransparams;
RTPSessionParamssessparams;
sessparams.SetOwnTimestampUnit(1.0/8000.0);
/*设置时间戳,1/8000表示1秒钟采样8000次,即录音时的8KHz*/
sessparams.SetAcceptOwnPackets(true);
transparams.SetPortbase(portbase);
/*本地通讯端口*/
b、设置恰当的时戳单元,是RTP会话初始化过程所要进行的另外一项重要工作,这是通过调用RTPSession
类的SetTimestampUnit()方法来实现的,前面已经提过。
c、当RTP会话成功建立起来之后,接下去就可以开始进行流媒体数据的实时传输了。
首先需要设置好数据发
送的目标地址,RTP协议允许同一会话存在多个目标地址,这可以通过调用RTPSession类的
AddDestination()、DeleteDestination()和ClearDestinations()方法来完成。
例如,下面的语句表示的
是让RTP会话将数据发送到本地主机的6000端口:
unsignedlongaddr=ntohl(inet_addr("
127.0.0.1"
));
sess.AddDestination(addr,6000);
d、目标地址全部指定之后,接着就可以调用RTPSession类的SendPacket()方法,向所有的目标地址发送
流媒体数据。
SendPacket()是RTPSession类提供的一个重载函数
对于同一个RTP会话来讲,负载类型、标识和时戳增量通常来讲都是相同的,JRTPLIB允许将它们设置为会
话的默认参数,这是通过调用RTPSession类的SetDefaultPayloadType()、SetDefaultMark()和
SetDefaultTimeStampIncrement()方法来完成的。
为RTP会话设置这些默认参数的好处是可以简化数据的发
送,例如,如果为RTP会话设置了默认参数:
sess.SetDefaultPayloadType(0);
sess.SetDefaultMark(false);
sess.SetDefaultTimeStampIncrement(10);
之后在进行数据发送时只需指明要发送的数据及其长度就可以了:
sess.SendPacket(buffer,5);
在真正的语音传输中,上面的buffer就是我们录音时所得到的buffer。
使用上面的函数可以简单的发送,但无法真正的实现RTP传输,我们需要调用另一个接口:
sess.SendPacket((void*)buffer,sizeof(buffer),0,false,8000);
详细的说明可以查看JRTPLIB的说明文档。
e、对于流媒体数据的接收端,首先需要调用RTPSession类的PollData()方法来接收发送过来的RTP或者
RTCP数据报。
JRTPLIB-3.7中修改PollData()方法为Poll(),使用都一样
由于同一个RTP会话中允许有多个参与者(源),你既可以通过调用RTPSession类的
GotoFirstSource()和GotoNextSource()方法来遍历所有的源,也可以通过调用RTPSession类的
GotoFirstSourceWithData()和GotoNextSourceWithData()方法来遍历那些携带有数据的源。
在从RTP会
话中检测出有效的数据源之后,接下去就可以调用RTPSession类的GetNextPacket()方法从中抽取RTP数
据报,当接收到的RTP数据报处理完之后,一定要记得及时释放。
JRTPLIB为RTP数据报定义了三种接收模式,其中每种接收模式都具体规定了哪些到达的RTP数据报将会被
接受,而哪些到达的RTP数据报将会被拒绝。
通过调用RTPSession类的SetReceiveMode()方法可以设置
下列这些接收模式:
RECEIVEMODE_ALL 缺省的接收模式,所有到达的RTP数据报都将被接受;
RECEIVEMODE_IGNORESOME 除了某些特定的发送者之外,所有到达的RTP数据报都将被接受,而被拒绝
的发送者列表可以通过调用AddToIgnoreList()、DeleteFromIgnoreList()和ClearIgnoreList()方法来进
行设置;
RECEIVEMODE_ACCEPTSOME 除了某些特定的发送者之外,所有到达的RTP数据报都将被拒绝,而被接受
的发送者列表可以通过调用AddToAcceptList()、DeleteFromAcceptList和ClearAcceptList()方法来进
行设置。
下面是采用第三种接收模式的程序示例。
if(sess.GotoFirstSourceWithData()){
do{
sess.AddToAcceptList(remoteIP,allports,portbase);
sess.SetReceiveMode(RECEIVEMODE_ACCEPTSOME);
RTPPacket*pack;
pack=sess.GetNextPacket();
//处理接收到的数据
deletepack;
}
while(sess.GotoNextSourceWithData());
}
完整的代码中,首先需调用Poll()方法接收RTP数据报,然后在BeginDataAccess()和EndDataAccess()之间进行数据接收的操作。
此时,我们设定程序一直do-while等待并处理数据
do{
#ifndefRTP_SUPPORT_THREAD
error_status=sess_client.Poll();
checkerror(error_status);
#endif//RTP_SUPPORT_THREAD
sess_client.BeginDataAccess();
//checkincomingpackets
if(sess_client.GotoFirstSourceWithData())
{
printf("
Beginplay\n"
);
do
while((pack=sess_client.GetNextPacket())!
=NULL)
//Youcanexaminethedatahere
Gotpacket!
\n"
timestamp1=pack->
GetTimestamp();
lengh=pack->
GetPayloadLength();
RawData=pack->
GetPayloadData();
//得到数据
timestamp:
%dlengh=%d\n"
timestamp1,lengh);
//wedon'
tlongerneedthepacket,so
//we'
lldeleteit
//Beginplay
intfd=open("
/dev/dsp"
O_RDWR);
intstatus=write(fd,RawData,lengh);
Playbytes:
%d\n"
status);
if(status!
=lengh)
perror("
wrotewrongnumberofbytes"
status=ioctl(fd,SOUND_PCM_SYNC,0);
if(status==-1)
SOUND_PCM_SYNCioctlfailed"
Playend\n"
close(fd);
sess_client.DeletePacket(pack);
}
}while(sess_client.GotoNextSourceWithData());
//return0;
sess_client.EndDataAccess();
}while
(1);
(2)程序流程图
发送:
获得接收端的IP地址和端口号
创建RTP会话
指定RTP数据接收端设置RTP会话默认参数
发送流媒体数据
接收:
获得用户指定的端口号创建RTP会话设置接收模式接受RTP数据检索RTP数据源获取RTP数据报删除RTP数据报
22222
可以继承类,这样方便
首先发送端:
sessparams.SetOwnTimestampUnit(1.0/8000.0);
sessparams.SetMaximumPacketSize(64000);
sessparams.SetAcceptOwnPackets(true);
sessparams.SetSourceTimeoutMultiplier(50);
sessparams.SetUsePollThread(true);
transparams.SetPortbase(7000);
m_TransSession.Create(sessparams,&
transparams);
//。
。
数据操作
m_TransSession.SendPacket(pSendBuffer,iSendSize);
//可以不管分包等事情
接收端:
还是继承它的RTPSession这个类吧
classRTPAppSession:
publicRTPSession
{
public:
BOOLWaitForRecvData();
RTPAppSession(RTPSession*pSendSession);
~RTPAppSession();
voidTrans();
virtualvoidOnRTPPacket(RTPPacket*pack,constRTPTime&
receivetime,constRTPAddress*senderaddress);
protected:
long
m_lSendTotalSize;
m_lRecvTotalSize;
HANDLE
m_hRecvDataEvent;
int
m_Cnt;
char
m_Table[10];
//发送Session
RTPSession*
m_pSendSession;
voidOnNewSource(RTPSourceData*dat);
voidOnBYEPacket(RTPSourceData*dat);
voidOnRemoveSource(RTPSourceData*dat);
voidOnPollThreadStep();
voidProcessRTPPacket(constRTPSourceData&
srcdat,constRTPPacket&
rtppack);
};
按这个类操作就可以了,没必要自己搞得很累
3333
RTPSession
对于大多数的RTP应用程序,RTPSession类可能是JRTPLIB唯一使用的类。
它能完全处理RTCP部份的数据包,所以用户可以把精力集中在真正的数据收发。
要知道RTPSession类在多线程下并不是安全的,因此,用户要通过某些锁同步机制来保证不会出现在不同线程当中调用同一个RTPSession实例。
RTPSession类有如下的接口。
•RTPSession(RTPTransmitter:
:
TransmissionProtocolproto=RTPTransmitter:
IPv4UDPProto)
使用proto类型传输层创建一个PRTSession实例。
如果proto使用用户自定义(user-defined)传输层,则相应的NewUserDefinedTransmitter()函数必须实现。
ps:
这里默认就行了,默认就是IPV4网络。
•intCreate(constRTPSessionParams&
sessparams,constRTPTransmissionParams*transparams=0)
使用RTPSession参数sessparams和RTPTransmission参数transparams真正创建一个RTP会话。
如果transparams为NULL,则使用默认的参数。
RTPSessionParams我们可能要设得比较多,RTPTransmissionParams参数就只要设置其中的端口就行了,端口一定要设对,不然进行组播时,这个进程将不接收数据。
设置方式可以看example.cpp。
•voidDestroy()
离开一个会话但不向其它组成员发送BYE包。
我不推荐用这个函数除非是错误处理,正常离开我们应该用ByeDestroy()。
•voidBYEDestroy(constRTPTime&
maxwaittime,constvoid*reason,sizetreasonlength)
发送一个BYE包并且离开会话。
在发送BYE包前等待maxwaittime,如果超时,会不发送BYE包直接离开,BYE包会包含你的离开原因reason。
相应的reasonlength表示reason长度。
因为BYE包是一个RTCP包,RTCP不是要发就发的,它的发送时间是为了平衡带宽通过计算得出来的,那就很有可能到了要发的时候以经超过了maxwaittime时间了,作者可能认一直保留个这会话这么久没意义。
当然,我常常把maxwaittime设得很大。
•boolIsActive()
看看这个RTPSession实例是否以经通过Create建立了真实的会话。
•uint32tGetLocalSSRC()
返回我们的SSRC。
至于什么是SSRC,去看看RFC3550吧。
我说过JRTPLIB只是RTP协议的包装,并没有做任何应用的事情。
•intAddDestination(constRTPAddress&
addr)
添加一个发送目标。
当然,如果我们使用组播,这里只用调用一次,把我们的组播地址写进去。
这样,这组的全部人都能收到你发的包。
但是组播可因特网的上设置很烦。
而且用组播测试也很烦(组播必须BIND一个端口,如果你想在同一台机器上运行两个软件实例来没试,你就会发现同一个端口BIND两次,当然,后面那次会失败,也就是说测试不了,要测?
找两台机器,或用虚拟机
),如果组播不满足,我们就要把组播变在单播,这时就要返复调用这个函数把其它组成员的IP都加进来了。
具体可以看看example3.cpp。
•intDeleteDestination(constRTPAddress&
从发送地址列表中删除一下地址。
•voidClearDestinations()
清除发送
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- jrtp 使用指南
![提示](https://static.bdocx.com/images/bang_tan.gif)