對於錄制音頻,Android系統就都自帶了一個小小的應用,可是使用起來可能不是特別的靈活。所以有提供了另外的倆種。
下邊來介紹下這三種錄制的方式;
1、通過Intent調用系統的錄音器功能,然后在錄制完畢保存以后在onActivityResult中返回錄制的音頻的uri,然后通過Mediaplayer進行播放
調用系統的錄音器
private final static int REQUEST_RECORDER = 100; private Uri uri; public void recorder_Intent(){ Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); startActivityForResult(intent,REQUEST_RECORDER); }獲取返回的信息
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && REQUEST_RECORDER == requestCode){ uri = data.getData(); } }<span style="background-color: rgb(255, 255, 255);"><span style="font-size:24px;">通過Mediaplayer進行播放</span></span>if (uri != null){ if (mediaPlayer != null) { try { mediaPlayer.reset(); mediaPlayer.setDataSource(RecorderActivity.this, uri); mediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } }else Toast.makeText(RecorderActivity.this,"沒有成功創建Mediaplayer",Toast.LENGTH_SHORT).show(); }
2、通過MediaRecorder來進行音頻的錄制:
MediaRecorder 類可用於音頻和視頻的捕獲。再構造了一個MediaRecorder對象之后,為了捕獲音頻,必須調用setAudioEncoder和setAudioSource這倆個方法。
假設不調用這些方法,那么將不會錄制音頻(視頻也相同不會),另外,MediaRecorder在准備錄制之前通常還會調用setOutputFormat 和setOutputFile,
在實例化MediaRecorder之后。應該調用的第一個方法是setAudioSource。它採用一個AudioSource內部類中定義的常量作為參數,我們通常使用的常量是MediaRecorder。
AudioSource.MIC.
依據順序,下一個調用的就是setOutputFormat ,這種方法採用在MediaRecorder.OutputFormat內部類中指定的常量作為參數:
(1)MediaRecorder.OutputFormat.MPEG_4:這個常量指定輸出的文件將是一個MPEG_4文件,包括音頻跟視頻軌
(2)MediaRecorder.OutputFormat.RAW_AMR;這個常量表示輸出一個沒有不論什么容器類型的原始文件,僅僅有在捕獲沒有視頻的音頻且音頻編碼器是AMR_NB時才會使用這個常量。
(3)MediaRecorder.OutputFormat.THREE_GPP:這個常量指定輸出的文件將是一個3gpp文件(.3gp)。它可能同一時候包括音頻跟視頻軌
MediaRecorder音頻編碼。在設置輸出格式之后,能夠調用setAudioEncoder方法來設置應該使用編碼器,可能的值指定為MediaRecorder.AudioEncoder類中的常量。出來使用DEFAULT之外,僅僅存在一個其它的值:MediaRecorder.AudioEncoder.AMR_NB,這是自適應多速率窄帶編解碼器。
這樣的編解碼器針對語音進行了優化,因此不適應於語音之外的其它內容。默認情況下他的採樣率是8kHz,碼率在 4.75~12.2kbps之間。這個倆個數據對於錄制語音之外的其它內容而言很低。可是,這是當前可用於MediaRecorder的唯一選擇。
下來就看代碼的實現:
這是錄制的代碼:
private MediaRecorder mediaRecorder = new MediaRecorder(); private File audioFile; public void recorder_Media(){ mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); File path = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Android/data/com.example.chengpengfei_d.recorderdemo/files"); path.mkdirs(); amplitude = new RecordAmplitude(); try { audioFile = File.createTempFile("recording",".3gp",path); mediaRecorder.setOutputFile(audioFile.getAbsolutePath()); mediaRecorder.prepare(); mediaRecorder.start(); isRecording = true; amplitude.execute(); } catch (IOException e) { e.printStackTrace(); } }
這是播放的代碼
case FLAG_MEDIA: isRecording = false; amplitude.cancel(true); mediaRecorder.stop(); mediaRecorder.release(); mediaPlayer.reset(); try { mediaPlayer.setDataSource(audioFile.getAbsolutePath()); mediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } break;
3 使用AudioRecord錄制原始音頻:
這就是第三種捕獲音頻的方法。使用AudioRecord的類。AudioRecord是三個方法中最靈活的(由於他同意訪問原始音頻流),可是他是擁有最少的內置功能。如不會自己主動壓縮音頻等等。
使用AudioRecord的基礎知識很easy。我們僅僅須要構造一個AudioRecord類型的對象,並傳入各種不同配置參數。
須要制定的第一個值就是音頻源。以下使用值與之前用於MediaRecorder的值同樣,其在MediaRecorder.AudioSource 中定義。實際上。這意味着能夠使用MediaRecorder.AudioSource.MIC;
int audiosource = MediaRecorder.AudioSource.MIC;
須要指定的下一個值是錄制的採樣率,應以赫茲為單位,我們知道。MediaRecorder採樣的音頻是8000赫茲。而CD質量的音頻一般是44100赫茲(44100Hz)。Hz或赫茲是每秒的樣本數量。
不同的Android手機硬件將可以以不同的採樣率進行採樣。對於我的這個樣例將以11025Hz的採樣率來進行採樣,這是一個經常使用的採樣率。
int sampleRateInHz = 11025;
接下來,須要指定捕獲的音頻通道的數量,在AudioFormat類中指定了用於此參數的常量。並且可依據名稱理解他們。

