前言Android音频采集android音频采集一般有两种方式:AudioRecord和MediaRecorder可以录制音频,MediaRecorder实现了大量封装,操作更简单,AudioRecord更灵活使用,可以实现更多的功能1.Android音频采集1.AudioRecord是基于字节流的录音;可实现语音实时处理、录播、音频实时处理;AudioRecord是一个比较底层的API,可以获取一帧PCM数据,然后可以对这些数据进行处理;输出的是PCM语音数据,如果保存为音频文件,播放器无法播放。使用AudioTrack进行处理;2、MediaRecorder基于文件录制;MediaRecorder是基于AudioRecorderAPI(最终会创建AudioRecord与AudioFlinger进行交互),可以直接将采集到的音频数据转换成执行的编码格式,并保存;集成了录音、编码、压缩等功能,支持少量音频格式文件;高封装,易操作;2、MediaRecorder实现了MediaRecorder(这里需要注意的是,录音和播放都是比较耗时的操作,需要在非主线程中进行操作)。录制的主要代码:privatebooleanstart(){try{//创建MediaRecordermMediaRecorder=newMediaRecorder();//创建录音文件mRecorderFile=newFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/recorderdemo/"+System.currentTimeMillis()+".m4a");如果(!mRecorderFile.getParentFile().exists())mRecorderFile.getParentFile().mkdirs();mRecorderFile.createNewFile();//配置MediaRecorder//从麦克风收集mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//将文件保存为MP4格式mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//所有android系统支持的中等采样频率mMediaRecorder.setAudioSamplingRate(44100);//通用AAC编码格式mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);//设置音质频率mMediaRecorder.setAudioEncodingBitRate(96000);//设置文件录制位置mMediaRecorder.setOutputFile(mRecorderFile.getAbsolutePath());//开始录制mMediaRecorder.prepare();mMediaRecorder.start();startRecorderTime=System.currentTimeMillis();}catch(Exceptione){Toast.makeText(FileActivity.this,"录制失败,请重试",Toast.LENGTH_SHORT).show();返回假;}//记录录音开始时间,用于统计时长,小于3秒不发送录音returntrue;}二、AudioRecord音频采集1.参数介绍AudioRecord的基本参数;audioResource:音频采集源;audioSampleRate:音频采样率;频道配置:频道;audioFormat:音频采样精度,指定采样数据的格式和每次采样的大小;bufferSizeInBytes:AudioRecord采集的音频数据的缓冲区大小;//指定音频源这个和MediaRecorder一样MediaRecorder.AudioSource.MIC指的是麦克风privatestaticfinalintmAudioSource=MediaRecorder.AudioSource.MIC;//指定采样率(MediaRecoder的采样率通常为8000Hz,AAC的采样率通常为44100Hz,采样率设置为44100,这是目前常用的采样率,官方文档说明了这个值与所有设置兼容)privatestaticfinalintmSampleRateInHz=44100;//指定采集音频的通道数。在AudioFormat类中指定用于此的常量privatestaticfinalintmChannelConfig=AudioFormat.CHANNEL_CONFIGURATION_MONO;//Mono//指定音频量化位数,在AudioFormat类中指定了以下可能的常量。通常我们选择ENCODING_PCM_16BIT和ENCODING_PCM_8BITPCM代表脉冲编码调制,实际上是原始音频样本。//所以可以将每个sample的分辨率设置为16-bit或者8-bit,16-bit会占用更多的空间和处理能力,所代表的音频更接近真实。privatestaticfinalintmAudioFormat=AudioFormat.ENCODING_PCM_16BIT;//指定缓冲区大小。可以通过调用AudioRecord类的getMinBufferSize方法获取。privateintmBufferSizeInBytes=AudioRecord.getMinBufferSize(mSampleRateInHz,mChannelConfig,mAudioFormat);//计算最小缓冲区//CreateAudioRecord.AudioRecord类实际上并不保存捕获的音频,因此需要手动创建文件并保存以供下载。privateAudioRecordmAudioRecord=newAudioRecord(MediaRecorder.AudioSource.MIC,mSampleRateInHz,mChannelConfig,mAudioFormat,mBufferSizeInBytes);//创建AudioRecorder对象2.添加音频采集权限CORD_AUDIO"获取过程构造一个AudioRecord对象。开始收集;读取收集的数据;停止收集;采集代码如下:android.view.View;导入android.widget.Button;导入java.io.BufferedOutputStream;导入java.io.DataOutputStream;导入java.io.File;导入java.io.FileOutputStream;导入java.io.IOException;publicclassAudioRecordTestextendsAppCompatActivityimplementsRunnable{privateButtonmBtnStartRecord,mBtnStopRecord;}//指定音频源这个和MediaRecorder一样MediaRecorder.AudioSource.MIC指的是麦克风privatestaticfinalintmAuderSource.MediaRecord=A.MIC;//指定采样率(MediaRecoder的采样率通常为8000Hz,AAC的采样率通常为44100Hz,采样率设置为44100,是目前常用的采样率,官方文档说明这个值兼容所有设置)privatestaticfinalintmSampleRateInHz=44100;//指定采集音频的通道数。在AudioFormat类中指定用于此的常量privatestaticfinalintmChannelConfig=AudioFormat.CHANNEL_CONFIGURATION_MONO;//Mono//指定音频量化位数,在AudioFormat类中指定了以下可能的常量。通常我们选择ENCODING_PCM_16BIT和ENCODING_PCM_8BITPCM代表脉冲编码调制,实际上是原始音频样本。//所以可以将每个sample的分辨率设置为16-bit或者8-bit,16-bit会占用更多的空间和处理能力,所代表的音频更接近真实。privatestaticfinalintmAudioFormat=AudioFormat.ENCODING_PCM_16BIT;//指定缓冲区大小。可以通过调用AudioRecord类的getMinBufferSize方法获取。私有intmBufferSizeInBytes;privateFilemRecordingFile;//存放AudioRecord录制的文件privatebooleanisRecording=false;//true表示录音privateAudioRecordmAudioRecord=null;privateFilemFileRoot=null;//文件目录//存放目录路径NameprivatestaticfinalStringmPathName=getFilesDir()+"/audiioRecordtest";//保存的音频文件名privatestaticfinalStringmFileName="audiorecordtest.pcm";//buffer中的数据写入数据,因为需要IO操作,所以读取数据的过程应该在子线程中执行。私有线程mThread;私有数据输出流mDataOutputStream;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_audio_record);初始化数据();初始化界面();}//初始化数据privatesvoidinitData(){mBufferSizeInBytes=AudioRecord.getMinBufferSize(mSampleRateInHz,mChannelConfig,mAudioFormat);//计算最小缓冲AudioRecord的对象;if(!mFileRoot.exists())mFileRoot.mkdirs();//创建文件夹}//初始化UIprivatevoidinitUI(){mBtnStartRecord=findViewById(R.id.btn_start_record);mBtnStopRecord=findViewById(R.id.btn_stop_record);mBtnStartRecord.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){开始记录();}});mBtnStopRecord.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){stopRecord();}});}//开始录音publicvoidstartRecord(){//AudioRecord.getMinBufferSize参数是否支持当前硬件设备getMinBufferSize");}else{strde();isRecording=true;如果(mThread==null){mThread=newThread(this);mThread.start();//启动线程}}}/***销毁线程方法*/privatevoiddestroyThread(){try{isRecording=false;if(null!=mThread&&Thread.State.RUNNABLE==mThread.getState()){尝试{线程.睡眠(500);mThread.interrupt();}catch(异常e){mThread=null;}}mThread=null;}catch(Exceptione){e.printStackTrace();}最后{mThread=null;}}//停止录音publicvoidstopRecord(){isRecording=false;//停止录音,回收AudioRecord对象,释放内存if(mAudioRecord!=null){if(mAudioRecord.getState()==AudioRecord.STATE_INITIALIZED){//初始化成功}if(mAudioRecord!=null){mAudioRecord.release();}}}@Overridepublicvoidrun(){//标记为开始采集状态isRecording=true;//创建一个Stream,存储从AudioRecord读取的数据mRecordingFile=newFile(mFileRoot,mFileName);if(mRecordingFile.exists()){//音频文件已保存删除mRecordingFile.delete();}try{mRecordingFile.createNewFile();//创建一个新文件}catch(IOExceptione){e.printStackTrace();Log.e("lu","创建和存储音频文件时出错");}try{//获取文件的数据流mDataOutputStream=newDataOutputStream(newBufferedOutputStream(newFileOutputStream(mRecordingFile)));byte[]buffer=newbyte[mBufferSizeInBytes];//判断录音停止时AudioRecord没有初始化释放,状态为STATE_UNINITIALIZED}mAudioRecord.startRecording();//开始录音//getRecordingState获取当前AudioRecording是否正在采集数据的状态0,mBufferSizeInBytes);for(inti=0;i