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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(三)Android局域网内语音对讲 基于UDP语音传输相关的知识,希望对你有一定的参考价值。

参考技术A 之前研究了基于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语音传输的主要内容,如果未能解决你的问题,请参考以下文章

物联网 mind+ 实时模式语音对讲

对讲机IP互联中继台系统实现的原理及网络模型

iOS语音对讲(三)FFmpeg实时解码AAC并播放PCM

局域网内通讯APP

技术分享| 快对讲,全球对讲

EasyCVR无法使用语音对讲功能的各种情况总结