jrtplib介绍[通俗易懂]

jrtplib介绍[通俗易懂]程序流程发送:获得接收端的IP地址和端口号创建RTP会话指定RTP数据接收端设置RTP会话默认参数发送流媒体数据接收:获得用户指定的端口号创建RTP会话设置接收模式接受RTP数据检索RTP数据源获取RTP数据报删除RTP数据报1.初始化I、在使用JRTPLIB进行实时流媒体数据传输之前,首先应该生成R…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

程序流程
发送:获得接收端的 IP 地址和端口号        创建 RTP 会话        指定 RTP 数据接收端 设置 RTP 会话 默认参数   发送流媒体数据
接收:获得用户指定的端口号  创建RTP会话  设置接收模式  接受RTP数据  检索RTP数据源  获取RTP数据报 删除RTP数据报

1.初始化

I、在使用 JRTPLIB 进行实时流媒体数据传输之前,首先应该生成 RTPSession 类的一个实例来表示此次 RTP会话,然后调用 Create() 方法来对其进行初始化操作。RTPSession 类的 Create() 方法只有一个参数,用来指明此次 RTP 会话所采用的端口号。

RTPSession sess;  
sess.Create(5000);

JRTPLIB-3.11中已经修改了Create(prot)方法。新的Create方法被修改为Create(sessparams,&transparams)。其中的两个参数需要如下先定义:

RTPUDPv4TransmissionParams transparams;
RTPSessionParams sessparams;

sessparams.SetOwnTimestampUnit(1.0/8000.0);/*设置时间戳,1/8000表示1秒钟采样8000次,即录音时的8KHz*/

sessparams.SetAcceptOwnPackets(true);

transparams.SetPortbase(portbase);/*本地通讯端口*/

II、设置恰当的时戳单元,是 RTP 会话初始化过程所要进行的另外一项重要工作,这是通过调用 RTPSession类的 SetTimestampUnit() 方法来实现的,前面已经提过。

 

2.数据发送

I、当 RTP 会话成功建立起来之后,接下去就可以开始进行流媒体数据的实时传输了。首先需要设置好数据发送的目标地址,RTP 协议允许同一会话存在多个目标地址,这可以通过调用 RTPSession 类的AddDestination()、DeleteDestination() 和 ClearDestinations() 方法来完成。例如,下面的语句表示的是让 RTP 会话将数据发送到本地主机的 6000 端口:

unsigned long addr = ntohl(inet_addr("127.0.0.1")); 
sess.AddDestination(addr, 6000);

II、目标地址全部指定之后,接着就可以调用 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的说明文档。

 

3.数据接收

对于流媒体数据的接收端,首先需要调用 RTPSession 类的 PollData() 方法来接收发送过来的 RTP 或者RTCP 数据报。

JRTPLIB-3.11中修改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();            // 处理接收到的数据    
           delete pack;   } 
 while (sess.GotoNextSourceWithData()); 
 }

完整的代码中,首先需调用Poll()方法接收RTP数据报,然后在BeginDataAccess()和EndDataAccess()之间进行数据接收的操作。此时,我们设定程序一直do-while等待并处理数据

do{

#ifndef RTP_SUPPORT_THREAD
                error_status = sess_client.Poll();
                checkerror(error_status);
#endif // RTP_SUPPORT_THREAD
                sess_client.BeginDataAccess();

                // check incoming packets
                if (sess_client.GotoFirstSourceWithData())
                {
                         printf("Begin play/n");
                        do
                        {
                                RTPPacket *pack;

                                while ((pack = sess_client.GetNextPacket()) != NULL)
                                {
                                        // You can examine the data here
                                        printf("Got packet !/n");
                                        timestamp1 = pack->GetTimestamp();
                                        lengh=pack->GetPayloadLength();
                                        RawData=pack->GetPayloadData();   //得到数据

printf("  timestamp: %dlengh=%d/n",timestamp1,lengh);


                                            int fd = open("/dev/dsp", O_RDWR);
                                            int status = write(fd, RawData,lengh );
                                            printf("Play bytes:%d/n",status);
                                            if (status != lengh)
                                              perror("wrote wrong number of bytes");

                                            status = ioctl(fd, SOUND_PCM_SYNC, 0);
                                            if (status == -1)
                                            perror("SOUND_PCM_SYNC ioctl failed");
                                            printf("Play end/n");
                                             close(fd);
                                        sess_client.DeletePacket(pack);

                                }
                        } while (sess_client.GotoNextSourceWithData());
                         //return 0;

                }

                sess_client.EndDataAccess();
            }while(1);

说明 : jrtp-3.x 中有两种数据接收方式:

第一种是用 jthread 库提供的线程自动在后台执行对数据的接收。

第二种是用户自己调用 RTPSession 中的 Poll 方法。

如果采取第一种方法则要安装 jthread 库,则安装 jthread-1.x.tar.gz ,而且 jthread-1.x 必须先与 jrtp-3.x 的安装。因为在 jrtp-3.x 的 configure 中,会查找系统是否有编译了 jthread 库,如果有,那么编译的 jrtp 库会开启对 jthread 的支持。因此如果先编译jrtp 在编译 jthread ,编译出来的 jrtp 是没有开启对 jthread 的支持的。如果采用第二种方法,那么可以不用编译 jthread 库,而直接编译 jrtp 库。

 

可以加入环境变量 export LD_LIBRARY_PATH=/XXX/lib,避免将所有lib都放入/usr下

./ example

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/164744.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 计算广告概述【计算广告】

    计算广告概述【计算广告】

  • networkmanager设置开机启动_network connectivity assistant

    networkmanager设置开机启动_network connectivity assistant通常的linux发行版对于网络的配置方法一般会同时支持network.service(即配置和使用/etc/sysconfig/network-scripts/下的配置文件来配置网络,对于ubuntu是/etc/network/interfaces等等)和NetworkManager.service(简称NM)。默认情况下,这2个服务都有开启,而且功能上是平行的,可以通过任意一个来配置网络,正常的情况下通过NM来配置网络后它会自动把配置同步到network.service的配置中。NM能管理各种网络

  • Levels – 虚幻引擎场景制作「建议收藏」

    Levels – 虚幻引擎场景制作「建议收藏」个人制作的一个UE4场景,虚幻引擎4相关,3D场景制作相关,LA工作流程相关;文档所附视频展示:https://zhuanlan.zhihu.com/p/56903372

  • ubuntu安装qt5.12_ubuntu安装分区

    ubuntu安装qt5.12_ubuntu安装分区下载Qt安装包官网下载速度较慢,可以从国内镜像下载。清华大学:https://mirrors.tuna.tsinghua.edu.cn/qt/中国科学技术大学:http://mirrors.ustc.edu.cn/qtproject/中国互联网络信息中心:https://mirrors.cnnic.cn/qt/安装包名称:qt-opensource-linux-x64-5.14.2.run./qt-opensource-linux-x64-5.14.2.run安装好后需要一些配置才能开始开发

    2022年10月15日
  • at24c02模块怎么用_AI8C模块参数

    at24c02模块怎么用_AI8C模块参数AT24C02模块概述:  该文主要描述了,AT24C02简介、AT24C02特性、硬件原理图、管脚描述、从器件地址、写周期限制、读写操作时序。1、AT24C02简介  AT24C01/02/04/08/16是一个1K/2K/4K/8K/16K位(AT24C02大小为256字节)串行CMOSE2PROM内部含有128/256/512/1024/2048个8位字节,CATALYST公…

    2022年10月29日
  • rj45管脚定义_rj45接口定义,rj45插座引脚定义

    RJ45是布线系统中信息插座(即通信引出端)连接器的一种,连接器由插头(接头、水晶头)和插座(模块)组成,插头有8个凹槽和8个触点。RJ是RegisteredJack的缩写,意思是“注册的插座”。在FCC(美国联邦通信委员会标准和规章)中RJ是描述公用电信网络的接口,计算机网络的RJ45是标准8位模块化接口的俗称。rj45插座引脚定义:常见的RJ45接口有两类:用于以太网网卡、路由器以太网接口等…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号