行业知识
Android 录音AudioRecord
2026-10-26 07:12:00
来源:互联网转载
AudioRecord是安卓多媒体框架中用于录制音频的工具。它支持录制原始音频数据,即PCM数据,PCM数据不能被播放器直接播放,需要编码压缩成常见音频格式才能被播放器识别。通常生成PCM文件之后可将PCM文件转成WAV文件一般的播放器便可直接播放了。
()接下来处理AudioRecord操作。
1.初始化AudioRecord
()先了解几个概念:
audioSource:音频来源sampleRateInHz:采样率,以赫兹为单位。目前,只有44100Hz是保证在所有设备上都可以使用的速率(最适合人耳的),但是其他速率(例如22050、16000和11025)可能在某些设备上可以使用;如果用于语音识别的话根据不同厂商需要采用不同的采样率channelConfig:音频通道的配置audioFormat:音频数据的格式bufferSizeInBytes:在录制期间写入音频数据的缓冲区的总大小(以字节为单位)
初始化操作:
int mBufferSize = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)*2;AudioRecord mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 16000, AudioFormat.CHANNEL_IN_MONO,//双声道 AudioFormat.ENCODING_PCM_16BIT, mBufferSize);
2.开始录音
/** * 录制pcm文件 * @param pcmFilePath pcm文件路径 */ public void startRecord(String pcmFilePath) { if (isRecord) { return; } this.mPcmFilePath=pcmFilePath; isRecord = true; RecordThread recordThread = new RecordThread(); mExecutorService.execute(recordThread); } class RecordThread implements Runnable { @Override public void run() { mAudioRecord.startRecording(); FileOutputStream fos = null; try { Log.i(TAG, "文件地址: " + mPcmFilePath); fos = new FileOutputStream(mPcmFilePath); byte[] bytes = new byte[mBufferSize]; while (isRecord) { mAudioRecord.read(bytes, 0, bytes.length); fos.write(bytes, 0, bytes.length); fos.flush(); } Log.i(TAG, "停止录制"); mAudioRecord.stop(); fos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } } 3.结束录音
/** * 停止录制 */ public void stopRecord() { isRecord = false; } 4.将录音生成的pcm文件转成wav文件
/** * pcm文件转wav文件 * @param pcmFile pcm文件 * @param wavFile wav文件 */ public void pcm2Wav(File pcmFile, File wavFile) { if (!pcmFile.exists()){ throw new RuntimeException(pcmFile.getAbsolutePath()+",there is no pcm file"); } mExecutorService.execute(new PcmToWavThread(pcmFile,wavFile)); } class PcmToWavThread implements Runnable { File pcmFile; File wavFile; public PcmToWavThread(File pcmFile, File wavFile) { this.pcmFile = pcmFile; this.wavFile = wavFile; } @Override public void run() { if (!wavFile.exists()){ try { wavFile.createNewFile(); PcmToWavUtil util=new PcmToWavUtil(mSampleRate,mChannel,mFormat); util.pcmToWav(pcmFile.getAbsolutePath(),wavFile.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } } } } pcm文成wav文件方法如下:
/** * pcm文件转wav文件 * * @param inFilename 源文件路径 * @param outFilename 目标文件路径 */ public void pcmToWav(String inFilename, String outFilename) { FileInputStream in; FileOutputStream out; long totalAudioLen;//总录音长度 long totalDataLen;//总数据长度 long longSampleRate = mSampleRate; int channels = mChannel == AudioFormat.CHANNEL_IN_MONO ? 1 : 2; long byteRate = 16 * mSampleRate * channels / 8; byte[] data = new byte[mBufferSize]; try { in = new FileInputStream(inFilename); out = new FileOutputStream(outFilename); totalAudioLen = in.getChannel().size(); totalDataLen = totalAudioLen + 36; writeWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate); while (in.read(data) != -1) { out.write(data); out.flush(); } Log.e(TAG, "pcmToWav: 停止处理"); in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 加入wav文件头 */ private void writeWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate, int channels, long byteRate) throws IOException { byte[] header = new byte[44]; // RIFF/WAVE header header[0] = 'R'; header[1] = 'I'; header[2] = 'F'; header[3] = 'F'; header[4] = (byte) (totalDataLen & 0xff); header[5] = (byte) ((totalDataLen >> 8) & 0xff); header[6] = (byte) ((totalDataLen >> 16) & 0xff); header[7] = (byte) ((totalDataLen >> 24) & 0xff); //WAVE header[8] = 'W'; header[9] = 'A'; header[10] = 'V'; header[11] = 'E'; // 'fmt ' chunk header[12] = 'f'; header[13] = 'm'; header[14] = 't'; header[15] = ' '; // 4 bytes: size of 'fmt ' chunk header[16] = 16; header[17] = 0; header[18] = 0; header[19] = 0; // format = 1 header[20] = 1; header[21] = 0; header[22] = (byte) channels; header[23] = 0; header[24] = (byte) (longSampleRate & 0xff); header[25] = (byte) ((longSampleRate >> 8) & 0xff); header[26] = (byte) ((longSampleRate >> 16) & 0xff); header[27] = (byte) ((longSampleRate >> 24) & 0xff); header[28] = (byte) (byteRate & 0xff); header[29] = (byte) ((byteRate >> 8) & 0xff); header[30] = (byte) ((byteRate >> 16) & 0xff); header[31] = (byte) ((byteRate >> 24) & 0xff); // block align header[32] = (byte) (2 * 16 / 8); header[33] = 0; // bits per sample header[34] = 16; header[35] = 0; //data header[36] = 'd'; header[37] = 'a'; header[38] = 't'; header[39] = 'a'; header[40] = (byte) (totalAudioLen & 0xff); header[41] = (byte) ((totalAudioLen >> 8) & 0xff); header[42] = (byte) ((totalAudioLen >> 16) & 0xff); header[43] = (byte) ((totalAudioLen >> 24) & 0xff); out.write(header, 0, 44); } 5.释放资源
/** * 释放资源 */ public void release() { if (mAudioRecord != null) { mAudioRecord.release(); } if (mExecutorService!=null){ mExecutorService.shutdown(); } } 至此录音功能即可实现了,如果想要测试可以直接使用MediaPlayer方法进行录音播放