使用UDP多播的android“walkie-talkie”

时间:2015-03-17 13:14:13

标签: android audio udp multicast

我必须为语音通信设计一个基本的Android应用程序。 UI有两个按钮,button1记录和实时广播,而button2让应用程序从设备接收音频。因此,要在两个设备之间进行通信,必须启用button2,而另一个使用button1进行通信。

必须使用UDP多播来实现网络功能。音频录制和播放已经预先实现,我必须实现网络功能。

这是我发送录音的代码。

    public void run() {
    try {
        byte[] pkt = new byte[MAXLEN];

        //setting up connection for UDP multicast
        InetAddress group = InetAddress.getByName("224.0.0.1");
        DatagramPacket packet;
        MulticastSocket socket = new MulticastSocket();

        while (!Thread.interrupted()) {

            int len = stream.read(pkt, 0, pkt.length);                          
            queue.put(pkt);
            Log.d("Audiocast", "recorded "+len+" bytes");

            //creating packet with buffered audio
            packet = new DatagramPacket(pkt, pkt.length,group, 3210);
            socket.send(packet);
        }
    } catch (InterruptedException e) {
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {

        stream.stop();
        stream.release();
    }

}

这是接收方的代码

public void run() {
    try {

        byte[] b = new byte[1024];
        DatagramPacket pack = new DatagramPacket(b, b.length);
        MulticastSocket  sock = new MulticastSocket(3210);
        sock.setBroadcast(true);
        sock.joinGroup(InetAddress.getByName("224.0.0.1"));
        byte[] bSockBuffer = new byte[1024];
        //byte            []bRecvBufTmp;

        sock.setReceiveBufferSize(bSockBuffer.length);
        while (!Thread.interrupted()) {

            sock.receive(pack);
            System.err.println("Received " + pack.getLength() +
                    " bytes from " + pack.getAddress());
                  pack.setLength(b.length);
            queue.put(pack.getData());
            byte[] pkt = queue.take();
            int len = stream.write(pack.getData(), 0, pack.getLength());
            Log.d("Audiocast", "played "+len+" bytes");
        }
    } catch (SocketException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        stream.stop();
        stream.release();
    }
}

问题是,一旦我连接Android设备并加载此应用程序,我在logcat上得到以下错误

03-17 18:29:35.505:E /(9532):设备驱动程序API匹配 03-17 18:29:35.505:E /(9532):设备驱动程序API版本:17 03-17 18:29:35.505:E /(9532):用户空间API版本:17 03-17 18:29:35.505:E /(9532):mali:REVISION = Linux-r3p1-01rel1 BUILD_DATE = 5月10日星期五18:36:49 KST 2013

一旦我从上面的代码中删除了所有与队列相关的函数,就没有错误。它仍然无法正常运行。应用程序加载,logcat在按下2个按钮之前提供以下信息(连续循环)。

Audiocast记录0字节/ Audiocast播放了0个字节

按下记录和广播按钮,将logcat输出更改为

Audiocast记录了1024个字节 Audiocast播放了0个字节

再次连续循环。

最后,如果我点击播放,那就是第二个按钮。 logcat输出更改为

Audiocast记录了0个字节

连续循环。一旦我取消第二个按钮,我就会听到静电噪音。 有人可以帮我解决这个问题,非常感谢谢谢。

这是主要的活动类,如果需要的话

public class AudiocastActivity extends Activity {
final static int SAMPLE_HZ = 11025, BACKLOG = 8;    
//  final static InetSocketAddress multicast = new      InetSocketAddress("224.0.0.1", 3210);

Record rec; 
Play play;

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

    WifiManager wifi = (WifiManager)getSystemService( Context.WIFI_SERVICE );
    if(wifi != null){
        WifiManager.MulticastLock lock = 
                wifi.createMulticastLock("Audiocast");
        lock.setReferenceCounted(true);
        lock.acquire();
    } else {
        Log.e("Audiocast", "Unable to acquire multicast lock");
        finish();
    }
}

@Override
protected void onStart() {
    super.onStart();

    BlockingQueue<byte[]> buf = new ArrayBlockingQueue<byte[]>(BACKLOG);        
    rec = new Record(SAMPLE_HZ, buf);
    play = new Play(SAMPLE_HZ, buf);

    findViewById(R.id.Record).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
                rec.pause(!((ToggleButton)v).isChecked());
        }
    });     
    findViewById(R.id.Play).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
                play.pause(!((ToggleButton)v).isChecked());
        }
    }); 

    Log.i("Audiocast", "Starting recording/playback threads");
    rec.start();
    play.start();
}

@Override
protected void onStop() {
    super.onStop();

    Log.i("Audiocast", "Stopping recording/playback threads");
    rec.interrupt();
    play.interrupt();
}

}

0 个答案:

没有答案