⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 流媒体编程linux

📁 本程序为在linux下实现FTP传输文件的实现
💻
📖 第 1 页 / 共 2 页
字号:

  目标地址全部指定之后,接着就可以调用 RTPSession 类的 SendPacket() 方法,向所有的目标地址发送流媒体
数据。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); 
  

  对于同一个 RTP 会话来讲,负载类型、标识和时戳增量通常来讲都是相同的,JRTPLIB 允许将它们设置为会话的
默认参数,这是通过调用 RTPSession 类的 SetDefaultPayloadType()、SetDefaultMark() 和
 SetDefaultTimeStampIncrement() 方法来完成的。为 RTP 会话设置这些默认参数的好处是可以简化数据的发送,
 例如,如果为 RTP 会话设置了默认参数: 

  sess.SetDefaultPayloadType(0); 
    sess.SetDefaultMark(false); 
    sess.SetDefaultTimeStampIncrement(10);
 

  之后在进行数据发送时只需指明要发送的数据及其长度就可以了: 

  sess.SendPacket(buffer, 5); 
  

  3.4 数据接收 

  对于流媒体数据的接收端,首先需要调用 RTPSession 类的 PollData() 方法来接收发送过来的 RTP 或者 RTCP 
数据报。由于同一个 RTP 会话中允许有多个参与者(源),你既可以通过调用 RTPSession 类的 GotoFirstSource()
 和 GotoNextSource() 方法来遍历所有的源,也可以通过调用 RTPSession 类的 GotoFirstSourceWithData() 和 
 GotoNextSourceWithData() 方法来遍历那些携带有数据的源。在从 RTP 会话中检测出有效的数据源之后,接下去就
 可以调用 RTPSession 类的 GetNextPacket() 方法从中抽取 RTP 数据报,当接收到的 RTP 数据报处理完之后,一
 定要记得及时释放。下面的代码示范了该如何对接收到的 RTP 数据报进行处理: 
if (sess.GotoFirstSourceWithData()) 
{
    do {     
	RTPPacket *pack;
	pack = sess.GetNextPacket();          // 处理接收到的数据     
	delete pack;  
    } while (sess.GotoNextSourceWithData());
}  JRTPLIB 为 RTP 数据报定义了三种接收模式,其中每种接收模式都具体规定了哪些到达的 RTP 数据报将会被
接受,而哪些到达的 RTP 数据报将会被拒绝。通过调用 RTPSession 类的 SetReceiveMode() 方法可以设置下列这
些接收模式: 

  ? RECEIVEMODE_ALL  缺省的接收模式,所有到达的 RTP 数据报都将被接受;

  ? RECEIVEMODE_IGNORESOME  除了某些特定的发送者之外,所有到达的 RTP 数据报都将被接受,而被拒绝的发
送者列表可以通过调用 AddToIgnoreList()、DeleteFromIgnoreList() 和 ClearIgnoreList() 方法来进行设置; 

  ? RECEIVEMODE_ACCEPTSOME  除了某些特定的发送者之外,所有到达的 RTP 数据报都将被拒绝,而被接受的发
送者列表可以通过调用 AddToAcceptList ()、DeleteFromAcceptList 和 ClearAcceptList () 方法来进行设置。 

  3.5 控制信息 

  JRTPLIB 是一个高度封装后的 RTP 库,程序员在使用它时很多时候并不用关心 RTCP 数据报是如何被发送和接收
的,因为这些都可以由 JRTPLIB 自己来完成。只要 PollData() 或者 SendPacket() 方法被成功调用,JRTPLIB 就能
够自动对到达的 RTCP 数据报进行处理,并且还会在需要的时候发送 RTCP 数据报,从而能够确保整个 RTP 会话过程
的正确性。 

  而另一方面,通过调用 RTPSession 类提供的 SetLocalName()、SetLocalEMail()、SetLocalLocation()、
SetLocalPhone()、SetLocalTool() 和 SetLocalNote() 方法,JRTPLIB 又允许程序员对RTP会话的控制信息进行设置
。所有这些方法在调用时都带有两个参数,其中第一个参数是一个 char 型的指针,指向将要被设置的数据;
而第二个参数则是一个 int 型的数值,表明该数据中的前面多少个字符将会被使用。例如下面的语句可以被用来设
置控制信息中的电子邮件地址: 

  sess.SetLocalEMail("xiaowp@linuxgam.com",19); 

  在 RTP 会话过程中,不是所有的控制信息都需要被发送,通过调用 RTPSession 类提供的 EnableSendName()、
EnableSendEMail()、EnableSendLocation()、EnableSendPhone()、EnableSendTool() 和 EnableSendNote() 方法
,可以为当前 RTP 会话选择将被发送的控制信息。 

  3.6 实际应用 

  最后通过一个简单的流媒体发送-接收实例,介绍如何利用 JRTPLIB 来进行实时流媒体的编程。清单 3 给出了数据发送端的完整代码,它负责向用户指定的 IP 地址和端口,不断地发送 RTP 数据包: 

  代码清单 3:sender.cpp 


#include  
#include  
#include "rtpsession.h"  

// 错误处理函数 
void checkerror(int err) 
{
   if (err < 0) {     
   char* errstr = RTPGetErrorString(err);     
   printf("Error:%s\\n", errstr);     
   exit(-1);   
   }
}  

int main(int argc, char** argv) 
{
   RTPSession sess;   
   unsigned long destip;   
   int destport;   
   int portbase = 6000;   
   int status, index;   
   char buffer[128];    
   
   if (argc != 3) {     
   printf("Usage: ./sender destip destport\\n");     
   return -1;   
   }    
   
   // 获得接收端的 IP 地址和端口号   
   destip = inet_addr(argv[1]);   
   if (destip == INADDR_NONE) {     
       printf("Bad IP address specified.\\n");     
       return -1;   
   }   
   destip = ntohl(destip);   
   destport = atoi(argv[2]);    
   // 创建 RTP 会话   
   status = sess.Create(portbase);   
   checkerror(status);    
   // 指定 RTP 数据接收端   
   status = sess.AddDestination(destip, destport);   
   checkerror(status);    
   // 设置 RTP 会话默认参数   
   sess.SetDefaultPayloadType(0);   
   sess.SetDefaultMark(false);   
   sess.SetDefaultTimeStampIncrement(10);    
   // 发送流媒体数据   
   index = 1;   
   do {     
       sprintf(buffer, "%d: RTP packet", index   );     
       sess.SendPacket(buffer, strlen(buffer));     
       printf("Send packet !\\n");   
   } while(1);    
   return 0; 
}



  清单 4 则给出了数据接收端的完整代码,它负责从指定的端口不断地读取 RTP 数据包: 

  代码清单 4:receiver.cpp 


#include  
#include "rtpsession.h" 
#include "rtppacket.h"  

// 错误处理函数 
void checkerror(int err) 
{
   if (err < 0) {
       char* errstr = RTPGetErrorString(err);     
       printf("Error:%s\\n", errstr);     
       exit(-1);   
   } 
}  

int main(int argc, char** argv) 
{
   RTPSession sess;   
   int localport;   
   int status;    
   if (argc != 2) {     
       printf("Usage: ./sender localport\\n");     
       return -1;
   }     
   
   // 获得用户指定的端口号   
   localport = atoi(argv[1]);    
   // 创建 RTP 会话   
   status = sess.Create(localport);   
   checkerror(status);    
   do {     
   // 接受 RTP 数据     
   status = sess.PollData();  
   // 检索 RTP 数据源     
   if (sess.GotoFirstSourceWithData()) {       
       do {         
           RTPPacket* packet;         
           // 获取 RTP 数据报         
           while ((packet = sess.GetNextPacket()) != NULL) {           
               printf("Got packet !\\n");           
               // 删除 RTP 数据报           
               delete packet;         
           }       
       } while (sess.GotoNextSourceWithData());     
   } while(1);    
   return 0; 
}  

四、小结   随着多媒体数据在 Internet 上所承担的作用变得越来越重要,需要实时传输音频和视频等多媒体数据
的场合也将变得越来越多,如 IP 电话、视频点播、在线会议等。RTP 是用来在 Internet 上进行实时流媒体传输的
一种协议,目前已经被广泛地应用在各种场合,JRTPLIB 是一个面向对象的 RTP 封装库,利用它可以很方便地完成 
Linux 平台上的实时流媒体编程。 


  流媒体指的是在网络中使用流技术传输的连续时基媒体,其特点是在播放前不需要下载整个文件,而是采用边下载边播放的方式,它是视频会议、IP 电话等应用场合的技术基础。RTP 是进行实时流媒体传输的标准协议和关键技
术,本文介绍如何在 Linux 下利用 JRTPLIB 进行实时流媒体编程。 

  一、流媒体简介 

  随着 Internet 的日益普及,在网络上传输的数据已经不再局限于文字和图形,而是逐渐向声音和视频等多媒体格式过渡。目前在网络上传输音频/视频(Audio/Video,简称 A/V)等多媒体文件时,基本上只有下载和流式传输两
种选择。通常说来,A/V 文件占据的存储空间都比较大,在带宽受限的网络环境中下载可能要耗费数分钟甚至数小时,所以这种处理方法的延迟很大。如果换用流式传输的话,声音、影像、动画等多媒体文件将由专门的流媒体服务器负责向用户连续、实时地发送,这样用户可以不必等到整个文件全部下载完毕,而只需要经过几秒钟的启动延时就可以了,当这些多媒体数据在客户机上播放时,文件的剩余部分将继续从流媒体服务器下载。 

  流(Streaming)是近年在 Internet 上出现的新概念,其定义非常广泛,主要是指通过网络传输多媒体数据的技术总称。流媒体包含广义和狭义两种内涵:广义上的流媒体指的是使音频和视频形成稳定和连续的传输流和回放流的一系列技术、方法和协议的总称,即流媒体技术;狭义上的流媒体是相对于传统的下载-回放方式而言的,指的是一种从 Internet 上获取音频和视频等多媒体数据的新方法,它能够支持多媒体数据流的实时传输和实时播放。通过运用流媒体技术,服务器能够向客户机发送稳定和连续的多媒体数据流,客户机在接收数据的同时以一个稳定的速率回放,而不用等数据全部下载完之后再进行回放。 

  由于受网络带宽、计算机处理能力和协议规范等方面的限制,要想从 Internet 上下载大量的音频和视频数据,无论从下载时 间和存储空间上来讲都是不太现实的,而流媒体技术的出现则很好地解决了这一难题。目前实现流媒体传输主要有两种方法:顺序流(progressive streaming)传输和实时流(realtime streaming)传输,它们分别适合于不同的应用场合。 

  顺序流传输 

  顺序流传输采用顺序下载的方式进行传输,在下载的同时用户可以在线回放多媒体数据,但给定时刻只能观看已经下载的部分,不能跳到尚未下载的部分,也不能在传输期间根据网络状况对下载速度进行调整。由于标准的 HTTP 服务器就可以发送这种形式的流媒体,而不需要其他特殊协议的支持,因此也常常被称作 HTTP 流式传输。顺序流式传输比较适合于高质量的多媒体片段,如片头、片尾或者广告等。 

  实时流传输 

  实时流式传输保证媒体信号带宽能够与当前网络状况相匹配,从而使得流媒体数据总是被实时地传送,因此特别适合于现场事件。实时流传输支持随机访问,即用户可以通过快进或者后退操作来观看前面或者后面的内容。从理论上讲,实时流媒体一经播放就不会停顿,但事实上仍有可能发生周期性的暂停现象,尤其是在网络状况恶化时更是如此。与顺序流传输不同的是,实时流传输需要用到特定的流媒体服务器,而且还需要特定网络协议的支持。 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -