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 提出问题吗?我看了看支持,但没找到有用的东西...
我的目标是一个 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 提出问题吗?我看了看支持,但没找到有用的东西...