Android端做RTP实时发送音频数据实现

       如果你也在Android端做RTP发送数据的话,通过网上查找资料,相信你不难发现,在使用RTP/RTCP协议发送数据是有现成的库进行调用的,Jlibrtp这个库就是Java实现的,但是这个库是没有说明文档的,比较抠脚,而且百度谷歌找到例子又很少,基本上都没什么卵用;一般搜到都是Jrtplib库,这是C实现库,对我们没多大用,除非你愿意先研究这个库的RTP实现,在用JNI调用,明显更蛋疼。这个没文档就只能自己瞎倒腾一下,还好勉强倒腾出来了。

       首先,你必须下一个Jlibrtp库:https://download.csdn.net/download/jwq1220/10355482 里面包含Jlibrtp的实现和java调用的Demo。

       下完后,新建一个Android工程,将Jlibrtp-0.2.2中的jlibrtp文件夹中的所有.java文件导入工程,全丢到一个新建的jlibrtp包里面,准备工作算是完成,在需要地方直接import这个包,就可以使用了。

demo中标已经将源码打包成jar形式可以直接使用,也可以通过上面链接下载最新的C库和java库。C库中包含demo亲测在linux上面机器间通讯正常

Android端做RTP实时发送音频数据实现_第1张图片

简单整理一下Jlibrtp实现RTP的过程:

1、首先建立收发端的会话,调用Jlibrtp库的实时传输会话类RTPSession,该类可以创建一个RTP会话,并设置传输的RTP端口和RTCP端口,以及与RTP包的相关的时间戳数据等。

2、然后通过RTPSessionRegister方法用于添加RTP会话的参与者,同时开启接收包的AppCallerThread线程类,其run方法调用回调函数receiveData,才开始接收RTP包,receiveData函数会去掉RTP包头,直接将RTP负载存入缓存,之后再进行分包的判断。

Android端做RTP实时发送音频数据实现_第2张图片

具体实现过程如下:

1、InitSession.java类初始化会话基础参数,设置目标IP及RTP端口号和RTCP端口号等;

数据发送和接收需要分包来处理,这里没有贴出来,demo中有完整的分包发送和接收的处理以及数据同步的多线程实现

 

[java] view plain copy

  1. package com.eric.androidrtpsenddata;  
  2. import java.net.DatagramSocket;  
  3. import java.net.InetSocketAddress;  
  4.   
  5.   
  6. import jlibrtp.*;  
  7.  
  8. public class InitSession implements RTPAppIntf{  
  9.     public RTPSession rtpSession = null;  
  10.       
  11.     public InitSession() {  
  12.         DatagramSocket rtpSocket = null;  
  13.         DatagramSocket rtcpSocket = null;  
  14.           
  15.         try {  
  16.             rtpSocket = new DatagramSocket(8002);  
  17.             rtcpSocket = new DatagramSocket(8003);  
  18.         } catch (Exception e) {  
  19.             System.out.println("发送创建会话异常抛出:"+e);  
  20.         }  
  21.           
  22.         //建立会话  
  23.         rtpSession = new RTPSession(rtpSocket, rtcpSocket);  
  24.         rtpSession.RTPSessionRegister(this,null,null);  
  25.         //设置参与者(目标IP地址,RTP端口,RTCP端口)  
  26.         Participant p = new Participant("192.168.226.116"80048005);  
  27.         rtpSession.addParticipant(p);  
  28.     }  
  29.       
  30.     public void receiveData(DataFrame frame, Participant p){  
  31.         String s = new String(frame.getConcatenatedData());  
  32.         System.out.println("接收到数据: "+s+" , 参与者CNAME: "  
  33.                 +p.getCNAME()+"同步源标识符("+p.getSSRC()+")");  
  34.     }  
  35.   
  36.       
  37.     public void userEvent(int type, Participant[] participant) {  
  38.         // TODO Auto-generated method stub  
  39.     }  
  40.   
  41.       
  42.     public int frameSize(int payloadType) {  
  43.         return 1;  
  44.     }  
  45. }  

 

 

2、MainActivity.java中发送数据;其中数据发送部分demo中做了修改数据来自真实的音频数据采集,采用AudioRecod,接收端采用AudioPlay来播放发送客户端采集来的实时音频数据,达到语音通话的效果。测试效果还不错。

以下是别人写的,下面demo下载中与下面是不一致的,完实际demo已经完全按照实际sdk的要求进行了封装,解决了大数据实时发送和接收的问题。有兴趣的可以自行下载。也可以操作以下简单例子的实现自行实现。

 

[java] view plain copy

  1. package com.eric.androidrtpsenddata;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5.   
  6.  
  7. public class MainActivity extends Activity{  
  8.        
  9.      @Override  
  10.         protected void onCreate(Bundle savedInstanceState) {  
  11.             super.onCreate(savedInstanceState);  
  12.             setContentView(R.layout.activity_main);   
  13.               
  14.             /*Thread receiveThread = new Thread(new Runnable() { 
  15.                 @Override 
  16.                 public void run() { 
  17.                     try { 
  18.                         receiveData(); 
  19.                     } catch (Exception e) { 
  20.                         e.printStackTrace(); 
  21.                         System.out.println("RTP接收数据异常:"+e); 
  22.                     } 
  23.                 } 
  24.             }); 
  25.             receiveThread.start();*/  
  26.               
  27.             Thread sendThread = new Thread(new Runnable() {  
  28.                 @Override  
  29.                 public void run() {  
  30.                     try {  
  31.                         openSession();  
  32.                     } catch (Exception e) {  
  33.                         e.printStackTrace();  
  34.                         System.out.println("RTP发送数据异常:"+e);  
  35.                     }  
  36.                 }  
  37.             });  
  38.             sendThread.start();  
  39.               
  40.         }  
  41.        
  42.      //Jlibrtp开启会话发送数据  ,这里的伪代码,实际demo中的代码输入的实时流通过MIC采集的数据然后分包发送给服务端
  43.      public void openSession(){  
  44.         InitSession test = new InitSession();  
  45.         long teststart = System.currentTimeMillis();  
  46.         String str = "abce abcd abce abce abce abcd abcd abce " +  
  47.                 "abcd abce abcd abce abcd abce abcd abce abcd abce " +  
  48.                 "abcd abce abcd abce abcd abce abcd abce abcd abce abcd " +  
  49.                 "abce abcd abce abcd abce abcd abce abcd abce abcd abce " +  
  50.                 "abcd abce abcd abce abcd abce abcd abce abcd abce abcd " +  
  51.                 "abce abcd abce abcd abce abcd abce abcd abce abcd abce " +  
  52.                 "abcd abce abcd abce abcd abce abcd abce abcd abce abcd " +  
  53.                 "abce abcd abce abcd abce abcd abce abcd abce abcd abce " +  
  54.                 "abcd abce abcd abce abcd abce abcd abce abcd abce abcd " +  
  55.                 "abce abcd abce abcd abce abcd abce abcd abce abcd abce " +  
  56.                 "abcd abce abcd abce abcd abce abcd abce abcd abce abcd " +  
  57.                 "abce abcd abce abcd abce abcd abce abcd ";  
  58.         byte[] data = str.getBytes();  
  59.         System.out.println(data.length);  
  60.         int i=0;  
  61.         while(i
  62.                 System.out.println("已发送第"+i+"个字节数组:"+data);  
  63.                 test.rtpSession.sendData(data);  
  64.                 i++;  
  65.         }  
  66.   
  67.         long testend = System.currentTimeMillis();  
  68.           
  69.         System.out.println("发送用时:" + (testend - teststart));  
  70.         System.out.println("结束时间:" + testend);  
  71.         System.out.println("开始时间:" + teststart);  
  72.      }  
  73.        
  74.      public void receiveData(){  
  75.          ReceiveData receive = new ReceiveData();  
  76.      }  
  77.           
  78. }  

例子Demo运行结果:

 


 

附上SDK地址:https://download.csdn.net/download/jwq1220/12088825

SDK是源码基于android studio编码的里面包含客户端和服务端的封装

用法如下:

  ServerManager serverManager = new ServerManager ();

  serverManager.setMode(ServerManager.SEVER);//如果是客户此处配置需要改为ServerManager.CLIENT
  serverManager.setRunning(true);
  serverManager.setRecording(true);

 

这个是没有封装的很早写的demo,上的例子都在这个demo里面:

https://download.csdn.net/download/jwq1220/10355482

 

你可能感兴趣的:(rtp)