当前位置: 移动技术网 > IT编程>移动开发>Android > Android实现语音数据实时采集、播放

Android实现语音数据实时采集、播放

2019年07月24日  | 移动技术网IT编程  | 我要评论

昆山视窗欢迎您,贝特爱维肤膏,大学生心理问题

最近做的项目是和语音实时采集并发送,对方实时接收并播放相关,下面记录下实现的核心代码。
很多android开发者应该知道android有个mediarecorder对象和mediaplayer对象,用于录制和播放音频。这个弊端在于他们不能实时采集并发送出去,所以,我们只能使用audiorecord和audiotrack来实现。
记得申明权限:

<uses-permission android:name="android.permission.modify_audio_settings" />
<uses-permission android:name="android.permission.record_audio" >


一、audiorecord实现核心代码介绍如下:

1、先申明相关录制配置参数

private audiorecord audiorecord;// 录音对象
private int frequence = 8000;// 采样率 8000
private int channelinconfig = audioformat.channel_configuration_mono;// 定义采样通道
private int audioencoding = audioformat.encoding_pcm_16bit;// 定义音频编码(16位)
private byte[] buffer = null;// 录制的缓冲数组


2、在开始录制前,我们需要初始化audiorecord类。

// 根据定义好的几个配置,来获取合适的缓冲大小
// int buffersize = 800;
int buffersize = audiorecord.getminbuffersize(frequence,
    channelinconfig, audioencoding);
// 实例化audiorecord
audiorecord = new audiorecord(mediarecorder.audiosource.mic,
    frequence, channelinconfig, audioencoding, buffersize);
// 定义缓冲数组
buffer = new byte[buffersize];

3、准备开始录制,使用循环不断读取数据。

audiorecord.startrecording();// 开始录制
isrecording = true;// 设置录制标记为true

// 开始录制
while (isrecording) {
// 录制的内容放置到了buffer中,result代表存储长度
int result = audiorecord.read(buffer, 0, buffer.length);
/*.....result为buffer中录制数据的长度(貌似基本上都是640)。
剩下就是处理buffer了,是发送出去还是直接播放,这个随便你。*/
}

//录制循环结束后,记得关闭录制!!
if (audiorecord != null) {
  audiorecord.stop();
}


二、audiotrack代码实现介绍如下:

1、声明播放相关配置。

private audiotrack track = null;// 录音文件播放对象
private int frequence = 8000;// 采样率 8000
private int channelinconfig = audioformat.channel_configuration_mono;// 定义采样通道
private int audioencoding = audioformat.encoding_pcm_16bit;// 定义音频编码(16位)
private int buffersize = -1;// 播放缓冲大小


2、初始化audiotrack对象(初始化一次,该对象可重复使用)

// 获取缓冲 大小
buffersize = audiotrack.getminbuffersize(frequence, channelinconfig,
    audioencoding);
// 实例audiotrack
track = new audiotrack(audiomanager.stream_music, frequence,
    channelinconfig, audioencoding, buffersize,
    audiotrack.mode_stream);


3、使用audiotrack播放语音数据。

//将语音数据写入即可。
track.write(dataarray, buffer, len);


问题一:

由于目前的项目是实时采集,实时发送,所以需要考虑到包的大小,经测试,我们使用160个byte作为一个包传递可以做到比较良好的播放效果(也就是将一份buffer拆分成四个发送)。处理代码如下:

// 将数据通过监听接口回调出去
if (audiorecordingcallback != null) {
  int offset = result % max_data_length > 0 ? 1 : 0;
  //将一个buffer拆分成几份小数据包 max_data_length 为包的最大byte数
  for (int i = 0; i < result / max_data_length + offset; i++) {
    int length = max_data_length;
    if ((i + 1) * max_data_length > result) {
      length = result - i * max_data_length;
    }
  //写到回调接口
  audiorecordingcallback.onrecording(buffer, i
      * max_data_length, length);
  }
}


问题二:

有时候传输的过来播放声音会一卡一卡的,为了解决这样的问题,暂时使用了语音双缓冲机制来解决,问题优化很明显。代码和示意图如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网