Android使用MediaRecorder類進行視頻的錄制。
需要注意,使用MediaRecorder 錄音錄像 的設置代碼步驟一定要按照API指定的順序來設置,否則報錯
步驟為:
1、設置視頻源,音頻源,即輸入源
2、設置輸出格式
3、設置音視頻的編碼格式
一、首先看布局文件,這里有一個SurfaceView,這是一個繪制容器,可以直接從內存或者DMA等硬件接口取得圖像數據,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.xqx.mediarecorder.app.WorkRecorder"> <!-- 開始錄制按鈕 --> <Button android:id="@+id/startRecord" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="btnStartRecord" android:text="開始錄制" /> <Button android:id="@+id/stopRecord" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="btnStopRecord" android:text="停止錄制" /> <SurfaceView android:id="@+id/surView" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
二、Activity 代碼
1、首先看下成員變量
// 開始錄制,停止錄制按鈕 private Button startRecord,stopRecord; // 顯示預覽的SurfaceView private SurfaceView surfaceView; // 標記,判斷當前是否正在錄制 boolean isRunning = false; // 錄制類 private MediaRecorder recorder; // 存儲文件 private File saveFile;
2、onCreate()方法中進行一些初始化
startRecord = (Button) findViewById(R.id.startRecord); stopRecord = (Button) findViewById(R.id.stopRecord); surfaceView = (SurfaceView) findViewById(R.id.surView); // onCreate()初始化 ,一開始肯定沒有開始錄制,所以停止按鈕不可點擊 stopRecord.setEnabled(false);
// 設置Surface不需要維護自己的緩沖區 surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 設置分辨率 surfaceView.getHolder().setFixedSize(320, 280); // 設置該組件不會讓屏幕自動關閉 surfaceView.getHolder().setKeepScreenOn(true);
3、現在看“開始錄制”監聽事件
----3.1
創建MediaRecorder對象
recorder = new MediaRecorder(); recorder.reset();
----3.2 設置三步,順序固定
//1.設置采集聲音 recorder.setAudioSource(MediaRecorder.AudioSource.MIC); //設置采集圖像 recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); //2.設置視頻,音頻的輸出格式 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); //3.設置音頻的編碼格式 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); //設置圖像的編碼格式 recorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
----3.3 其他可選設置,更多請查看API
//設置立體聲 recorder.setAudioChannels(2); //設置最大錄像時間 單位:毫秒 recorder.setMaxDuration(600000); //設置最大錄制的大小 單位,字節 recorder.setMaxFileSize(1024*1024); //音頻一秒鍾包含多少數據位 recorder.setAudioEncodingBitRate(128); //設置選擇角度,順時針方向,因為默認是逆向90度的,這樣圖像就是正常顯示了,這里設置的是觀看保存后的視頻的角度 recorder.setOrientationHint(90);
//設置錄像的分辨率
recorder.setVideoSize(176, 144);
----3.4 設置文件存儲路徑,這里簡陋了,實際開發中需要判斷是否有外部存儲,是否有目標目錄 ,是否已經存在相同名字的文件 等問題
//設置輸出文件路徑 saveFile = new File(Environment.getExternalStorageDirectory() .getCanonicalFile() + "/myvideo.mp4");
recorder.setOutputFile(saveFile.getAbsolutePath());
----3.5 使用SurfaceView進行預覽
recorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
----3.6 開始錄制
recorder.prepare(); //開始錄制 recorder.start(); //讓開始按鈕不可點擊,停止按鈕可點擊 startRecord.setEnabled(false); stopRecord.setEnabled(true); isRunning = true;
----3.7 停止錄制
//停止錄制 recorder.stop(); //釋放資源 recorder.release(); recorder = null; //設置開始按鈕可點擊,停止按鈕不可點擊 startRecord.setEnabled(true); stopRecord.setEnabled(false);
完整代碼:

1 package com.xqx.mediarecorder.app; 2 3 import android.app.Activity; 4 import android.media.MediaRecorder; 5 import android.os.Bundle; 6 import android.os.Environment; 7 import android.view.SurfaceHolder; 8 import android.view.SurfaceView; 9 import android.view.View; 10 import android.widget.Button; 11 import android.hardware.Camera; 12 13 import java.io.File; 14 import java.io.IOException; 15 16 public class WorkRecorder extends Activity implements Camera.PreviewCallback { 17 18 // 開始錄制,停止錄制按鈕 19 private Button startRecord,stopRecord; 20 // 顯示預覽的SurfaceView 21 private SurfaceView surfaceView; 22 // 標記,判斷當前是否正在錄制 23 boolean isRunning = false; 24 // 錄制類 25 private MediaRecorder recorder; 26 // 存儲文件 27 private File saveFile; 28 @Override 29 protected void onCreate(Bundle savedInstanceState) { 30 super.onCreate(savedInstanceState); 31 setContentView(R.layout.activity_work_recorder); 32 33 startRecord = (Button) findViewById(R.id.startRecord); 34 stopRecord = (Button) findViewById(R.id.stopRecord); 35 surfaceView = (SurfaceView) findViewById(R.id.surView); 36 37 // onCreate()初始化 ,一開始肯定沒有開始錄制,所以停止按鈕不可點擊 38 stopRecord.setEnabled(false); 39 40 // 設置Surface不需要維護自己的緩沖區 41 surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 42 // 設置分辨率 43 surfaceView.getHolder().setFixedSize(320, 280); 44 // 設置該組件不會讓屏幕自動關閉 45 surfaceView.getHolder().setKeepScreenOn(true); 46 47 } 48 49 /** 50 * 開始錄制 51 * @param view 52 */ 53 public void btnStartRecord(View view) { 54 55 // 首先判斷當前是否處理視頻錄制狀態,只有不是錄制狀態的時候,才可以開始錄制 56 if (!isRunning){ 57 try { 58 //創建MediaRecorder對象 59 recorder = new MediaRecorder(); 60 recorder.reset(); 61 62 63 //1.設置采集聲音 64 recorder.setAudioSource(MediaRecorder.AudioSource.MIC); 65 //設置采集圖像 66 recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 67 //2.設置視頻,音頻的輸出格式 68 recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 69 //3.設置音頻的編碼格式 70 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); 71 //設置圖像的編碼格式 72 recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); 73 74 //設置立體聲 75 recorder.setAudioChannels(2); 76 //設置最大錄像時間 單位:毫秒 77 recorder.setMaxDuration(600000); 78 //設置最大錄制的大小 單位,字節 79 recorder.setMaxFileSize(1024*1024); 80 //音頻一秒鍾包含多少數據位 81 recorder.setAudioEncodingBitRate(128); 82 //設置選擇角度,順時針方向,因為默認是逆向90度的,這樣圖像就是正常顯示了,這里設置的是觀看保存后的視頻的角度 83 recorder.setOrientationHint(90); 84 85 //設置輸出文件路徑 86 // saveFile = FileUtils.getMediaRecoderFolder(this); 87 saveFile = new File(Environment.getExternalStorageDirectory() 88 .getCanonicalFile() + "/myvideo.mp4"); 89 // recorder.setVideoSize(320, 240); 90 // recorder.setVideoFrameRate(20); 91 recorder.setOutputFile(saveFile.getAbsolutePath()); 92 //使用SurfaceView預覽 93 recorder.setPreviewDisplay(surfaceView.getHolder().getSurface()); 94 recorder.prepare(); 95 //開始錄制 96 recorder.start(); 97 //讓開始按鈕不可點擊,停止按鈕可點擊 98 startRecord.setEnabled(false); 99 stopRecord.setEnabled(true); 100 isRunning = true; 101 } catch (IOException e) { 102 e.printStackTrace(); 103 } 104 105 106 } 107 } 108 109 /** 110 * 結束錄制 111 * @param view 112 */ 113 public void btnStopRecord(View view) { 114 if (isRunning){ 115 //停止錄制 116 recorder.stop(); 117 //釋放資源 118 recorder.release(); 119 recorder = null; 120 //設置開始按鈕可點擊,停止按鈕不可點擊 121 startRecord.setEnabled(true); 122 stopRecord.setEnabled(false); 123 } 124 } 125 126 @Override 127 public void onPreviewFrame(byte[] data, Camera camera) { 128 129 } 130 }
本例子只是一個簡單的Demo,用於給剛接觸MediaRecorder音頻錄制的coder學習,存在一些Bug和不足,各位coder可以繼續拓展
不足:
1、只有當點擊“開始錄制”的時候SurfaceView組件才可以看到攝像頭拍攝的預覽,否則是一篇黑,這里可以看下Canera類,進行相應的調整
2、保存路徑,需要判斷是否有外部存儲,存儲空間是否足夠,路徑是否不存在,是否有已有的文件名相同的文件存在等問題,設置文件的名字,我這里是固定路徑固定文件名
3、攝像預覽效果是有90度旋轉的,這里需要大家個人去看下MedioRecoder的API 去進行設置
4、沒有設置對焦,像素不清楚,攝像寬高變形