Android 在没有 SIP 的情况下使用 PTT 聊天 VoIP - 多播、AudioStream、Audiogroup 不工作

Android Chat VoIP with PTT without SIP - multicast, AudioStream, Audiogroup not working

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

我的代码如下: 首先是 class "RTP_VoIP_Manager",其中实现了接收和传输的 2 种方法。 在一段简单的代码之后,我用它来调用 activity 中的 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); }
}



}

在 ACTIVITY 内(例如传输):

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

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

谁会遇到同样的问题,我会分享我的发现。在“http://developer.android.com/reference/android/net/rtp/AudioStream.html”,我发现“自动分配本地端口以符合 RFC 3550”;这意味着在一个 android 设备中分配端口后,它必须以某种方式发送到另一个设备(我手动进行测试)。然后我首先尝试使用单播 IP 地址(然后使用设备的 IP 地址,即 192.168.1.10)并且它有效。当我简单地将单播地址与多播地址交换时,它不起作用。所以我的结论是 android.net.RTP 不适用于多播。我会按照 bt jaybers 的建议去研究 JMF(谢谢!!!),如果成功的话,我会分享结果。我想知道为什么在官方 android 站点上写了 "android.net.rtp" 包 "Provides APIs for RTP (Real-time Transport Protocol), allowing applications to manage on-demand or interactive data streaming. In particular, apps that provide VOIP, push-to-talk, conferencing, and audio streaming can use these APIs to initiate sessions and transmit or receive data streams over any available network." 如何在没有多播的情况下进行即按即说和会议?有人知道如何向 google 提出问题吗?我看了看支持,但没找到有用的东西...