Fau*_*o70 7 java android voip datagram rtp
我的目标是在GSM/UMTS/LTE网络中建立一个即按即说聊天应用程序; 最初我想使用多播地址和点对点而不会使服务器过载; 不幸的是,经过深入调查,我发现GSM/UMTS/LTE网络中不允许多播,因此我必须使用服务器来反弹VoIP数据包.我不太喜欢这个解决方案,因为我不得不重载服务器,但我找不到更好的解决方案.如果你有一个替代解决方案非常适应...
因此,我必须将VoIP从Android客户端发送到服务器(PC),反之亦然.服务器是Java,它必须接收VoIP数据包然后将VoIP数据包发送到其他N个客户端; 服务器是VoIP数据包的保护者.
我开发了代码,但它不起作用; 我没有任何错误,只是我有非常糟糕的VoIP服务:我丢失了很多碎片,我听到的是非常多的声音......错误在哪里?我想它应该在服务器代码中; 服务器只需获取数据包并重新发送,而不知道它们是RTP上的VoIP.
如下请见
先谢谢你,福斯托
//使用ANDROID代码向服务器发送VOIP
//Attribute definition
private static final AudioCodec myAudioCodec_COSTANTE = AudioCodec.PCMU ;
private static final int myAudioGroupTX_COSTANTE = AudioGroup.MODE_NORMAL ;
private static final int myAudioGroupRX_COSTANTE = AudioGroup.MODE_NORMAL ;
private static final int myRtpStreamTX_COSTANTE = RtpStream.MODE_SEND_ONLY ;
private static final int myRtpStreamRX_COSTANTE = RtpStream.MODE_RECEIVE_ONLY ;
private static final int myAudioManagerTX_COSTANTE = AudioManager.MODE_IN_COMMUNICATION;
private static final int myAudioManagerRX_COSTANTE = AudioManager.MODE_IN_COMMUNICATION;
//Method called for VoIP trasmission
myAudioStream = new AudioStream(localClientIP);
myAudioGroup = new AudioGroup();
myAudioManager = (AudioManager) myContext.getSystemService(Context.AUDIO_SERVICE);
myAudioGroup.setMode(myAudioGroupTX_COSTANTE);
myAudioStream.join(null);
myAudioStream.setCodec(myAudioCodec_COSTANTE);
myAudioStream.setMode(myRtpStreamTX_COSTANTE);
myAudioStream.associate(ipaddress_Server, port_Server)
myAudioStream.join(myAudioGroup);
myAudioManager.setMode(myAudioManagerTX_COSTANTE);
myAudioManager.setSpeakerphoneOn(false);
myAudioManager.setMicrophoneMute(false);
Run Code Online (Sandbox Code Playgroud)
// JAVA服务器代码用于接收来自Android的VOIP并将其重新发送给服务器
DatagramSocket datagramSocket_RX_VoIP= new DatagramSocket();
DatagramSocket datagramSocket_TX_VoIP= new DatagramSocket();
int unicast_port_TX_VoIP = 5000 ;
String unicast_ip_TX_VoIP = "192.168.0.3";
Thread t = new Thread(new Runnable() {
public void run() {
try {
DatagramPacket myPacket;
while (true) {
myPacket = ManagePacket.initializePacket(); //Function to prepare the packe ; the problem is not here!!!
datagramSocket_RX_VoIP.receive(myPacket);
InetAddress ppp = InetAddress.getByName(unicast_ip_TX_VoIP);
myPacket.setAddress(ppp);
myPacket.setPort( unicast_port_TX_VoIP ) ;
datagramSocket_TX_VoIP.send(myPacket);
}
} catch (Exception ex) {
log.debug("Exception: " + ex.getMessage(), ex);
}
}
});
t.start();
Run Code Online (Sandbox Code Playgroud)
jay*_*ers 10
您没有提供有关您的申请的足够详细信息.使用任何UDP流应用程序,您需要解决以下问题:
网络抖动和缓冲:当数据包到达时,您无法在收到数据后立即播放音频,因为下一个数据包可能比预期的要晚,并且您的音频播放会有间隙.到达率的变化称为网络抖动.在尝试播放之前,您需要缓冲一些数据量.通常你使用某种环形缓冲区.
数据包丢失:UDP会丢包.你需要"处理"这个.如果您发送10个数据包且数据包#4丢失,则无法播放数据包#3,然后播放数据包#5.听起来不错.解决这个问题的方法:
音频流不是一项微不足道的任务.你不能只是打开一个套接字,发送数据,并在另一端播放它,并期望它能够工作.您对UDP流的最大担忧是网络抖动和数据包丢失.如果您不想处理损失并且可能会有一些额外的延迟,请使用TCP,但请确保在开始播放之前缓冲足够的音频.
| 归档时间: |
|
| 查看次数: |
2753 次 |
| 最近记录: |