1. 程式人生 > 其它 >Android平臺 音訊錄製踩坑記

Android平臺 音訊錄製踩坑記

Android平臺 音訊錄製播放主要方式有兩個:  AudioRecord 和 MediaRecord.

AudioRecord 是更底層的類, 能夠實現邊錄邊播, 通過(AudioRecord 和 AudioTrack組合實現湯姆貓應用等)輸出的是pcm語音資料,需要自己實現資料轉碼才能夠播放。

MediaRecord 主要是 用來錄影的,是更偏向於應用層的類。集成了錄音 編碼 壓縮,只支援少量的錄音音訊格式,如3gp amr acc等

AudioRecord 是將採集到的 指定聲音取樣資料的 資訊記錄在一個相關聯的buffer中, 我們可以對裸資料進行操作

// 獲得緩衝區位元組大小      
// 取樣頻率
// 設定音訊的錄製的聲道CHANNEL_IN_STEREO為雙聲道,CHANNEL_CONFIGURATION_MONO為單聲道 // 音訊資料格式:PCM 16位每個樣本。保證裝置支援。PCM 8位每個樣本。不一定能得到裝置支援。 int bufferSizeInBytes = AudioRecord.getMinBufferSize(AudioFileFunc.AUDIO_SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); // 建立AudioRecord物件 第一個引數:音訊獲取源 AudioRecord audioRecord = new
AudioRecord(AudioFileFunc.AUDIO_INPUT, AudioFileFunc.AUDIO_SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes); try { audioRecord.startRecording(); } catch (IllegalStateException e) { e.printStackTrace(); } new Thread(new AudioRecordThread()).start();
// 開啟資料寫入執行緒 class AudioRecordThread implements Runnable { @Override public void run() { writeDateToFile();//往檔案中寫入資料 listener.onSpeechOver(0); } } private static void writeDateTOFile() { // new一個byte陣列用來存一些位元組資料,大小為緩衝區大小 final byte[] audiodata = new byte[bufferSizeInBytes]; FileOutputStream fos = null; try { File file = new File(currentFilePath); if (file.exists()) { file.delete(); } file.createNewFile(); fos = new FileOutputStream(file);// 建立一個可存取位元組的檔案 } catch (Exception e) { e.printStackTrace(); } while (mIsRecording == true) { final int size = audioRecord.read(audiodata, 0, bufferSizeInBytes); if (AudioRecord.ERROR_INVALID_OPERATION != size) { try { fos.write(audiodata); calculateVolume(audiodata, 0, size); } catch (IOException e) { e.printStackTrace(); } } } try { fos.close();// 關閉寫入流 } catch (IOException e) { e.printStackTrace(); } } private void close() { if (audioRecord != null) { mIsRecording = false;//停止檔案寫入 try { audioRecord.stop(); audioRecord.release();//釋放資源 } catch (Exception e) { e.printStackTrace(); } audioRecord = null; } }

MediaRecord:直接指定輸出檔案 中間過程進行程式介入不太方便。

MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(OUTPUT_FILENAME);
recorder.prepare();
recorder.start();
...
recorder.stop();
recorder.release();
// reset 之後相當於整個record重新構造
recorder.reset();