Android基于UDP语音对讲系列(三)

微信公众号:Android疯子

Android基于UDP语音对讲系列(三)
之前研究了基于UDP的文字传输点击打开链接,以及Android端的语音录制点击打开链接,这篇文章就记录一下Android端局域网内的语音传输,简单的实现语音对讲,当然里面还存在着很多问题,包括语音不清晰啊、杂音多啊,不管了,先听见声音就行了。测试的时候两部手机。
程序写了两个线程,一个用于录制AudioRecordThread,一个用于播放AudioTrackThread.
(一)录制与发送

 1 @Override
 2    public void run() {
 3        if (mSocket == null) return;
 4        try {
 5            mStartTime = System.currentTimeMillis();
 6            audioRec.startRecording();
 7            while (flag) {
 8                try {
 9                    byte[] bytes_pkg = buffer.clone();
10                    if (mRecordQueue.size() >= 2) {
11                        int length = audioRec.read(buffer, 0, minBufferSize);
12                        //获取音量大小
13                        mVolume = getAudioColum(buffer);
14                        System.out.println(TAG + "= " + mVolume);
15                        Message message = mHandler.obtainMessage();
16                        message.arg1 = (int) mVolume;
17                        mHandler.sendMessage(message);
18
19                        DatagramPacket writePacket;
20                        InetAddress inet = InetAddress.getByName(inetAddressName);
21                        writePacket = new DatagramPacket(buffer, length, inet, PORT);
22                        writePacket.setLength(length);
23                        System.out.println("AudioRTwritePacket = " + writePacket.getData().toString());
24
25                        mSocket.send(writePacket);
26                    }
27                    mRecordQueue.add(bytes_pkg);
28                } catch (Exception e) { // TODO Auto-generated catch block
29                    e.printStackTrace();
30                }
31            }
32            audioRec.stop();
33        } catch (Exception e) {
34            e.printStackTrace();
35        }
36    }

里面包含了获取音量大小,便于在页面上面展示,方法参考了[点击打开链接]

 1private double getAudioColum(byte[] buffer) { 
 2    double sumVolume = 0.0;
 3
 4    double avgVolume = 0.0;
 5
 6    double volume = 0.0;
 7
 8    for (int i = 0; i < buffer.length; i += 2) { 
 9        int v1 = buffer[i] & 0xFF;
10
11        int v2 = buffer[i + 1] & 0xFF;
12
13        int temp = v1 + (v2 << 8);// 小端
14
15        if (temp >= 0x8000) { 
16            temp = 0xffff - temp;
17
18        } 
19        sumVolume += Math.abs(temp);
20
21    } 
22    avgVolume = sumVolume / buffer.length / 2;
23
24    volume = Math.log10(1 + avgVolume) * 10;
25
26    return volume;
27}

(二)接收与播放

 1@Override
 2public void run() { 
 3    if (mSocket == null) return;
 4    //从文件流读数据
 5    audioTrk.play();
 6    while (flag) { 
 7        DatagramPacket recevPacket;
 8        try { 
 9        recevPacket = new DatagramPacket(buffer, 0, buffer.length);
10        mSocket.receive(recevPacket);
11        audioTrk.write(recevPacket.getData(), 0, recevPacket.getLength());
12        } catch (IOException e) { 
13         // TODO Auto-generated catch block
14            e.printStackTrace();
15        } 
16     } 
17     audioTrk.stop();
18}

(三)主页面 接收按钮事件

 1@OnClick({R.id.btn_receive}) 
 2public void onViewClicked(View view) { 
 3     switch (view.getId()) { 
 4         case R.id.btn_receive:
 5           if (btnReceive.getText().toString().equals("开始接收")) { 
 6            btnReceive.setText("停止接收");
 7           try { 
 8             if (audioTrackThread == null) { 
 9            audioTrackThread = new AudioTrackThread();
10                    } 
11             new Thread(audioTrackThread).start();
12
13                } catch (SocketException e) {
14                   e.printStackTrace();
15                }
16              } else { btnReceive.setText("开始接收");
17                audioTrackThread.setFlag(false);
18            } 
19            break;
20    } }

(四)发送按钮事件

 1ivSpeak.setOnTouchListener(new View.OnTouchListener() { @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) @Override
 2    public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { 
 3            case MotionEvent.ACTION_DOWN: //按下按钮开始录制
 4                ivSpeak.setText("正在说话");
 5                //显示录音提示
 6                relativeLayout.setVisibility(View.VISIBLE);
 7                try { if (audioRecordThread == null) { audioRecordThread = new AudioRecordThread(handler);
 8                    } audioRecordThread.setInetAddressName(tvReceiveIp.getText().toString());
 9                    audioRecordThread.setFlag(true);
10                    new Thread(audioRecordThread).start();
11                } catch (SocketException e) { e.printStackTrace();
12                }
13                 break;
14            case MotionEvent.ACTION_UP: 
15            case MotionEvent.ACTION_CANCEL: //松开按钮结束录制
16                ivSpeak.setText("按住说话");
17                relativeLayout.setVisibility(View.GONE);
18                audioRecordThread.setFlag(false);
19                mStopTime = audioRecordThread.getmStopTime();
20                mStartTime = audioRecordThread.getmStartTime();
21                creatMessageBean((mStopTime - mStartTime) / 1000, true);
22                break;
23        } 
24            return true;
25    } });
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stormxiaofeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值