【问题标题】:Creating a VOIP app that works within a Wifi Hotspot创建在 Wifi 热点中运行的 VOIP 应用程序
【发布时间】:2020-03-18 14:36:53
【问题描述】:

使用此代码:

public class MainActivity extends AppCompatActivity {

    int clientAmount = 0;
    int localPort = 0;
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        try {

            AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
            audio.setMode(AudioManager.MODE_IN_COMMUNICATION);
            final AudioGroup m_AudioGroup = new AudioGroup();
            m_AudioGroup.setMode(AudioGroup.MODE_NORMAL);

            final AudioStream m_AudioStream = new AudioStream(getAPAddress());

            int localPort = m_AudioStream.getLocalPort();


            Log.d("VOIP","Local Port: "+ Integer.toString(localPort));

            m_AudioStream.setCodec(AudioCodec.PCMU);
            m_AudioStream.setMode(RtpStream.MODE_NORMAL);

            findViewById(R.id.connectButton).setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    String remoteAddress = "";
                    String remotePort = "";

                    try {
                        remoteAddress = ((TextView) findViewById(R.id.ipField)).getText().toString();
                        //String remoteAddress = fetchIPs().get(0);
                        remotePort = ((EditText) findViewById(R.id.portField)).getText().toString();

                    }catch(Exception e){
                        ((TextView) findViewById(R.id.statusLabel)).setText("Enter Correct Information");
                    }
                    //Log.d("VOIP", fetchIPs().get(0));

                    try {
                        m_AudioStream.associate(InetAddress.getByName(remoteAddress), Integer.parseInt(remotePort));

                        Log.d("VOIP","Succesfully connected to " + remoteAddress);

                    } catch (Exception e) {
                        ((TextView) findViewById(R.id.statusLabel)).setText("Exception with associating");
                        Log.d("VOIP","Exception with associating");
                        Log.d("VOIP", e.getMessage());
                    }
                    m_AudioStream.join(m_AudioGroup);
                }
            });

            findViewById(R.id.DisconnectButton).setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    m_AudioStream.release();
                }
            });

        } catch (Exception e) {
            Log.e("VOIP", "Exception when setting up the Audiostream!");
            e.printStackTrace();
        }
    }


    public InetAddress getAPAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();

                if(intf.getName().equals("ap0")) {

                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                        InetAddress inetAddress = enumIpAddr.nextElement();

                        for(int i = 0; i<intf.getInterfaceAddresses().size(); i++){

                            if( intf.getInterfaceAddresses().get(i).getAddress() instanceof Inet4Address){

                                Log.d("VOIP", "IP: " + intf.getInterfaceAddresses().get(i).getAddress() + " NetworkInterface: " + intf.getName());
                                return (Inet4Address) intf.getInterfaceAddresses().get(i).getAddress();
                            }
                        }
                    }
                }
            }
        } catch (SocketException ex) {
            Log.e("VOIP", ex.toString());
        }
        return null;
    }

    public InetAddress getWLANAddress() {
        InetAddress result = null;

        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();


                if(intf.getName().equals("wlan0")) {
                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        InterfaceAddress a = intf.getInterfaceAddresses().get(1);

                        for(int i = 0; i<intf.getInterfaceAddresses().size(); i++){

                            if( intf.getInterfaceAddresses().get(i).getAddress() instanceof Inet4Address){
                                Log.d("VOIP", "IP: " + intf.getInterfaceAddresses().get(i).getAddress() + " NetworkInterface: " + intf.getName());
                                result =  intf.getInterfaceAddresses().get(i).getAddress();
                            }
                        }
                        if (!inetAddress.isLoopbackAddress()) {
                            return result;
                        }
                    }
                }
            }
        } catch (SocketException ex) {
            Log.e("VOIP", ex.toString());
        }

        Log.d("VOIP"," Access Point nor Wlan accessible");

        return null;

    }

}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/lblLocalPort"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/localPort" />

    <EditText
        android:id="@+id/ipField"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:hint="@string/iPHint"
        android:inputType="phone" />

    <EditText
        android:id="@+id/portField"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:hint="@string/portHint"
        android:inputType="number">

        <requestFocus />
    </EditText>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp">

        <Button
            android:id="@+id/connectButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/connect" />

        <Button
            android:id="@+id/DisconnectButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/Disconnect" />

        <Button
            android:id="@+id/fetchButtons"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Fetch IPs" />
    </LinearLayout>

    <TextView
        android:id="@+id/statusLabel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView" />
</LinearLayout>

我想创建一个点对点 Walkie Talkie 应用程序,允许我在两个设备之间传输音频。一个称为 HostDevice 的设备创建一个 WiFi 接入点(热点),另一个设备 ClientDevice 连接到它。我的理解是,使用 HostDevice,我使用接入点网络接口的 InetAddress(称为“ap0”)启动 AudioStream,使用 ClientDevice,我使用 wlan 网络接口的 InetAddress(“wlan0”)启动 AudioStream。 (这是正确的吗?)所以当我将代码上传到 HostDevice 时,我写道:

final AudioStream m_AudioStream = new AudioStream(getAPAddress());

在 ClientDevice 端我有相同的代码,除了我像这样启动 AudioStream:

final AudioStream m_AudioStream = new AudioStream(getWLANAddress());

如下图所示,当我输入两台设备的 IP 地址和端口号,然后在任一设备上按连接时,我在 m_AudioStream.associate(InetAddress.getByName(remoteAddress), Integer.parseInt(remotePort)); 处收到异常消息,显然,我没有听到任何来自来自任一设备的扬声器。

This answer from Murphybro2 表示这就是两个设备相互通信所需的全部内容。那么我的理解在哪里崩溃了?

【问题讨论】:

    标签: android audio-streaming hotspot rpt


    【解决方案1】:

    检查 VOIP 或点对点应用程序是否正常工作的步骤

    第 1 步:检查音频流是否被正确捕获和处理。 如果可能,打印日志或检查 logcat 以获取特定日志或音频原始转储。

    第 2 步:检查音频 RTP 数据包是否传输到网络以及正确的 IP 地址和端口号。 pcap 文件(用于嗅探的wireshark /tcpdump 工具)网络数据包。解码为 RTP 数据包

    第 3 步:检查接收器接收到的数据是否被正确处理并使用与捕获的相同配置进行渲染。 如果可能,打印日志或检查 logcat 以获取特定日志或音频原始转储。

    请根据上述步骤分享您的观察/结果。

    【讨论】:

    • 我从 Play 商店下载了“数据包捕获”,并在我的设备上作为接收方和发送方进行了测试。端口号和IP地址正确!我无法在应用程序中将它们解码为 RTP 数据包,但以十六进制格式我可以看到每个捕获看起来都一样:前 2 个字节始终相同(80 00),以下 10 个字节每次都不同(可能包含数据我需要),其余的都是“FF”
    • 您可以将录制的文件传输到PC并在wireshark工具中打开它以检查数据包并在wireshark中播放(RTP分析)
    猜你喜欢
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    相关资源
    最近更新 更多