美文网首页Android UDP语音对讲研究
(三)Android局域网内语音对讲 基于UDP语音传输

(三)Android局域网内语音对讲 基于UDP语音传输

作者: 孖彧 | 来源:发表于2019-10-11 17:38 被阅读0次

    之前研究了基于UDP的文字传输点击打开链接,以及Android端的语音录制点击打开链接,这篇文章就记录一下Android端局域网内的语音传输,简单的实现语音对讲,当然里面还存在着很多问题,包括语音不清晰啊、杂音多啊,不管了,先听见声音就行了。测试的时候两部手机,上图:

    程序写了两个线程,一个用于录制AudioRecordThread,一个用于播放AudioTrackThread.

    (一)录制与发送

    @Override

    public void run() {

    if (mSocket == null)

    return;

    try {

    mStartTime = System.currentTimeMillis();

    audioRec.startRecording();

    while (flag) {

    try {

    byte[] bytes_pkg = buffer.clone();

    if (mRecordQueue.size() >= 2) {

    int length = audioRec.read(buffer, 0, minBufferSize);

    //获取音量大小

    mVolume = getAudioColum(buffer);

    System.out.println(TAG + "= " + mVolume);

    Message message = mHandler.obtainMessage();

    message.arg1 = (int) mVolume;

    mHandler.sendMessage(message);

    DatagramPacket writePacket;

    InetAddress inet = InetAddress.getByName(inetAddressName);

    writePacket = new DatagramPacket(buffer, length, inet, PORT);

    writePacket.setLength(length);

    System.out.println("AudioRTwritePacket = " + writePacket.getData().toString());

    mSocket.send(writePacket);

    }

    mRecordQueue.add(bytes_pkg);

    } catch (Exception e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    audioRec.stop();

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

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

    private double getAudioColum(byte[] buffer) {

    double sumVolume = 0.0;

    double avgVolume = 0.0;

    double volume = 0.0;

    for (int i = 0; i < buffer.length; i += 2) {

    int v1 = buffer[i] & 0xFF;

    int v2 = buffer[i + 1] & 0xFF;

    int temp = v1 + (v2 << 8);// 小端

    if (temp >= 0x8000) {

    temp = 0xffff - temp;

    }

    sumVolume += Math.abs(temp);

    }

    avgVolume = sumVolume / buffer.length / 2;

    volume = Math.log10(1 + avgVolume) * 10;

    return volume;

    }

    (二)接收与播放

    @Override

    public void run() {

    if (mSocket == null)

    return;

    //从文件流读数据

    audioTrk.play();

    while (flag) {

    DatagramPacket recevPacket;

    try {

    recevPacket = new DatagramPacket(buffer, 0, buffer.length);

    mSocket.receive(recevPacket);

    audioTrk.write(recevPacket.getData(), 0, recevPacket.getLength());

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    audioTrk.stop();

    }

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

    @OnClick({R.id.btn_receive})

    public void onViewClicked(View view) {

    switch (view.getId()) {

    case R.id.btn_receive:

    if (btnReceive.getText().toString().equals("开始接收")) {

    btnReceive.setText("停止接收");

    try {

    if (audioTrackThread == null) {

    audioTrackThread = new AudioTrackThread();

    }

    new Thread(audioTrackThread).start();

    } catch (SocketException e) {

    e.printStackTrace();

    }

    } else {

    btnReceive.setText("开始接收");

    audioTrackThread.setFlag(false);

    }

    break;

    }

    }

    (四)发送按钮事件

    ivSpeak.setOnTouchListener(new View.OnTouchListener() {

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)

    @Override

    public boolean onTouch(View v, MotionEvent event) {

    switch (event.getAction()) {

    case MotionEvent.ACTION_DOWN:

    //按下按钮开始录制

    ivSpeak.setText("正在说话");

    //显示录音提示

    relativeLayout.setVisibility(View.VISIBLE);

    try {

    if (audioRecordThread == null) {

    audioRecordThread = new AudioRecordThread(handler);

    }

    audioRecordThread.setInetAddressName(tvReceiveIp.getText().toString());

    audioRecordThread.setFlag(true);

    new Thread(audioRecordThread).start();

    } catch (SocketException e) {

    e.printStackTrace();

    }

    break;

    case MotionEvent.ACTION_UP:

    case MotionEvent.ACTION_CANCEL:

    //松开按钮结束录制

    ivSpeak.setText("按住说话");

    relativeLayout.setVisibility(View.GONE);

    audioRecordThread.setFlag(false);

    mStopTime = audioRecordThread.getmStopTime();

    mStartTime = audioRecordThread.getmStartTime();

    creatMessageBean((mStopTime - mStartTime) / 1000, true);

    break;

    }

    return true;

    }

    });

    相关文章

      网友评论

        本文标题:(三)Android局域网内语音对讲 基于UDP语音传输

        本文链接:https://www.haomeiwen.com/subject/pxjxmctx.html