AndroidCamera1---設置攝像頭方向、打開線程與預覽線程、設置參數、Camera外設按鍵、自動對焦與觸摸對焦、拍照、人臉檢測、位置管理、旋轉管理、變焦、錄像


1. 設置攝像頭方向

2. 打開線程與預覽線程 

3. 設置參數

4. Camera外設按鍵

5. 自動對焦與觸摸對焦

6. 拍照

7. 人臉檢測

8. 位置管理

9. 旋轉管理

10. 變焦

11. 錄像




Camera的架構為典型的C/S架構,Client端,用戶的行為,是為應用程序進程,Server端,設備的功能,是為Camera服務守護進程,客 戶端進程承載用戶的需求,由Binder進程間通信送往服務端實現設備的功能,服務端由回調函數和消息機制反饋數據返還給用戶。

ps查看進程,類似 com.android.camera是為客戶端Camera進程,/system/bin/mediaserver是為服務端守護進程,由系統啟動時開啟。


1. 設置攝像頭方向

Framework框架層的Camera對象(camera.java)里有一個類class CameraInfo,里面存放了兩個公有成員變量facing和orientation,即我們要討論的前后置和方向。 程序第一次初始化時initializeFirstTime(),通過getCameraInfo()得到前后置和方向的信息,客戶端發送請求 getCameraInfo()詢問服務端,服務端調用抽象層拿數據,抽象層參考底層camera sensor驅動的數據facing和orientation,這兩個值在驅動里是寫死的,不能由用戶改變,camera程序啟動以后就把它們作為全局變 量存放起來。

1.1 前置與后置

后置back camera背對手機屏幕,朝外,像素高,前置front camera,面對自己,朝內,像素低。

1.2 方向

攝像頭模組有長邊和短邊,比如采集圖像的比例為4:3,那么4為長邊,3為短邊。設備屏幕也有長邊和短邊,理論上,攝像頭模組的長邊不能與屏幕的長邊垂直,至於為什么呢,我語文水平太差,沒辦法很好地表達出來...總之目的就是為了顯示效果。


2 打開線程與預覽線程

onCreate()里會先后開啟CameraOpenThread和CameraPreviewThread。

打開camera還需要線程?CameraOpenThread名為打開,實為C/S connect連接服務端,binder進程間通信,開銷較大。預覽線程必須在打開線程完成以后執行,它貫穿始終直到進程消亡為止,整個預覽過程相對復 雜,在抽象層和底層驅動實現,概括講,預覽線程再開啟兩個線程,一個拿sensor的frame,一個送往framebuffer經 surfaceflinger顯示出來。


3 設置參數

預覽拍照錄像之前,用戶需要設置很多參數,比如閃光,白平衡,場景,對比度等。

程序里這些參數保存在SharedPreferences共享優選項和Parameters兩個地方,Preferences包含Parameters, 打開程序讀取優選項參數,關閉程序保存優選項參數,考慮到用戶經常會調整參數,引入Parameters來保存從打開以后到關閉以前這個中間過程的參數變 量,Parameters的鍵值由抽象層根據硬件sensor的能力決定。


4. Camera外設按鍵

Manifest里注冊broadcast receiver,

        <receiver android:name="com.android.camera.CameraButtonIntentReceiver">
            <intent-filter>
                <action android:name="android.intent.action.CAMERA_BUTTON"/>
            </intent-filter>
        </receiver>

有些手機上有camera按鍵,用戶按下按鍵,android輸入系統有兩種實現方法,

1)發送廣播CAMERA_BUTTON,收到廣播后開啟主Activity。

2)上報鍵值KEYCODE_CAMERA,程序收到消息,可自定義實現功能,比如拍照。

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_CAMERA:
                if (mFirstTimeInitialized && event.getRepeatCount() == 0) {
                    onShutterButtonClick();
                }
                return true;


5. 自動對焦與觸摸對焦

外界事物由光線經凸透鏡聚焦到sensor上成像,camera模組開啟馬達前后平移鏡頭取得最佳成像效果,這個過程稱之為對焦。

5.1 自動對焦

1) camera模組會因感光強度變化而自動開啟對焦,驅動控制。

2) 用戶長按快門,軟件控制自動對焦。

3) 用戶按下快門拍照,拍攝前自動對焦。

程序里,Camera對象實現類ShutterButton的接口OnShutterButtonListener里的方法 onShutterButtonFocus(boolean pressed)和onShutterButtonClick(),后者是拍照,下節討論,先看 onShutterButtonFocus(boolean pressed),這個pressed判斷是否為一次有效的長按,如果是的話,執行autoFocus(),這個autoFocus()也是Camera 對象實現類FocusManager的接口Listener里的方法,由binder交給camera service,最后在底層驅動實現自動對焦。

5.2 觸摸對焦

自動對焦的對焦區域位於屏幕正中,用戶也可觸摸特定區域對焦。

Camera對象實現類View的接口OnTouchListener里的方法onTouch(),輸入系統上報MotionEvent的xy坐標,保存在Parameters,執行autoFocus(),抽象層讀取Paramters的觸摸點坐標,實現區域對焦。


6. 拍照

拍照分四步,對焦,拍照,接收圖片,保存圖片。

mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback,
                mPostViewPictureCallback, new JpegPictureCallback(loc));

需要理解四個回調函數,參考上一篇文章。

1)對焦

拍照前如果已經區域對焦,則取消自動對焦,反之,開啟一次自動對焦。對焦完成后,底層發送對焦成功與否的消息給camera對 象,FocusManager把狀態mState保存起來,如果正在對焦未完成(mState == STATE_FOCUSING)則不可拍照,直到對焦完畢。

2)拍照

onShutterButtonClick() -> doSnap() -> capture() -> takePicture(),具體實現在抽象層和底層驅動,實質就是拿一張預覽的圖像,抽象層讀取拍照時的Parameters參數配置,包括用戶選擇的 照片大小。

3)接收圖片

通過回調,由底層發送圖片給camera對象。

RawPictureCallback,得到原始圖片,需要軟件壓縮Jpeg。(YUV轉Jpeg)

JpegPictureCallback,直接得到Jpeg圖片,需要硬件壓縮Jpeg。

PostViewPictureCallback,拍完后預覽圖片。

4)保存圖片

交由線程ImageSaver保存圖片和生成thumbnails。

默認路徑位於/mnt/sdcard/DCIM/Camera/


7. 人臉檢測

人臉檢測可以軟件實現,可以硬件實現,軟件實現增加CPU開銷,硬件實現增大耗電,鼓勵硬件實現...

上層Camera對象實現了 framework層Camera的接口FaceDetectionListener的方法onFaceDetection(Face[] faces, Camera camera),回調機制同上,硬件sensor識別臉部信息,發送face給camera對象,framework定義face的特征,比如眼睛,嘴 巴,上層保存mFaces數據,更新UI。


8. 位置管理

位置管理LocationManager用來記錄拍攝圖片的GPS位置信息(經維度),存入JPEG頭部插入的Exif里。

用戶在菜單“相機設置”里的"保存所在位置"選擇打開(前提是GPS已開啟),屏幕左上方會出現一個GPS圖標,表示現在可以記錄GPS信息了。

程序里,Camera對象實現了位置管理監聽器LocationManager.Listener的接口showGpsOnScreenIndicator()和hideGpsOnScreenIndicator(),顯示或者隱藏GPS圖標。

程序第一次初始化時initializeFirstTime(),通過讀取優選項Preference得到bool值recordLocation,判斷 是否需要記錄GPS信息,如果需要,在拍照capture()里調用LocationManager的方法得到Location loc,並將其存入Exif。


9. 旋轉管理

假設一台手機,camera正常安裝,豎直方向作為默認方向(orientation == 0)拍攝照片,即拍攝“肖像照”(portrait),得到的照片顯示在屏幕上也是豎直方向。

如果把手機旋轉90度水平過來拍攝“山水照”(landscape),對於camera sensor來說,沒有旋轉的概念,所以軟件上要把圖片旋轉90度回來。



軟件上,需要借助方向監聽器隨時更新方向信息,並保存在Parameters里,抽象層實現拍照功能時從Parameters里讀取方向。

具體的,camera對象內部類MyOrientationEventListener的方法onOrientationChanged()保存方向 orientation的值,MyOrientationEventListener繼承 OrientationEventListener,OrientationEventListener的onSensorChanged()把從 sensorManager拿到的xyz坐標轉換成方向。

