Java 桌面和android之间的ip语音

Java 桌面和android之间的ip语音,java,android,sockets,voip,Java,Android,Sockets,Voip,我正在尝试在android和桌面之间实时传输音频。我已经开发了很多应用程序,一个用于android,一个用于桌面。 桌面应用程序已成功在两台桌面之间进行实时音频传输,android应用程序已成功在两台android设备之间进行音频传输。 我正在为此进程使用本地ip地址和端口(在两个应用程序中) 问题是,当我尝试在android和桌面(使用相同的应用程序)之间传输音频时,它不起作用。 我只能传输单向音频,例如在桌面接收语音或传输语音时 请帮忙 下面是android应用程序的代码 packa

我正在尝试在android和桌面之间实时传输音频。我已经开发了很多应用程序,一个用于android,一个用于桌面。 桌面应用程序已成功在两台桌面之间进行实时音频传输,android应用程序已成功在两台android设备之间进行音频传输。 我正在为此进程使用本地ip地址和端口(在两个应用程序中)

问题是,当我尝试在android和桌面(使用相同的应用程序)之间传输音频时,它不起作用。 我只能传输单向音频,例如在桌面接收语音或传输语音时

请帮忙

下面是android应用程序的代码

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

}