【发布时间】:2017-12-06 19:12:27
【问题描述】:
我是 VoIP 新手。我想创建一个使用 RTP 使用客户端/服务器架构流式传输音频的应用程序。有不同的 API 可用但我需要了解核心级别。我研究过 RFC。谁能建议我如何制作音频 RTP 数据包并将其与 JAVA 中的数据包解包一起发送到服务器。 提前致谢。
【问题讨论】:
-
我已经成功实现了。如果有人想要我的代码,请随时通过电子邮件与我联系。 suleman748@gmail.com
我是 VoIP 新手。我想创建一个使用 RTP 使用客户端/服务器架构流式传输音频的应用程序。有不同的 API 可用但我需要了解核心级别。我研究过 RFC。谁能建议我如何制作音频 RTP 数据包并将其与 JAVA 中的数据包解包一起发送到服务器。 提前致谢。
【问题讨论】:
创建一个空的 Java 类。
为 RTP 标头中的所有字段添加成员。对单个位字段使用 bool。对于数字字段,您需要注意需要多少位,即使用 int 表示 SSRC,使用时间戳、序列的缩写、有效负载类型的字节等。CSRC 应该是整数的数组(或 arrayList 或其他) .音频负载应该是一个字节数组。
数据包只是字节数组,因此您需要一个 ToBytes() 方法来输出数据包 byte[],以及一个将 byte[] 作为参数的构造函数。要发送数据包,请调用 ToBytes() 并将结果放入 UDP 数据包中。
在您的 ToBytes() 方法中,创建一个 12 字节的字节数组,加上每个 CSRC 的额外 4 字节,再加上音频负载中的字节数。
您需要使用按位或运算符设置单个位值。例如,Marker 位是第二个字节的第一位,所以要设置它:
if(marker)
{
bytes[1] = bytes[1] | 0x80; //0x80 is 1000 0000
}
要设置整数或短整数值,您需要将值转换为网络顺序(双序)字节数组,然后使用 arraycopy 将其设置在缓冲区中。我将由您来了解如何创建网络顺序字节数组。
对于采用 byte[] 的构造函数,您需要反向执行上述过程。要检查单个位的值,请使用 AND 运算符,例如:
marker = bytes[1] & 0x80 == 1;
在此类或辅助类中,您可能需要一些方法来帮助根据数据包计数和采样率设置时间戳。比如payload是G.711,就是8000个样本/秒,也就是说每20ms发送一个包,payload是160字节,所以每包时间戳会增加160。
【讨论】: