没有SIP的PTT的Android聊天VoIP - 多播,AudioStream,Audiogroup无法正常工作

时间:2015-03-31 07:55:33

标签: android chat voip audio-streaming multicast

我的目标是用于与PTT进行VoIP聊天的Android应用程序(按键通话)。 由于PTT(一个Android设备说话,其他N个Android设备听),我需要多播地址。我认为正确的解决方案是RTP。 由于几个原因,我无法使用SIP;不幸的是,WEB上的所有代码示例都是由SIP完成的。 在下面我写的代码,但它不起作用;我测试了2个设备(一个接收和另一个传输)但我听不到任何声音。 为什么?问题是多播IP? 首先,我将非常感谢使用我的下面代码的解决方案;如果它不可用,我将不胜感激任何有关其他解决方案/类/等的建议......以及示例代码以获得我的目标(聊天PTT不使用SIP)

我的代码如下: 首先是“RTP_VoIP_Manager”类,其中实现了2种接收和发送方法。 在一段简单的代码之后,我用它来调用活动中的2个方法。 先感谢您 福斯托

public class RTP_VoIP_Manager
{

private static final String tag="RTP_VoIP_Manager";
private AudioStream audioStream;
private AudioGroup audioGroup;
private Context myContext;
private int localPort;
private InetAddress clientIP;
private InetAddress multicastIPInetAddress;
private static String multicastIP;
private static int multicastPort;

public RTP_VoIP_Manager(String multicastIPArg, int multicastPortArg)   {
    try {
        myContext= BaseActivity.get_myContext();
        clientIP= FunctionsAndParameters.getClientIP();
        audioGroup = new AudioGroup();
        audioGroup.setMode(AudioGroup.MODE_NORMAL);
        audioStream = new AudioStream(clientIP);
        this.multicastIP = multicastIPArg ;
        this.multicastPort = multicastPortArg ;
        this.multicastIPInetAddress =InetAddress.getByName(multicastIP);

    }
    catch (SocketException ex) { Log.e(tag, "Eccezione sul try; SocketException: "+ ex.getMessage(), ex);}
    catch (Exception ex) { Log.e(tag, "Eccezione sul try; Exception: "+ ex.getMessage(), ex); }

}

public void receive_RTP_VoIP( ) {
    try {
        audioStream.join(null); // altrimenti dà errore (java.lang.IllegalStateException: Busy)
        audioStream.setCodec(AudioCodec.PCMU);
        audioStream.setMode(RtpStream.MODE_RECEIVE_ONLY);
        audioStream.associate(multicastIPInetAddress, multicastPort);
        audioStream.join(audioGroup);
        AudioManager Audio =  (AudioManager) myContext.getSystemService(Context.AUDIO_SERVICE);
        Audio.setMode(AudioManager.MODE_IN_COMMUNICATION);
        Audio.setSpeakerphoneOn(true);
        Audio.setMicrophoneMute(false);
        Log.d(tag, "Avviata Ricezione in chiamata di gruppo - Nome Thread: " + Thread.currentThread().getName());

        HeaderFragmentManager.setIsTrasmittingInGroupCall(false);
        HeaderFragmentManager.setIsReceivingInGroupCall(true);
    }
    catch (UnknownHostException ex) { Log.e(tag, "Eccezione sul try; UnknownHostException: "+ ex.getMessage(), ex); }
    catch (Exception ex) { Log.e(tag, "Eccezione sul try; Exception: "+ ex.getMessage(), ex); }
}

public void transmit_RTP_VoIP() {
    try {
        audioStream.join(null); // altrimenti dà errore (java.lang.IllegalStateException: Busy)
        audioStream.setCodec(AudioCodec.PCMU);
        audioStream.setMode(RtpStream.MODE_SEND_ONLY);
        audioStream.associate(multicastIPInetAddress, multicastPort);
        audioStream.join(audioGroup);
        AudioManager Audio =  (AudioManager) myContext.getSystemService(Context.AUDIO_SERVICE);
        Audio.setMode(AudioManager.MODE_IN_COMMUNICATION);
        Audio.setSpeakerphoneOn(false);
        Audio.setMicrophoneMute(true);
        Log.d(tag, "Avviata Trasmissione in chiamata di gruppo - Nome Thread: " + Thread.currentThread().getName());

        HeaderFragmentManager.setIsTrasmittingInGroupCall(true);
        HeaderFragmentManager.setIsReceivingInGroupCall(false);
    }
    catch (UnknownHostException ex) { Log.e(tag, "Eccezione sul try; UnknownHostException: "+ ex.getMessage(), ex); }
    catch (Exception ex) { Log.e(tag, "Eccezione sul try; Exception: "+ ex.getMessage(), ex); }
}



}

在活动中(例如传播):

                    Thread t = new Thread(new Runnable() {
                        public void run() {
                            try { myNativeClass.transmit_RTP_VoIP(); }
                            catch (Exception ex)
                            { Log.e(tag,"Avvio nuovo Thread per receive_RTP_VoIP(); exception: " + ex.getMessage(), ex); }
                        }
                    });
                    t.start();

2 个答案:

答案 0 :(得分:3)

对于谁会遇到同样的问题,我会分享我发现的内容。在“http://developer.android.com/reference/android/net/rtp/AudioStream.html”我发现“本地端口被自动分配以符合RFC 3550”;这意味着在一个Android设备中分配端口后,必须以某种方式将其发送到另一个设备(我手动测试)。然后我首先尝试使用单播IP地址(然后使用设备的IP地址,即192.168.1.10)并且它有效。当我简单地用多播地址交换单播地址时,它不起作用。所以我的结论是android.net.RTP不适用于多播。我会按照建议的方式去研究JMF(谢谢!!!),如果成功,我会分享结果。我想知道为什么在官方的android站点中,“android.net.rtp”包被写为“为RTP提供API(实时传输协议)”,允许应用程序管理按需或交互式数据流。特别是应用程序提供VOIP,即按即说,会议和音频流可以使用这些API来启动会话,并通过任何可用的网络传输或接收数据流。“如何在没有多播的情况下进行按键通话和会议?有人知道如何向Google提问这个问题吗?我想看看支持,但我找不到任何有用的东西......

答案 1 :(得分:1)

Java Media Framework指南位于http://download.oracle.com/otndocs/jcp/7276-jmf-2.0-fr-doc-oth-JSpec/ 从第139页开始,它提供了使用多播传输流式RTP音频的代码示例。