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上面机器间通讯正常

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

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

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

具体实现过程如下:

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);  
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
这是一个比较复杂的问题,需要涉及到很多方面的知识。以下是一个简单的示例代码,供参考: 发送代码: ```java public class H264Sender { private DatagramSocket rtpSocket; private DatagramSocket rtcpSocket; private InetAddress address; private int port; private int sequenceNumber; private int timestamp; private final int payloadType = 96; public H264Sender(String ip, int port) throws SocketException, UnknownHostException { this.port = port; this.address = InetAddress.getByName(ip); rtpSocket = new DatagramSocket(); rtcpSocket = new DatagramSocket(); } public void send(byte[] data) throws IOException { int length = data.length; // RTP Header byte[] rtpHeader = new byte[12]; rtpHeader[0] = (byte) (0x80 | payloadType); rtpHeader[1] = (byte) 0x80; rtpHeader[2] = (byte) ((sequenceNumber >> 8) & 0xFF); rtpHeader[3] = (byte) (sequenceNumber & 0xFF); rtpHeader[4] = (byte) ((timestamp >> 24) & 0xFF); rtpHeader[5] = (byte) ((timestamp >> 16) & 0xFF); rtpHeader[6] = (byte) ((timestamp >> 8) & 0xFF); rtpHeader[7] = (byte) (timestamp & 0xFF); rtpHeader[8] = (byte) ((System.currentTimeMillis() >> 24) & 0xFF); rtpHeader[9] = (byte) ((System.currentTimeMillis() >> 16) & 0xFF); rtpHeader[10] = (byte) ((System.currentTimeMillis() >> 8) & 0xFF); rtpHeader[11] = (byte) (System.currentTimeMillis() & 0xFF); // RTP Packet byte[] rtpPacket = new byte[length + rtpHeader.length]; System.arraycopy(rtpHeader, 0, rtpPacket, 0, rtpHeader.length); System.arraycopy(data, 0, rtpPacket, rtpHeader.length, length); // Send RTP Packet DatagramPacket rtpPacketToSend = new DatagramPacket(rtpPacket, rtpPacket.length, address, port); rtpSocket.send(rtpPacketToSend); // RTCP Packet byte[] rtcpPacket = new byte[8]; rtcpPacket[0] = (byte) 0x80; rtcpPacket[1] = (byte) 0xC9; rtcpPacket[2] = (byte) 0x00; rtcpPacket[3] = (byte) 0x06; rtcpPacket[4] = (byte) ((sequenceNumber >> 8) & 0xFF); rtcpPacket[5] = (byte) (sequenceNumber & 0xFF); rtcpPacket[6] = (byte) ((length >> 8) & 0xFF); rtcpPacket[7] = (byte) (length & 0xFF); // Send RTCP Packet DatagramPacket rtcpPacketToSend = new DatagramPacket(rtcpPacket, rtcpPacket.length, address, port + 1); rtcpSocket.send(rtcpPacketToSend); sequenceNumber++; timestamp += 90000 / 30; // 30 fps } public void close() { rtpSocket.close(); rtcpSocket.close(); } } ``` 接收代码: ```java public class H264Receiver { private DatagramSocket rtpSocket; private DatagramSocket rtcpSocket; private InetAddress address; private int port; public H264Receiver(String ip, int port) throws SocketException, UnknownHostException { this.port = port; this.address = InetAddress.getByName(ip); rtpSocket = new DatagramSocket(port); rtcpSocket = new DatagramSocket(port + 1); } public byte[] receive() throws IOException { byte[] buffer = new byte[65536]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port); rtpSocket.receive(packet); return Arrays.copyOfRange(packet.getData(), packet.getOffset() + 12, packet.getLength()); } public void close() { rtpSocket.close(); rtcpSocket.close(); } } ``` 这个示例代码简单实现了H264视频流的实时发送和接收。具体实现过程中还需要考虑一些其他的问题,比如: - H264编解码实现 - RTP和RTCP协议中其他字段的处理 - 码率控制和带宽限制 - 防止丢包和重传机制 因此,这个示例代码只是一个简单的参考,实际应用中需要根据具体需求进行相应的修改和优化。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深宫大院

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值