如今將使用單聲道配置。
int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
隨后。須要指定音頻格式。在AudioFormat類中也指定了一下各種可能的常量。
在這四個選擇中,我們選擇PCM_16位和PCM 8位。PCM代表脈沖編碼調制(Pulse Code Modulation) 他實際上是原始的音頻樣本。
因此能夠設置每一個樣本的分辨率為16位或8位。16位將占用很多其它的控件和處理能力,但表示的音頻將更接近真實。
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
最后將須要指定緩沖區大小。時間上能夠查詢AudioRecord類以獲得最小緩沖區大小。查詢方式是調用getMinBufferSize的靜態方法,同一時候傳入採樣率,通道配置以及音頻格式。
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,channelConfig ,audioFormat);
下邊就看實際的代碼吧:
主要分倆個方法,還有些初始化的代碼:
private boolean isPlaying = false; private int frequency = 11025; int audioFormat = AudioFormat.ENCODING_PCM_16BIT; int audiosource = MediaRecorder.AudioSource.MIC; int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; File recordingFile = null; RecordAudio recordAudio = null; PlayAudio playAudio = null; public void recorder_Audio() throws IOException { //AudioRecord不會直接保存音頻。須要自己保存 File path = new File(Environment.getExternalStorageDirectory().getAbsolutePath()); path.mkdirs(); try { recordingFile = File.createTempFile("recording", ".pcm", path); } catch (IOException e) { e.printStackTrace(); } recordAudio = new RecordAudio(); recordAudio.execute(); } public void playRecorder() { isRecording = false; playAudio = new PlayAudio(); playAudio.execute(); } //播放錄制音頻的異步任務 private class PlayAudio extends AsyncTask<Void,Integer,Void>{ @Override protected Void doInBackground(Void... params) { isPlaying = true; int bufferSize = AudioTrack.getMinBufferSize(frequency,channelConfig,audioFormat); short[] buffer = new short[bufferSize / 4]; DataInputStream dis= null; try { dis = new DataInputStream(new BufferedInputStream(new FileInputStream(recordingFile))); } catch (FileNotFoundException e) { e.printStackTrace(); } AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,frequency,channelConfig,audioFormat,bufferSize,AudioTrack.MODE_STREAM); audioTrack.play(); try { while(isPlaying && dis.available() > 0 ){ int i = 0; while(dis.available() > 0 && i < buffer.length){ buffer[i] = dis.readShort(); i++; } audioTrack.write(buffer,0,buffer.length); } dis.close(); } catch (IOException e) { e.printStackTrace(); } return null; } } <span style="white-space:pre"> </span>//錄制音頻的一個異步任務; private class RecordAudio extends AsyncTask<Void,Integer,Void>{ @Override protected Void doInBackground(Void... params) { isRecording = true; DataOutputStream dos = null; try { dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(recordingFile))); int bufferSize = AudioRecord.getMinBufferSize(frequency,channelConfig,audioFormat); AudioRecord audioRecord = new AudioRecord(audiosource,frequency,channelConfig,audioFormat,bufferSize); short [] buffer = new short[bufferSize]; audioRecord.startRecording(); int r = 0; while(isRecording){ int bufferReadResult = audioRecord.read(buffer,0,bufferSize); for (int i = 0; i<bufferReadResult; i++){ try { dos.writeShort(buffer[i]); } catch (IOException e) { e.printStackTrace(); } } publishProgress(new Integer(r)); r++; } audioRecord.stop(); dos.close(); } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); mTv_progress.setText(values[0] + ""); } }
至此三種方式也就完了,這是一個關於音頻錄制的實例。通過三種不同方式的錄制來達到同樣的目的。可是要了解。三種的優缺點。假設想看實際效果,下載以后執行下看看吧。本實例是在Android studio中開發,假設Ecplise的話那么直接移植代碼,以及清單文件的內容,應該就能夠,假設不行能夠聯系我。
下載地址:http://download.csdn.net/detail/u012808234/9482926