一、功能简介与操作视频
该APP功能完成音频的录制并命名保存与播放功能
1、录制
在音频录制界面点击开始按钮即可进行录制,录制过程中可以点击暂停按钮暂时停止录制,暂停可以继续录制,点击停止按钮结束录制,然后,跳出命名和保存框,点击删除按钮则不保存此次录音文件,在输入框输入文件名并点击保存按钮可以保存此次录音的音频文件
2、查看录音文件列表
在音频录制界面中点击文件列表按钮即可跳转查看录音文件列表,该列表显示了ARecordFiles文件夹中所有的录音文件,长按某个录音文件可以选择删除或者分享给手机上其他应用,点击某个录音文件,跳转到播放该录音文件界面
3、播放
进入播放界面后,点击播放按钮即可进行播放,播放过程中可以点击暂停按钮暂时停止播放,暂停可以继续播放,点击结束按钮结束播放。一次播放结束后,可以再次点击播放按钮重新播放
二、文件夹结构

FileUtil.java找出ARecordFiles文件下所有音频文件然后保存到ArrayList中
Pcm2WavUtil.java将原始的.pcm音频文件转成可直接播放的.wav音频文件
PlayerManager.java与音频播放有关
RecorderManager.java与音频录制有关
TimerManager.java与计时器有关
AudioPlay.java实现具体的音频播放功能,与activity_audio_play.xml绑定
FileListAdapter.java继承了BaseAdapter适配器,目的是将文件显示在listview控件中,与activity_filelist绑定
ListActivity.java实现具体的文件显示功能,主要用到了listview控件,与activity_list绑定
MainActivity.java实现具体的音频录制功能,与activity_filelist绑定
ListActivity.java实现具体的文件显示功能,主要用到了listview控件,与activity_main绑定
三、实现
3.1 录制
使用java自带的AudioRecord进行录制
实现录音步骤:
①计算缓冲录音数据的字节数组的大小。AudioRecord 需要一个容器来缓冲来自硬件的音频信息。
bufferSize=AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE,AUDIO_CHANNEL,AUDIO_ENCODING);
②创建AudioRecord对象
myrecord=new AudioRecord(AUDIO_INPUT,AUDIO_SAMPLE_RATE,AUDIO_CHANNEL,AUDIO_ENCODING,bufferSize);
③初始化一个buffer
buffer = new byte[bufferSize];
④开始录音
myrecord.startRecording();
Recordstatus=Status.STATUS_START;
⑤创建一个数据流,一边从AudioRecord中读取声音数据到初始化的buffer,一边将buffer中数据导入数据流,这里创建一个新线程完成该操作,注意使用Environment.getExternalStorageDirectory()获取手机存储的根目录
new Thread(()->{
FileOutputStream os=null;
try {
//首先创建文件夹
File dirFile = new File(Environment.getExternalStorageDirectory(),DirName);
if(!dirFile.exists()){
dirFile.mkdirs();
}
File myfile=new File(dirFile,finalFileName);
//如果文件存在,先删除文件
if(myfile.exists()){
myfile.delete();
}
//然后创建新文件
myfile.createNewFile();
os = new FileOutputStream(myfile);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (Exception e) {
Log.e("TestFile", "Error on write File:" + e);
}
if(os!=null){
//判断录音的状态
while(Recordstatus==Status.STATUS_START){
int read = myrecord.read(buffer, 0, bufferSize);
// 如果读取音频数据没有出现错误,就将数据写入到文件
if (AudioRecord.ERROR_INVALID_OPERATION != read) {
try {
os.write(buffer);
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
).start();
⑥停止录音
myrecord.stop();
Recordstatus=Status.STATUS_STOP;
myrecord.release();
myrecord=null;
Recordstatus=Status.STATUS_NO_READY;
另外,还可以使用MediaPlayer进行录制。 MediaPlayer比AudioRecord更上层,使用起来更方便、易用,但是AudioRecord偏底层,因此也就更灵活,我可以自由设置位宽,采样率,通道数与录制时所使用的的麦克风这些参数。
录制声音MediaRecorder和AudioRecord 区别
<1>.MediaRecorder录制的音频文件是经过压缩后的,需要设置编码器。并且录制的音频文件可以用系统自带的Music播放器播放。
<2>.而AudioRecord录制的是PCM格式的音频文件,需要用AudioTrack来播放,AudioTrack更接近底层。
<3>.在用MediaRecorder进行录制音视频时,最终还是会创建AudioRecord用来与AudioFlinger进行交互。
<4>.MediaRecorder录制的数据是 amr MP3 格式 ,AudioRecord录制出来的是比较原始的PCM音频格式 ,PCM经过编码压缩可以为 amr MP3 AAC。
<5>.如果想简单地做一个录音机,录制成音频文件,则推荐使用 MediaRecorder,而如果需要对音频做进一步的算法处理、或者采用第三方的编码库进行压缩、以及网络传输等应用,则建议使用 AudioRecord
3.2 暂停/继续录制
实现该功能最重要的是对录音状态的控制
构建状态类,控制录音状态
public enum Status {
//未开始
STATUS_NO_READY,
//预备
STATUS_READY,
//录音
STATUS_START,
//暂停
STATUS_PAUSE,
//停止
STATUS_STOP
}
//初始状态为未开始
private Status Recordstatus=Status.STATUS_NO_READY;
每次录音开始—录音暂停/停止这一阶段我们称之为一个周期,而每个周期都创建一个临时.pcm文件,保存该周期录制的音频,因此暂停/继续录制功能的实现可看成是将录制分成多个周期,最终得到多个临时小文件,最后将这些小文件合并成为一个大的.pcm文件完成对该功能的实现。这里注意:每个周期的临时文件命名不能冲突,否则会出现覆盖,导致某部分音频的缺失,另外要将各个周期的临时文件名按照创建顺序保存下来,保证最后音频的顺序性。
//合并所有临时文件成为一个文件
public void mergeAllFiles(){
File finalFile =new File(Environment.getExternalStorageDirectory(),DirName+"/"+Afilename);
FileOutputStream os=null;
try {
//创建最终文件
finalFile.createNewFile();
os = new FileOutputStream(finalFile);
//将每个临时文件的内容读出来并保存到最终文件中,同时删除临时文件
for (String fileName : AllFiles) {
FileInputStream in =null;
File infile=new File(Environment.getExternalStorageDirectory(),DirName+"/"+fileName);
in = new FileInputStream(infile);
byte[] data = new byte[bufferSize];
while (in.read(data) != -1) {
os.write(data);
}
in.close();
infile.delete();//删除临时文件
}
AllFiles.clear();//清除ArrayList
FileVersion=1;//清除版本号
os.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (Exception e) {
Log.e("TestFile", "Error on write File:" + e);
}
}
3.3 pcm转wav
pcm与wav:
一般通过麦克风采集的录音数据都是PCM格式的,即不包含头部信息,播放器无法知道音频采样率、位宽等参数,导致无法播放,在pcm文件的数据开头加入WAVE HEAD数据即可转成wav文件
wav头文件:

| 偏移地址 | 命名 | 内容 |
|---|---|---|
| 00-03 | ChunkId | “RIFF” |
| 4-07 | ChunkS |

本文详细介绍了如何在Android中实现音频录制、暂停/继续、自定义命名保存、pcm转wav、文件列表显示、播放、计时器、文件分享及长按操作等功能。涉及到的关键技术包括AudioRecord、MediaRecorder、MediaPlayer、FileUtil和PopupMenu等,同时讨论了不同音频处理类的优缺点。此外,还强调了权限管理和文件操作的相关细节。
最低0.47元/天 解锁文章

588





