网站建设 响应式 北京支付网站开发费可以做无形资产
在使用 JRTPLIB 进行实时流媒体数据传输之前,首先应该生成 RTPSession 类的一个实例来表示此次 RTP 会话。然后调用 Create() 方法来对其进行初始化操作
RTPSessionParams sessparams;
RTPUDPv4TransmissionParams transparams;
    sessparams.SetOwnTimestampUnit(1.0/10.0);                     //设置时戳发送频率
     sessparams.SetAcceptOwnPackets(true);                     //设置参数为ture,可以接收自己发送的流媒体数据
transparams.SetPortbase(portbase); //设置进行流媒体数据传输或接收的本主机端口
sess.Create(sessparams, &transparams); //创建RTP任务
2、数据发送 
    (1)、指定目标地址
    RTPIPv4Address  addr(destip, destport);          //声明RTPv4Address的对象addr,并初始化(设置目标地址)
sess.AddDestination(addr); //指定目标地址
   (2)发送流媒体数据
    SendPacket() 是 RTPSession 类提供的一个重载函数,具有多种形式:
    int SendPacket(void *data,int len);
    int SendPacket(void *data,int len,unsigned char pt,bool mark,unsigned long timestampinc); 
    int SendPacket(void *data,int len,unsigned short hdrextID,void *hdrextdata,int numhdrextwords);
    int SendPacket(void *data,int len,unsigned char pt,bool mark,unsigned long timestampinc,unsigned  short hdrextID,void *hdrextdata,int numhdrextwords);
    SendPacket() 最典型的用法是类似于下面的语句,其中第一个参数是要被发送的数据,而第二个参数则指明将要发送数据的长度,再往后依次是 RTP 负载类型、标识和时戳增量。 
    sess.SendPacket(buffer, 5, 0, false, 10); 
  
    (3)、设置发送数据默认参数
    对于同一个 RTP 会话来讲,负载类型、标识和时戳增量通常来讲都是相同的,JRTPLIB 允许将它们设置为会话的默认参数,这是通过调用 RTPSession 类的SetDefaultPayloadType()、SetDefaultMark() 和 SetDefaultTimeStampIncrement() 方法来完成的。为 RTP 会话设置这些默认参数的好处是可以简化数据的发送,例如,如果为 RTP 会话设置了默认参数: 
    sess.SetDefaultPayloadType(0); 
    sess.SetDefaultMark(false); 
    sess.SetDefaultTimeStampIncrement(10);
  
    之后在进行数据发送时只需指明要发送的数据及其长度就可以了: 
    sess.SendPacket(buffer, 5); 
  3、接收或发送延时
    RTPTime::Wait(RTPTime(1,0));       //延时10s;
 4、数据接收
   (1)、接收函数
    对于流媒体数据的接收端,首先需要调用 RTPSession 类的 PollData() 方法来接收发送过来的 RTP 或者 RTCP 数据报。由于同一个 RTP 会话中允许有多个参与者(源),你既可以通过调用 RTPSession 类的 GotoFirstSource() 和 GotoNextSource() 方法来遍历数据源中的所有数据,也可以通过调用 RTPSession 类的 GotoFirstSourceWithData() 和 GotoNextSourceWithData() 方法来遍历那些携带有数据的源。在从 RTP 会话中检测出有效的数据源之后,接下去就可以调用 RTPSession 类的 GetNextPacket() 方法从中抽取 RTP 数据报,当接收到的 RTP 数据报处理完之后,一定要记得及时释放。下面的代码示范了该如何对接收到的 RTP 数据报进行处理:
sess.BeginDataAccess(); //上锁,开始接收RTP数据
   if (sess.GotoFirstSourceWithData()) {  
      do {    
         RTPPacket *pack;    
        while((pack = sess.GetNetPacket()) != NULL) {
               cout <<   pack->GetPayloadLength() << endl;          //打印本次所收到的数据包内容         
// 处理接收到的数据
        }
       } while (sess.GotoNextSourceWithData());
    }
    
    (2)、接收设置
    通过调用 RTPSession 类的 SetReceiveMode() 方法可以设置哪些到达的 RTP 数据报将会被接受或拒绝,其参数有:
    RECEIVEMODE_ALL  缺省的接收模式,所有到达的 RTP 数据报都将被接受;
    RECEIVEMODE_IGNORESOME  除了某些特定的发送者之外,所有到达的 RTP 数据报都将被接受,而被拒绝的发送者列表可以通过调用 AddToIgnoreList()、DeleteFromIgnoreList() 和 ClearIgnoreList() 方法来进行设置;
    RECEIVEMODE_ACCEPTSOME  除了某些特定的发送者之外,所有到达的 RTP 数据报都将被拒绝,而被接受的发送者列表可以通过调用 AddToAcceptList ()、DeleteFromAcceptList 和 ClearAcceptList () 方法来进行设置。
5、控制信息
       JRTPLIB 是一个高度封装后的 RTP 库,程序员在使用它时很多时候并不用关心 RTCP 数据报是如何被发送和接收的,因为这些都可以由 JRTPLIB 自己来完成。只要 PollData() 或者SendPacket() 方法被成功调用,JRTPLIB 就能够自动对到达的 RTCP 数据报进行处理,并且还会在需要的时候发送 RTCP 数据报,从而能够确保整个 RTP 会话过程的正确性。
    
       而另一方面,通过调用 RTPSession 类提供的 SetLocalName()、SetLocalEMail()、SetLocalLocation()、SetLocalPhone()、SetLocalTool() 和 SetLocalNote() 方法,JRTPLIB 又允许程序员对RTP会话的控制信息进行设置。所有这些方法在调用时都带有两个参数,其中第一个参数是一个 char 型的指针,指向将要被设置的数据;而第二个参数则是一个 int 型的数值,表明该数据中的前面多少个字符将会被使用。例如下面的语句可以被用来设置控制信息中的电子邮件地址: 
    sess.SetLocalEMail("2111@qq.com",11); 
    
       通过调用 RTPSession 类提供的 EnableSendName()、EnableSendEMail()、EnableSendLocation()、EnableSendPhone()、EnableSendTool() 和 EnableSendNote() 方法,可以为当前 RTP 会话选择将被发送的控制信息。
6、以下是我根据示例写的发送端个接收端的代码
发送端:
#include <iostream>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
using namespace std;
 #include "../include/jrtplib3/rtpsession.h"
 #include "../include/jrtplib3/rtpudpv4transmitter.h"
 #include "../include/jrtplib3/rtpsessionparams.h"
 #include "../include/jrtplib3/rtpipv4address.h"
 #include "../include/jrtplib3/rtperrors.h"
 #include "../include/jrtplib3/rtppacket.h"
int checkerror(int err) {
  if (err < 0) {
   string errstr(RTPGetErrorString(err));
   cout << "Error:" << errstr <<endl;
   exit(-1);
  }
  return 0; 
 }
int main(void)
 {
  RTPSession sess;
  RTPUDPv4TransmissionParams transparams;
         RTPSessionParams sessparams;
  int val;
  char buffer[10] = "123456789";
  unsigned long  destip = ntohl(inet_addr("127.0.0.1"));
  int destport = 6008;
  int portbase = 6002;
 sessparams.SetOwnTimestampUnit(1.0/10.0);        
         sessparams.SetAcceptOwnPackets(true);
         transparams.SetPortbase(portbase);
 val = sess.Create(sessparams, &transparams);
  checkerror(val); 
 RTPIPv4Address addr(destip, destport);
   
  val = sess.AddDestination(addr);
  checkerror(val);
         while(1) {
   val = sess.SendPacket(buffer, sizeof(buffer), 0, false, 10);
   checkerror(val);                                                                   
   cout << "Send packet:"<< buffer << endl;
   
 #ifndef RTP_SUPPORT_THREAD
                 val = sess.Poll();
                 checkerror(val);
 #endif // RTP_SUPPORT_THREAD
   RTPTime::Wait(RTPTime(1,0));
  }
  sess.BYEDestroy(RTPTime(10,0),0,0);
  return 0;
 } 
接收端:
#include <iostream>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
using namespace std;
 #include "../include/jrtplib3/rtpsession.h"
 #include "../include/jrtplib3/rtpudpv4transmitter.h"
 #include "../include/jrtplib3/rtpsessionparams.h"
 #include "../include/jrtplib3/rtpipv4address.h"
 #include "../include/jrtplib3/rtperrors.h"
 #include "../include/jrtplib3/rtppacket.h"
int checkerror(int err) {
  if (err < 0) {
   string errstr(RTPGetErrorString(err));
   cout << "Error:" << errstr <<endl;
   exit(-1);
  }
  return 0; 
 }
int main(void)
 {
  RTPSession sess;
  RTPUDPv4TransmissionParams transparams;
         RTPSessionParams sessparams;
  int val;
  int localport = 6008;
 sessparams.SetOwnTimestampUnit(1.0/10.0);        
         sessparams.SetAcceptOwnPackets(true);
         transparams.SetPortbase(localport);
 val = sess.Create(sessparams, &transparams);
  checkerror(val);
  
  while (1) {
          sess.BeginDataAccess();
          if (sess.GotoFirstSourceWithData()) {
                  do {
                          RTPPacket *pack;
                          while ((pack = sess.GetNextPacket()) != NULL) {
                                  cout <<"Got packet!  "
           << pack ->GetExtendedSequenceNumber()
           << "   from SSRC  "
           << pack->GetSSRC()
           << "    Length:   " 
           << pack->GetPayloadLength()
           << "   "
           << pack->GetPayloadData()
           << "  "
           << pack->GetPacketData() << endl;
                                  sess.DeletePacket(pack);
                          }
                  } while (sess.GotoNextSourceWithData());
           }
           sess.EndDataAccess();
  
 #ifndef RTP_SUPPORT_THREAD
                 val = sess.Poll();
                 checkerror(val);
 #endif // RTP_SUPPORT_THREAD
   // RTPTime::Wait(RTPTime(1,0));
  }
  sess.BYEDestroy(RTPTime(10,0),0,0);
 return 0;
 } 
文章出处:http://blog.csdn.net/zhulinfeiba/article/details/3573048
