Java 桌面和android之间的ip语音
我正在尝试在android和桌面之间实时传输音频。我已经开发了很多应用程序,一个用于android,一个用于桌面。 桌面应用程序已成功在两台桌面之间进行实时音频传输,android应用程序已成功在两台android设备之间进行音频传输。 我正在为此进程使用本地ip地址和端口(在两个应用程序中) 问题是,当我尝试在android和桌面(使用相同的应用程序)之间传输音频时,它不起作用。 我只能传输单向音频,例如在桌面接收语音或传输语音时 请帮忙 下面是android应用程序的代码Java 桌面和android之间的ip语音,java,android,sockets,voip,Java,Android,Sockets,Voip,我正在尝试在android和桌面之间实时传输音频。我已经开发了很多应用程序,一个用于android,一个用于桌面。 桌面应用程序已成功在两台桌面之间进行实时音频传输,android应用程序已成功在两台android设备之间进行音频传输。 我正在为此进程使用本地ip地址和端口(在两个应用程序中) 问题是,当我尝试在android和桌面(使用相同的应用程序)之间传输音频时,它不起作用。 我只能传输单向音频,例如在桌面接收语音或传输语音时 请帮忙 下面是android应用程序的代码 packa
package com.example.myrtpapplication;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.net.rtp.AudioCodec;
import android.net.rtp.AudioGroup;
import android.net.rtp.AudioStream;
import android.net.rtp.RtpStream;
import android.os.Handler;
import android.os.StrictMode;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
public class MainActivity extends AppCompatActivity {
EditText remote_ip_editText;
EditText remote_port_editText;
TextView locolport;
AudioStream audioStream;
AudioGroup audioGroup;
String localip;
Handler handler;
int flag=0;
private static int REQUEST_EXTERNAL_STORAGE=1;
private String[] PERMISSIONS={
Manifest.permission.RECORD_AUDIO,
Manifest.permission.MODIFY_AUDIO_SETTINGS,
Manifest.permission.INTERNET,
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
verifyPermissions(MainActivity.this);
if(flag==1) {
locolport = (TextView) findViewById(R.id.lp);
remote_ip_editText = (EditText) findViewById(R.id.remote_ip);
remote_port_editText = (EditText) findViewById(R.id.remote_port);
handler = new Handler();
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
int line = 0;
try {
AudioManager audiomanager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audiomanager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audiomanager.setSpeakerphoneOn(true);
// audiomanager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
if (audiomanager.isMicrophoneMute()) {
Toast.makeText(MainActivity.this, "Microphone is mute", Toast.LENGTH_LONG).show();
}
audioGroup = new AudioGroup();
audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION);
localip = getLocalAddress().toString();
audioStream = new AudioStream(getLocalAddress());
locolport.append(String.valueOf(audioStream.getLocalPort()));
audioStream.setCodec(AudioCodec.PCMU);
audioStream.setMode(RtpStream.MODE_NORMAL);
//Toast.makeText(MainActivity.this, "line = 10", Toast.LENGTH_SHORT).show();
} catch (SocketException se) {
Toast.makeText(MainActivity.this, se.getMessage(), Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(MainActivity.this, "line = " + line + e.getMessage() + "\n" + localip, Toast.LENGTH_LONG).show();
Log.e("-------", e.toString());
e.printStackTrace();
}
}else{
Toast.makeText(MainActivity.this, "permissions denied rizi", Toast.LENGTH_SHORT).show();
}
}
public void call(View view)
{
try {
//Toast.makeText(MainActivity.this, remote_ip_editText.getText().toString(), Toast.LENGTH_SHORT).show();
InetAddress remoteIp = InetAddress.getByName(remote_ip_editText.getText().toString());
Toast.makeText(MainActivity.this, remote_port_editText.getText().toString(), Toast.LENGTH_SHORT).show();
Integer remotePort= Integer.parseInt(remote_port_editText.getText().toString());
audioStream.associate(remoteIp, remotePort);
audioStream.join(audioGroup);
Toast.makeText(MainActivity.this, "call Success", Toast.LENGTH_SHORT).show();
}
catch (UnknownHostException ex){
Toast.makeText(MainActivity.this, "Unkown host Exception "+ ex.getMessage(), Toast.LENGTH_SHORT).show();
}
catch (Exception e) {
Toast.makeText(MainActivity.this, "Exception "+ e, Toast.LENGTH_SHORT).show();
}
}
public InetAddress getLocalAddress()
{
InetAddress localAddress;
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface networkInterface = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = networkInterface.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress ip = enumIpAddr.nextElement();
if (!ip.isLoopbackAddress()) {
if (ip.isSiteLocalAddress()) {
return ip;
}
}
}
}
}
catch (Exception e)
{
Toast.makeText(MainActivity.this, "Exception at get local Address"+e.getMessage(), Toast.LENGTH_SHORT).show();
}
return null;
}
public void verifyPermissions(Activity activity) {
// Check if we have write permission
int permission1= ActivityCompat.checkSelfPermission(activity, Manifest.permission.MODIFY_AUDIO_SETTINGS);
int permission2= ActivityCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO);
int permission3= ActivityCompat.checkSelfPermission(activity, Manifest.permission.INTERNET);
if (permission1 != PackageManager.PERMISSION_GRANTED || permission2 != PackageManager.PERMISSION_GRANTED || permission3 != PackageManager.PERMISSION_GRANTED ) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS,
REQUEST_EXTERNAL_STORAGE
);
}else{
flag=1;
}
}
}
发射机类
package rtpstreamdesktop;
import java.util.Vector;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.DataSink;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NotRealizedError;
import javax.media.Processor;
import javax.media.control.FormatControl;
import javax.media.control.TrackControl;
import javax.media.format.AudioFormat;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;
/**
*
* @author Abdul Rab
*
*/
public class SimpleVoiceTransmiter implements Runnable
{
/**
* @param args
*/
public void run()
{
CaptureDeviceInfo di = null;
Format format;
format = new AudioFormat(AudioFormat.ULAW_RTP, 8000, 8, 1);
// First find a capture device that will capture linear audio
// data at 8bit 8Khz
AudioFormat captureFormat = new AudioFormat(AudioFormat.LINEAR, 8000, 16, 1);
Vector devices = CaptureDeviceManager.getDeviceList(captureFormat);
if (devices.size() > 0)
{
di = (CaptureDeviceInfo) devices.elementAt(0);
} else
{
System.err.println("No capture devices");
// exit if we could not find the relevant capturedevice.
System.exit(-1);
}
// Create a processor for this capturedevice & exit if we
// cannot create it
Processor processor = null;
try
{
processor = Manager.createProcessor(di.getLocator());
} catch (Exception e)
{
System.out.println("Procesor Exception: ");
}
// configure the processor
processor.configure();
while (processor.getState() != Processor.Configured)
{
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
System.out.println("interupted processor exception: ");
}
}
processor.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW_RTP));
TrackControl track[] = processor.getTrackControls();
boolean encodingOk = false;
// Go through the tracks and try to program one of them to
// output gsm data.
for (int i = 0; i < track.length; i++)
{
if (!encodingOk && track[i] instanceof FormatControl)
{
if (((FormatControl) track[i]).setFormat(format) == null)
{
track[i].setEnabled(false);
} else
{
encodingOk = true;
}
} else
{
// we could not set this track to gsm, so disable it
track[i].setEnabled(false);
}
}
// At this point, we have determined where we can send out
// gsm data or not.
// realize the processor
if (encodingOk)
{
if (!new net.sf.fmj.ejmf.toolkit.util.StateWaiter(processor).blockingRealize())
{
System.err.println("Failed to realize");
return;
}
// get the output datasource of the processor and exit
// if we fail
DataSource ds = null;
try
{
ds = processor.getDataOutput();
} catch (NotRealizedError e)
{
e.printStackTrace();
System.exit(-1);
}
// hand this datasource to manager for creating an RTP
// datasink our RTP datasink will multicast the audio
try
{
String url = "rtp://192.168.8.102:60010/audio/16";
MediaLocator m = new MediaLocator(url);
DataSink d = Manager.createDataSink(ds, m);
d.open();
d.start();
System.out.println("Starting processor");
processor.start();
Thread.sleep(30000);
} catch (Exception e)
{
System.out.println("RTP connection exception: ");
System.exit(-1);
}
}
}
}
我不了解你的代码在一个方向上是如何工作的,因为你在Android端使用(正确的)Android.net.rtp包(而不是发送/接收Voip包),而在PC端似乎没有任何Voip模块;在代码中,您试图使用MediaLocator播放Voip数据包,但Voip数据包不是媒体文件(如mp3) 在我看来,解决方案可能是,在PC端,导入Voip Java模块(有一些开源软件,如“pjsip”),但您必须对其进行调整和研究。这一部分很费时,也不容易,因为您必须稍微了解一下voip是如何工作的,等等
再见,福斯托你必须拿出更多的努力来创作我想我已经宣布了一切。。请告诉我你对它有什么不了解@JamesKPolk。我会解释它进一步阅读链接。我已经提供了完整的代码。你可以复制粘贴来测试它,它也会产生同样的问题。我不能提供最小的原因是,我也不知道导致问题的代码的确切部分。提供最小的示例需要一些努力,但这是您必须付出的努力,而不是我们。谢谢大家,再见,我非常感谢。我一定要试一试
package rtpstreamdesktop;
import java.util.Vector;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.DataSink;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NotRealizedError;
import javax.media.Processor;
import javax.media.control.FormatControl;
import javax.media.control.TrackControl;
import javax.media.format.AudioFormat;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;
/**
*
* @author Abdul Rab
*
*/
public class SimpleVoiceTransmiter implements Runnable
{
/**
* @param args
*/
public void run()
{
CaptureDeviceInfo di = null;
Format format;
format = new AudioFormat(AudioFormat.ULAW_RTP, 8000, 8, 1);
// First find a capture device that will capture linear audio
// data at 8bit 8Khz
AudioFormat captureFormat = new AudioFormat(AudioFormat.LINEAR, 8000, 16, 1);
Vector devices = CaptureDeviceManager.getDeviceList(captureFormat);
if (devices.size() > 0)
{
di = (CaptureDeviceInfo) devices.elementAt(0);
} else
{
System.err.println("No capture devices");
// exit if we could not find the relevant capturedevice.
System.exit(-1);
}
// Create a processor for this capturedevice & exit if we
// cannot create it
Processor processor = null;
try
{
processor = Manager.createProcessor(di.getLocator());
} catch (Exception e)
{
System.out.println("Procesor Exception: ");
}
// configure the processor
processor.configure();
while (processor.getState() != Processor.Configured)
{
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
System.out.println("interupted processor exception: ");
}
}
processor.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW_RTP));
TrackControl track[] = processor.getTrackControls();
boolean encodingOk = false;
// Go through the tracks and try to program one of them to
// output gsm data.
for (int i = 0; i < track.length; i++)
{
if (!encodingOk && track[i] instanceof FormatControl)
{
if (((FormatControl) track[i]).setFormat(format) == null)
{
track[i].setEnabled(false);
} else
{
encodingOk = true;
}
} else
{
// we could not set this track to gsm, so disable it
track[i].setEnabled(false);
}
}
// At this point, we have determined where we can send out
// gsm data or not.
// realize the processor
if (encodingOk)
{
if (!new net.sf.fmj.ejmf.toolkit.util.StateWaiter(processor).blockingRealize())
{
System.err.println("Failed to realize");
return;
}
// get the output datasource of the processor and exit
// if we fail
DataSource ds = null;
try
{
ds = processor.getDataOutput();
} catch (NotRealizedError e)
{
e.printStackTrace();
System.exit(-1);
}
// hand this datasource to manager for creating an RTP
// datasink our RTP datasink will multicast the audio
try
{
String url = "rtp://192.168.8.102:60010/audio/16";
MediaLocator m = new MediaLocator(url);
DataSink d = Manager.createDataSink(ds, m);
d.open();
d.start();
System.out.println("Starting processor");
processor.start();
Thread.sleep(30000);
} catch (Exception e)
{
System.out.println("RTP connection exception: ");
System.exit(-1);
}
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package rtpstreamdesktop;
/**
*
* @author Rizwan
*/
public class RtpStreamDesktop {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Thread(new SimpleVoiceReceiver()).start();
new Thread(new SimpleVoiceTransmiter()).start();
}
}