当前位置: 首页 > 面试题库 >

VoIP RTP从/到服务器(在Java中)与android的流传输

齐锐进
2023-03-14
问题内容

我的目标是在GSM / UMTS /
LTE网络中建立一键通聊天应用程序;最初,我想使用多播地址和对等网络而不会使服务器过载。不幸的是,经过深入的调查,我发现GSM / UMTS /
LTE网络中不允许组播,因此我必须使用服务器来退回VoIP数据包。我不太喜欢这种解决方案,因为我必须使服务器超载,但是没有找到更好的解决方案。如果您有替代解决方案,将非常感激…

因此,我必须将VoIP从Android客户端发送到服务器(PC),反之亦然。服务器采用Java语言,必须先接收VoIP数据包,然后再将VoIP数据包发送到其他N个客户端。服务器是VoIP数据包的保镖。

我开发了代码,但是没有用;我没有任何错误,只是我的VoIP服务非常差:我松了很多东西,听到的​​声音非常杂乱……错误在哪里?我想它应该在服务器代码中;服务器只是获取数据包并重新发送它们,而不知道它们是RTP上的VoIP。

如下请见

  • 我用来将VoIP数据包发送到服务器的代码。之所以起作用,是因为我将其用于直接从Android到Android发送VoIP数据包的个人呼叫时没有问题;在android中接收来自服务器的数据包的代码非常相似,因此我不会重新复制它。如您所见,我使用android.net.rtp。
  • 我在Java服务器上用来退回VoIP数据包的代码

预先谢谢你,福斯托

//用于将VOIP发送到服务器的ANDROID代码

//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);

// 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();

问题答案:

您没有提供有关您的应用程序的足够详细信息。对于任何UDP流应用程序,您需要解决以下问题:

  • 网络抖动和缓冲:数据包到达后,您将无法在收到音频后立即播放音频,因为下一个数据包可能会晚于预期的时间,并且音频播放中会有间隙。到达速率的变化称为网络抖动。在尝试播放之前,您需要缓冲一些数据。通常,您使用某种环形缓冲区。

  • 数据包丢失:UDP会造成数据包丢失。您需要与此“交易”。如果发送10个数据包,但缺少数据包#4,则无法播放数据包#3,然后再播放数据包#5。听起来不好。处理方法:

    • 隐蔽性丢失:尽量减少丢失数据包的不良影响。您可以演奏静音(尽管听起来最好,除非您将其淡化为静音)。您可以通过检查周围的数据包来生成丢失的音频,从而“估计”丢失的音频。
    • 前向纠错:多次发送数据包。有许多方法和方案。代价是更高的延迟和更多的网络利用率
    • 乱序到达:数据包可能乱序到达。使用RTP序列号来处理此问题。

音频流不是一件容易的事。您不能只是打开一个套接字,发送数据并在另一端播放它并期望它能正常工作。UDP流最大的问题是网络抖动和数据包丢失。如果您不想处理损失,并且可能会有一些额外的延迟,请使用TCP,但一定要在开始播放之前缓冲足够的音频。



 类似资料:
  • 问题内容: 我目前正在尝试将直播麦克风音频从Android设备流式传输到Java程序。我首先在两个Android设备之间发送实时音频,以确认我的方法正确。在接收设备上几乎没有任何延迟地可以完美地听到音频。接下来,我将相同的音频流发送到一个小型Java程序,并验证了数据也已正确发送到此处。现在,我想要做的是对这些数据进行编码,并以某种方式在运行Java程序的服务器上对其进行回放。我宁愿在使用HTML

  • 问题内容: 我想将录制的音频从浏览器实时流传输到服务器并播放。该服务器最终将成为播放这些音频流的嵌入式设备。 到目前为止,我已经成功地录制了音频并将其编码为WAVE文件,并使用网络音频API并按照本教程在浏览器上播放。 现在,我有了.WAV编码的Blob流。我试图找到通过Web套接字连接将其流式传输到Node.js后端并使用npm模块播放它们的方法。但是我没有运气。 有人知道我应该遵循的任何资源或

  • 问题内容: 我正在尝试从Android设备将文件上传到php服务器。有相同问题的话题,但他使用的是不同的方法。我的Android辅助代码运行正常,并且未显示任何错误消息,但服务器未收到任何文件。这是我的示例代码,我在网上找到了。 和我的PHP服务器端代码如下 Apache正在运行。当我运行服务器时,出现此错误消息。上传文件时出错,请重试!我已经在eclipse中检查了日志数据,我认为是套接字问题,

  • 我正试图从我的android设备上传文件到php服务器,但服务器没有收到任何文件。这是我的示例代码,我在网上找到的。php服务器,我正在通过chunk上传文件 我的Android代码 PHP Server文件上传中的代码,我是通过块完成文件上传的,请谁帮我发送正确的代码文件通过块上传和相关的android文件上传代码

  • 问题内容: 我正在尝试将文件从我的Android设备上传到php服务器,但服务器未收到任何文件。这是我的示例代码,我在线找到了。php服务器,我正在通过块上传文件 我的Android代码 PHP Server代码在文件上传中,我已经完成了通过块进行文件上传,请有人帮助我通过块和相关的android文件上传代码发送正确的代码文件 问题答案: 我不知道您的代码,但是为您提供了两个有效的代码:这适用于所

  • 问题内容: 我一直在使用Node.js中的二进制流进行实验,但令我惊讶的是,确实有一个工作演示,它使用节点无线电流获取Shoutcast流,并使用分块编码将其推入HTML5元素。但这仅适用于Safari! 这是我的服务器代码: 我的客户代码很简单: 这在Mac上的Safari 5中可以正常运行,但在Chrome或Firefox中似乎无法执行任何操作。有任何想法吗? 可能的候选对象包括编码问题,或者