【Android】录音暂停和继续
Android自带的录音类MediaRecorder只有start和stop功能,既没有pause功能也没有seekto函数,所以我们要实现暂停功能需要自己动手。而暂停这个功能在很多地方是需要的,假设一个应用中有录音这个功能,那么当电话打来的时候就需要使用暂停功能,并且在打完电话之后恢复录音。(小米手机的原生录音功能是在打进来电话的时候停止录音)。
基本思想是,基于它只能开始和暂停(也有reset重置功能),那么我们只能在打进电话的同时调用stop方法,这个别无它法,然后我们要做的就是在电话打完恢复应用的时候就去重新开始一段录音,等用户点击保存的时候,合并所有的录音文件,这样就可以实现暂停和继续录音的功能。借鉴以下两篇博客以及自己的经验做出阐述如下:
博客一:AMR文件格式分析
博客二:Android MediaRecorder实现暂停断点录音功能
前一篇博客描述了AMR文件的格式,我们可以确定,AMR文件的前6个字节(也就是文件头)是一定一样的。
这幅图最前面的额框就是文件头"#!AMR\n"的ASCII字符码,我在MAC上使用Vim命令同样可以看到该效果(包括换行),截图如下:
左上角就是"#!AMR\n"的文件头,这里换行了。
到这里就很简单了,AMR文件的文件头很简单,什么都没有,而我们要做的就是读一个文件头,将所有文件的音频帧拼凑到一起,OK,继续。
1 /** 合并所有的音频文件 */ 2 public void mergeAllAmrFiles(){ 3 // 创建音频文件,合并的文件放这里 4 File tempFile = new File(recordingFiles.get(0)); 5 File mergeFile = new File(tempFile.getParent() + File.separator + Utils.QIDUO_AMR + ".amr"); 6 Log.d("RECORD", "MERGE : " + mergeFile.getAbsolutePath()); 7 FileOutputStream fileOutputStream = null; 8 9 if(!mergeFile.exists()){ 10 try { 11 mergeFile.createNewFile(); 12 } catch (IOException e){ 13 // TODO Auto-generated catch block 14 e.printStackTrace(); 15 } 16 } 17 18 try { 19 fileOutputStream=new FileOutputStream(mergeFile); 20 } catch (IOException e) { 21 // TODO Auto-generated catch block 22 e.printStackTrace(); 23 } 24 25 //list里面为暂停录音 所产生的几段录音文件的名字,中间几段文件的减去前面的6个字节头文件 26 for(int index = 0; index < recordingFiles.size(); index++){ 27 File file=new File(recordingFiles.get(index)); 28 Log.d("RECORD-PATH", recordingFiles.get(index) + file.length()); 29 try { 30 FileInputStream fileInputStream=new FileInputStream(file); 31 byte []myByte = new byte[fileInputStream.available()]; 32 //文件长度 33 int length = myByte.length; 34 Log.d("RECORD-LENGTH", length + ""); 35 36 //头文件 37 if(index == 0){ 38 while(fileInputStream.read(myByte) != -1){ 39 fileOutputStream.write(myByte); 40 //fileOutputStream.write(myByte, 0,length); 41 } 42 } 43 44 //之后的文件,去掉前面6个字节(头文件) 45 else{ 46 while(fileInputStream.read(myByte) != -1){ 47 fileOutputStream.write(myByte, 6, length - 6); 48 } 49 } 50 51 fileOutputStream.flush(); 52 fileInputStream.close(); 53 //合并之后删除文件 54 //file.delete(); 55 } catch (Exception e) { 56 // TODO Auto-generated catch block 57 e.printStackTrace(); 58 } 59 } 60 61 //结束后关闭流 62 try { 63 fileOutputStream.flush(); 64 fileOutputStream.close(); 65 } catch (IOException e) { 66 // TODO Auto-generated catch block 67 e.printStackTrace(); 68 } 69 70 mSampleFile = mergeFile;//指向它,以便获取地址 71 }
如上代码,我们将除第一个文件的其余amr文件的文件头全部去掉,拼凑在一起即可实现需要的功能。
注意点:
1 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 2 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);// 3 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
OutputStream一定要设置为"RAW_AMR"类型,THREE_GPP是一定不可以的!(文件格式完全不一样,需要重新考察文件头)