標準的支持錄製的類是MediaRecorder。和Media Player類似,MediaRecorder在其生命週期內也會傳遞各種狀態。這些狀態如下所示(關於這些狀態的更多詳細信息,可以查看開發者網站中給出的狀態圖,http://developer.android.com/reference/android/media/MediaRecorder.html):
Initial
MediaRecorder類執行實例化。
Initialized
MediaRecorder執行了初始化,可以使用了。
DataSource Configured
對媒體資源(指定在哪裡輸出)進行配置。
Prepared
準備好MediaRecorder,用於記錄。
Recording
正在執行記錄。
Released
釋放所有的資源。
要使用MediaRecorder,在清單文件中要設置某些許可:
·要支持視頻記錄,選擇RECORD_VIDEO和CAMERA:
<uses-permission android:name=\"android.permission.RECORD_VIDEO\"/> <uses-permission android:name=\"android.permission.CAMERA\"/>
·要記錄音頻,選擇:
<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>
錄製音頻
有3種錄製音頻的方式。標準方式是使用MediaRecorder;最簡單的方式是使用Intent;AudioRecorder可以直接從硬件緩衝區中錄製。
MediaRecorder音頻錄製
首先,初始化MediaRecorder。然後設置數據源信息(音頻輸入源、輸出格式、編碼類型,在哪裡錄製文件等)。從版本8開始,還可以設置比特率和樣本比率。完成這些後,調用prepare方法。
// initialize the MediaRecorder MediaRecorder mediarecorder = new MediaRecorder; // configure the data source // the source of the audio input mediarecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // output format mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); // encoding mediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // use absolute path to file where output is stored mediarecorder.setOutputFile(\"/sdcard/audiorecordexample.3gpp\"); // prepare to record mediarecorder.prepare;
然後,當需要啟動錄製時,執行start方法:
mediarecorder.start;
要停止錄製,可以調用stop方法。如果後來又想繼續錄製,則可以調用reset方法強制MediaRecorder回到空閒狀態。然後重新配置數據源,再次準備MediaRecorder:
mediarecorder.stop; ... mediarecorder.reset;
一旦不再需要MediaRecorder,要記得釋放它:
mediarecorder.release;
下面是一個簡單的應用示例,它為用戶提供record按鈕。單擊該按鈕,record方法會在已經指向的文件路徑下錄製。然後,會顯示stop按鈕,record按鈕會變得不可見。當單擊stop按鈕時,會調用stopRecord方法,又重新顯示record按鈕。
public class AudioRecorder extends Activity { private MediaRecorder mediarecorder; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.audiorecorderlayout); ImageButton recordbutton = (ImageButton) findViewById(R.id.record); recordbutton.setOnClickListener(new OnClickListener { public void onClick(View v) { record(\"/sdcard/audiorecordexample.3gpp\"); } }); ImageButton stopbutton = (ImageButton) findViewById(R.id.stop); stopbutton.setOnClickListener(new OnClickListener { public void onClick(View v) { stopRecord; } }); } private void record(String filePath) { try { File mediafile = new File(filePath); if(mediafile.exists) { mediafile.delete; } mediafile = null; // record button goes away ImageButton button = (ImageButton) findViewById(R.id.record); button.setVisibility(View.GONE); // stop button shows up ImageButton stopbutton = (ImageButton) findViewById(R.id.stop); stopbutton.setVisibility(View.VISIBLE); // set up media recorder if(mediarecorder == null) mediarecorder = new MediaRecorder; mediarecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mediarecorder.setOutputFile(filePath); // prepare media recorder mediarecorder.prepare; // start media recorder mediarecorder.start; } catch (Exception e) { e.printStackTrace; } } } private void stopRecord { // stop media recorder mediarecorder.stop; // reset media recorder mediarecorder.reset; // record button shows up ImageButton button = (ImageButton) findViewById(R.id.record); button.setVisibility(View.VISIBLE); // stop button goes away ImageButton stopbutton = (ImageButton) findViewById(R.id.stop); stopbutton.setVisibility(View.GONE); } }
使用Intent錄製音頻
通過Intent錄製是最簡單的方式。只需要構建Media Store.Audio.Media.RECORD_SOUND_ACTION intent,然後在Activity內調用startActivityForResult方法啟動它,它會啟動在大多數Android設備中都會提供的默認音頻錄製程序,繼續錄製一些音頻:
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); startActivityForResult(intent, 1); // intent and requestCode of 1
錄製完成後,音頻錄製程序結束,啟動調用startActivityForResult方法的Activity會到前端執行。當發生這種情況時,會觸發Activity的onActivityResult方法,其中包括了我們提供的requestCode代碼(在這個例子中,即1),結果代碼(OK或error),以及包含指向記錄的音頻文件的intent:
protected void onActivityResult(int requestCode, int resultCode, Intent intent) { // is it our requestCode? if (requestCode == 1) { // is the resultCode OK? if (resultCode == RESULT_OK) { // lets get the uri Uri audioUri = intent.getData; // lets play the uri or do something with it. playAudio(audioUri); } } }
AudioRecorder音頻錄製
和AudioTrack類似,AudioRecorder提供了更直接的錄製體驗:
short buffer = new short[10000]; recorder = new AudioRecord( // source to record from MediaRecorder.AudioSource.MIC, // frequency 11025, // channel config —mono, stereo, etc. AudioFormat.CHANNEL_CONFIGURATION_MONO, // audio encoding AudioFormat.ENCODING_PCM_16BIT, // buffer size buffer.length );
AudioRecord方法提供了需要錄製的音頻資源類型(話筒、攝像機話筒、或語音呼叫)、以Hz表示的採樣比率(44100、22050或11025)、音頻配置(單聲道或立體聲)、音頻格式/編碼、以字節數表示的緩衝區長度。注意,緩衝區的大小決定了AudioRecord在讀取運行數據之前能夠錄製的時間。數據應該從音頻硬件中讀取,以小於總錄製緩衝區的大小讀取。Android的AudioRecord一旦配置完成,會自動知道如何使用設備上的硬件接口,從而提供愉快的用戶體驗。
為開始錄製,設置AudioRecord的Record狀態,重複從硬件緩衝區中讀取數據:
recorder.startRecording; while(recordablestate) { try { // read in up to buffer size int readBytes = recorder.read(buffer, 0, buffer.length); // do something with the bytes that are read } catch (Exception t) { recordablestate = false; } }
要停止錄製,將AudioRecord的狀態置為Stop。如果不想錄製,則不要忘記釋放和錄製相關的所有資源。如果還想繼續錄製,可以調用startRecording方法再開始錄製:
// stop recording recorder.stop; // release recording resources recorder.release;
視頻錄製
可以通過兩種方式錄製視頻:通過使用MediaRecorder或通過使用Intent。不支持類似音頻那樣的原始錄製。
MediaRecorder視頻錄製
通過MediaRecorder錄製視頻的過程和錄製音頻的過程非常相似:初始化MediaRecorder,準備數據源,啟動MediaRecorder。可以給用戶提供預覽窗口,這樣他可以預覽捕捉到的視頻,通過提供之前提到的surface來播放視頻。一般來說,會使用VideoView:
// initialize MediaRecorder mediarecorder = new MediaRecorder; // set data source mediarecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); mediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); mediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); mediarecorder.setOutputFile(\"/sdcard/someexamplevideo.mp4\"); // provide a surface to show the preview in. in this case a VideoView is used videoview = (VideoView) findViewById(R.id.videosurface); SurfaceHolder holder = videoview.getHolder; mediarecorder.setPreviewDisplay(holder.getSurface); // prepare mediarecorder.prepare; // start recording mediarecorder.start;
intent視頻錄製
基於intent的視頻錄製和使用intent錄製音頻類似。要使用的intent是MediaStore.ACTION_VIDEO_CAPTURE,結果數據是視頻文件的URI。