文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2022-06-06 05:27

关注

最近做的项目是和语音实时采集并发送,对方实时接收并播放相关,下面记录下实现的核心代码。
很多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);

}
//录制循环结束后,记得关闭录制!!
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);
  }
}

问题二:

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

您可能感兴趣的文章:Android基于讯飞语音SDK实现语音识别Android仿微信语音聊天功能android预置默认的语音信箱号码具体实现Android实现语音识别代码Android使用百度语音识别的示例代码Android 轻松实现语音识别详解及实例代码Android Studio应用开发集成百度语音合成使用方法实例讲解Android 基于百度语音的语音交互功能(推荐)Android仿微信语音聊天界面设计android语音即时通讯之录音、播放功能实现代码


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