程序啟動,注冊sensor監聽器並使能,sensorManager不斷上報底層sensor數據,通過消息機制發送到camera對象,后者計算坐標 數據得到方向orientation的值(實際外包給orientationListener完成),最后保存Parameters。


10. 變焦

用戶拖動Zoom橫條可放大縮小預覽畫面連續變焦,另一種所謂狀態變焦,其原理是一樣的。

camera對象的內部類ZoomChangeListener實現ZoomControl的方法,實質是把變焦的任務全權交給ZoomControl。 ZoomControl監聽處理用戶的觸摸事件dispatchTouchEvent(),用來得到並處理變焦倍數 mListener.onZoomValueChanged(index),它由mCameraDevice.startSmoothZoom()通過 binder交給camera service,camera service再通過sendComand命令機制交給抽象層實現變焦,抽象層開啟變焦線程,變焦改變預覽,通過回調機制發送消息 CAMERA_MSG_ZOOM把變焦倍數返還給camera對象,最終camera對象收到消息 后,ZoomListener.onZoomChange()把變焦倍數保存到Parameters.


11. 錄像

ModePicker負責切換模式,一共有三種模式,普通模式,錄像模式和全景模式,Manifest里依次聲明這三個activity。

切換模式,銷毀原有activity,開啟新activity,伴隨關閉preview,重啟preview,保存配置,讀取配置,開銷很大。

錄像VideoCamera.java同預覽Camera.java的思路類似,按下錄像按鈕,程序監聽用戶事件,開啟錄像,錄像交給MediaRecoder,StagefrightRecorder負責。


 

核心提示: 如何獲取Android設備上的詳細的攝像頭信息呢? 目前Samsung的Galaxy Tab和Nexus S均有前置攝像頭,獲取Android攝像頭的詳細信息,Android獲取攝像頭詳細信息,在Android 2.3 SDK中得到了增強:在android.hardware.Camera類中,API Level 9的S

如何獲取Android設備上的詳細的攝像頭信息呢? 目前Samsung的Galaxy Tab和Nexus S均有前置攝像頭,獲取Android攝像頭的詳細信息,在Android 2.3 SDK中得到了增強:

在android.hardware.Camera類中,API Level 9的SDK中加入了兩個比較重要的方法,使用getNumberOfCameras這個static類型方法可以獲取當前Android設備上的攝像頭數 量,比如Nexus S有兩個,方法原型如下

[java]  view plain copy
 
  1. publicstaticint getNumberOfCameras ()  

而對於具體的每個攝像頭的信息,可以通過Camera類的getCameraInfo()這個靜態方法獲取,該方法有兩個參數,參數一的ID,我們 通過getNumberOfCameras獲取的值減1即可,類似數組索引從0開始一樣,用循環遍歷每個攝像頭信息,參數二是 android.hardware.Camera.CameraInfo類,有關getCameraInfo方法的原型如下:

[java]  view plain copy
 
  1. publicstaticvoidint cameraId, Camera.CameraInfo cameraInfo)  

對於Camera.CameraInfo類而言,比較簡單,包含兩個字段

public int facing 代表攝像頭的方位,目前有定義值兩個分別為CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK后置
public int orientation下面是拍照的旋轉方向,一般自然些有0度、90度、180度和270度,這樣可以獲取我們正確的手握設備是橫着還是豎着,有關拍照時的方向設置,可以參考下面的代碼設置

[java]  view plain copy
 
  1. publicstaticvoid int new int int;<br>  
  2. switch casebreak casebreak casebreak casebreak int if ;<br>  
  3.  - result) % ;  
  4. else  
  5. ) % ;<br>  
  6. }  










 

Android Camera 使用小結

Android手機關於Camera的使用,一是拍照,二是攝像,由於Android提供了強大的組件功能,為此對於在Android手機系統上進行 Camera的開發,我們可以使用兩類方法:一是借助Intent和MediaStroe調用系統Camera App程序來實現拍照和攝像功能,二是根據Camera API自寫Camera程序。由於自寫Camera需要對Camera API了解很充分,而且對於通用的拍照和攝像應用只需要借助系統Camera App程序就能滿足要求了,為此先從調用系統Camera App應用開始來對Android Camera做個簡單的使用小結。

調用系統Camera App實現拍照和攝像功能

不是專門的Camera應用,一般用到Camera的需求就是獲取照片或者視頻,比如微博分享、隨手記等,對於在Symbian系統上通過簡單地調用系統 自帶的Camera APP來實現該功能是做不到的,但是Android系統強大的組件特性,使得應用開發者只需通過Intent就可以方便的打開系統自帶的Camera APP,並通過MediaStroe方便地獲取照片和視頻的文件路徑。具體我們還是用代碼來說話吧:

例1、 實現拍照

在菜單或按鈕的選擇操作中調用如下代碼,開啟系統自帶Camera APP,並傳遞一個拍照存儲的路徑給系統應用程序,具體如下:

imgPath = "/sdcard/test/img.jpg";

//必須確保文件夾路徑存在,否則拍照后無法完成回調

File vFile = new File(imgPath);

if(!vFile.exists())

{

File vDirPath = vFile.getParentFile(); //new File(vFile.getParent());

vDirPath.mkdirs();

}

Uri uri = Uri.fromFile(vFile);

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);//

startActivityForResult(intent, SystemCapture);

上面我們使用的是startActivityForResult,所以最好需要重載void onActivityResult(int requestCode, int resultCode, Intent data)函數,不過因為當傳入文件路徑的的情況下,data返回參數是null值,只要resultCode為RESULT_OK,則上述代碼中 /sdcard/test/img.jpg的圖片文件就是最新的照片文件。所以我們在這里只需給出如下簡單的代碼,將其顯示到ImageView中

if (resultCode == RESULT_OK)

{

iViewPic.setImageURI(Uri.fromFile(new File(imgPath)));

}

假設不傳參數MediaStore.EXTRA_OUTPUT的情況下,onActivityResult函數在resultCode為RESULT_OK的情況下,data返回的參數是經過實際拍攝照片經過縮放的圖像數據,可以通過類似如下方法來打印縮放圖像的尺寸

if (resultCode == RESULT_OK)

{

Bitmap bmp = (Bitmap)data.getExtras().get("data");

Log.d("Test", "bmp width:" + bmp.getWidth() + ", height:" + bmp.getHeight());

}

另外假如僅僅是調用系統照相機拍照,不關心拍照結果,則可以簡單使用如下代碼

Intent intent = new Intent(); //調用照相機

intent.setAction("android.media.action.STILL_IMAGE_CAMERA");

startActivity(intent);

備注:上面設置MediaStore.EXTRA_OUTPUT的方法,經過手機實測除了我們設定的路徑下有照片外,在手機存儲卡上也會保存一份照片,默 認目錄為sdcard/dcim/camera下面,我曾經嘗試着想如果每次返回可以取得sdcard/dcim/camera下面的路徑就好了,但是目 前看來沒辦法直接獲得,可以借助MediaStroe每次去查詢最后一條照片記錄,應該也是可行的。

例2、 實現攝像

在攝像功能時,嘗試着設置MediaStore.EXTRA_OUTPUT以傳入類似拍照時的文件路徑,結果在我的測試真機上,那個視頻文件居然是一個0k的空文件,最后通過類似如下代碼實現

Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);//參數設置可以省略

startActivityForResult(intent, SystemVideoRecord);

在onActivityResult函數中進行如下代碼調用

Uri videoUri = data.getData();

//String[] projection = { MediaStore.Video.Media.DATA, MediaStore.Video.Media.SIZE };

Cursor cursor = managedQuery(videoUri, null, null, null, null);

cursor.moveToFirst();//這個必須加,否則下面讀取會報錯

int num = cursor.getCount();

String recordedVideoFilePath = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA));

int recordedVideoFileSize = cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.SIZE));

iResultText.setText(recordedVideoFilePath);

Log.i("videoFilePath", recordedVideoFilePath);

Log.i("videoSize", ""+recordedVideoFileSize);

上面的返回參數data,也會因為用戶是否設置MediaStore.EXTRA_OUTPUT參數而改變,假設沒有通過EXTRA_OUTPUT設置路 徑,data.getData返回的Uri為content://media/external/video/media/*,*個數字,代表具體的記錄 號,通過managedQuery可以獲取到路徑,假如設置了EXTRA_OUTPUT的話(比如/sdcard/test.3gp),則 data.getData返回的Uri則為file:///sdcard/test.3gp,但是該文件居然是空白內容(不知道是不是跟手機有關,也沒有 在其它手機上驗證過)。

根據Camera API實現自己的拍照和攝像程序

通過上面對調用系統Camera App實現拍照和攝像功能的例子,我們發現雖然能夠滿足我們的需求,但是畢竟自由度降低了,而且拍照的界面就是系統的樣子,現在很多拍照程序,比如火爆的 Camera 360軟件等,就需要根據SDK提供的Camera API來編寫自己的程序。

准備工作

上面調用系統Camera App,我們壓根不需要任何權限,但是這里用Camera API,就必須在manifest內聲明使用權限,通常由以下三項

<uses-permission android:name = "android.permission.CAMERA" />

<uses-feature android:name = "android.hardware.camera" />

<uses-feature android:name = "android.hardware.camera.autofocus" />

一般拍照和攝像的時候需要寫到sd卡上,所以還有一向權限聲明如下

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

真做攝像功能時,需要音頻錄制和視頻錄制功能,所以又需要下面兩項權限聲明

<uses-permission android:name="android.permission.RECORD_VIDEO"/>

<uses-permission android:name="android.permission.RECORD_AUDIO"/>

另外使用Camera API拍照或攝像,都需要用到預覽,預覽就要用到SurfaceView,為此Activity的布局中必須有SurfaceView。

拍照流程

上面簡單介紹了下准備工作,下面結合拍照過程中的需要用到的API對拍照流程做下簡單描述

1、在Activity的OnCreate函數中設置好SurfaceView,包括設置SurfaceHolder.Callback對象和SurfaceHolder對象的類型,具體如下

SurfaceView mpreview = (SurfaceView) this.findViewById(R.id.camera_preview);

SurfaceHolder mSurfaceHolder = mpreview.getHolder();

mSurfaceHolder.addCallback(this);

mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

2、在SurfaceHolder.Callback的surfaceCreated函數中,使用Camera的Open函數開機攝像頭硬件,這個API 在SDK 2.3之前,是沒有參數的,2.3以后支持多攝像頭,所以開啟前可以通過getNumberOfCameras先獲取攝像頭數目,再通過 getCameraInfo得到需要開啟的攝像頭id,然后傳入Open函數開啟攝像頭,假如攝像頭開啟成功則返回一個Camera對象,否則就拋出異 常;

3、開啟成功的情況下,在SurfaceHolder.Callback的surfaceChanged函數中調用getParameters函數得到已 打開的攝像頭的配置參數Parameters對象,如果有需要就修改對象的參數,然后調用setParameters函數設置進去(SDK2.2以后,還 可以通過Camera::setDisplayOrientation設置方向);

4、同樣在surfaceChanged函數中,通過Camera::setPreviewDisplay為攝像頭設置SurfaceHolder對象,設置成功后調用Camera::startPreview函數開啟預覽功能,上面3,4兩步的代碼可以如下所示

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)

{

//已經獲得Surface的width和height,設置Camera的參數

Camera.Parameters parameters = camera.getParameters();

parameters.setPreviewSize(w, h);

List<Size> vSizeList = parameters.getSupportedPictureSizes();

for(int num = 0; num < vSizeList.size(); num++)

{

Size vSize = vSizeList.get(num);

}

if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)

{

//如果是豎屏

parameters.set("orientation", "portrait");

//在2.2以上可以使用

//camera.setDisplayOrientation(90);

}

else

{

parameters.set("orientation", "landscape");

//在2.2以上可以使用

//camera.setDisplayOrientation(0);

}

camera.setParameters(parameters);

try {

//設置顯示

camera.setPreviewDisplay(holder);

} catch (IOException exception) {

camera.release();

camera = null;

}

//開始預覽

camera.startPreview();

}

5、假設要支持自動對焦功能,則在需要的情況下,或者在上述surfaceChanged調用完startPreview函數后,可以調用 Camera::autoFocus函數來設置自動對焦回調函數,該步是可選操作,有些設備可能不支持,可以通過 Camera::getFocusMode函數查詢。代碼可以參考如下:

// 自動對焦

camera.autoFocus(new AutoFocusCallback()

{

@Override

public void onAutoFocus(boolean success, Camera camera)

{

if (success)

{

// success為true表示對焦成功,改變對焦狀態圖像

ivFocus.setImageResource(R.drawable.focus2);

}

}

});

6、在需要拍照的時候,調用takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)函數來完成拍照,這個函數中可以四個回調接口,ShutterCallback是快門按下的回調,在這里 我們可以設置播放“咔嚓”聲之類的操作,后面有三個PictureCallback接口,分別對應三份圖像數據,分別是原始圖像、縮放和壓縮圖像和JPG 圖像,圖像數據可以在PictureCallback接口的void onPictureTaken(byte[] data, Camera camera)中獲得,三份數據相應的三個回調正好按照參數順序調用,通常我們只關心JPG圖像數據,此時前面兩個PictureCallback接口參 數可以直接傳null;

7、每次調用takePicture獲取圖像后,攝像頭會停止預覽,假如需要繼續拍照,則我們需要在上面的PictureCallback的onPictureTaken函數末尾,再次掉喲更Camera::startPreview函數;

8、在不需要拍照的時候,我們需要主動調用Camera::stopPreview函數停止預覽功能,並且調用Camera::release函數釋放 Camera,以便其他應用程序調用。SDK中建議放在Activity的Pause函數中,但是我覺得放在surfaceDestroyed函數中更 好,示例代碼如下

// 停止拍照時調用該方法

public void surfaceDestroyed(SurfaceHolder holder)

{

// 釋放手機攝像頭

camera.release();

}

以上就是自己實現拍照程序的的流程,一般還可以還可以獲取預覽幀的圖像數據,可以分別通過Camera::setPreviewCallback和Camera::setOneShotPreviewCallback來設置每幀或下一幀圖像數據的回調,這里就不做展開了。

攝像流程

攝像流程也是需要預覽的,而且流程上與拍照流程在起始的1~4步流程和結束的8流程是一樣的,唯一不同的是6和7兩個步驟,至於5自動對焦本身就是可選的,在攝像流程也沒必要。

6、開啟視頻錄制,需要創建一個MediaRecorder對象,並調用Camera::unLock操作解鎖攝像頭,因為默認Camera都是鎖定的, 只有解鎖后MediaRecorder等多媒體進程調用,並設置一些參數,然后調用MediaRecorder:: start開啟錄制具體可以參閱如下代碼:

MediaRecorder mMediaRecorder = new MediaRecorder();

// Unlock the camera object before passing it to media recorder.

camera.unlock();

mMediaRecorder.setCamera(camera);

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);

mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

mMediaRecorder.setProfile(mProfile);

mMediaRecorder.setMaxDuration(100000);//ms為單位

long dateTaken = System.currentTimeMillis();

Date date = new Date(dateTaken);

SimpleDateFormat dateFormat = new SimpleDateFormat(getString(R.string.video_file_name_format));

String title = dateFormat.format(date);

String filename = title + ".3gp"; // Used when emailing.

String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME;

String filePath = cameraDirPath + "/" + filename;

File cameraDir = new File(cameraDirPath);

cameraDir.mkdirs();

mMediaRecorder.setOutputFile(filePath);

try {

mMediaRecorder.prepare();

mMediaRecorder.start(); // Recording is now started

} catch (RuntimeException e) {

Log.e(TAG, "Could not start media recorder. ", e);

return;

}

7、上面設置了最大間隔為100s,當100是視頻錄制結束,錄制就會被停止,如果沒有設時長和文件大小限制,那么通常需要調用MediaRecorder:: stop函數主動停止視頻的錄制,並將Camera對象通過lock函數繼續加鎖,示例代碼如下

mMediaRecorder.stop();

mMediaRecorder.reset();

mMediaRecorder.release();

mMediaRecorder = null;

if(camera != null)

camera.lock();

之后的操作根據交互要么重新錄制要么就釋放Camera對象回到拍照流程的8步驟了。在這里就不做贅述了。

使用和整理過程中,由於英文不太好,非常感謝網上的一篇SDK中文翻譯,鏈接地址如下

http://blog.csdn.net/raindrophust/article/details/6205038

另外Android開發,最佳借鑒,我覺得還是源碼,Camera的很多參數和使用方法可以參照源碼中Camera APP的源碼,目錄為packages\apps\Camera。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM