音影片直播技術--Android影片採集(Camera2)

Camera2

介紹

今天為大家介紹一下如何在 Android 上進行影片採集。在 Android 系統下有兩套 API 可以進行影片採集,它們是 Camera 和 Camera2 。Camera是以前老的 API ,從 Android 5.0(21)之後就已經放棄了。我今天主要給大家介紹一下如何使用 Camera2 進行影片的採集。原碼可以在這裡獲取

Camera2 整體工作結構

Camera2結構圖

  • Camera Device:代表一個攝影機,在一部手機上有可能有多個攝影機,如前置攝影機,後置攝影機等。
  • CameraCaptureSession:表式Android Device(APP)與CameraDevice之間的會話層,類似於 http中的 session。
  • CaptureRequest:APP要想拍照,攝像都是向 CameraDevice 發送CaptureRequest請求。這個請求是通過上面的 Session發送出去的。
  • CameraMetadata:CameraDevice將捕獲到的數據封裝成CameraMetadata通過Session傳給 APP。其實這一步基本是隱藏起來的,在API中我們很少直接用它。
  • Android Device:可以把它想像成我們自己的APP應用。
  • Surface:存放數據的類,在實際的操作中,我們只要把 surface告訴CaptureRequest.Builder,當有數據到來之後,系統底層就會將數據存放到 surface中。

Camera2 主要類介紹

  • CameraManager:攝影機管理器。用於攝影機的管理,如檢測系統攝影機、打開系統攝影機,獲取攝影機參數。
  • CameraCharacteristics:用於管理攝影機特性。該對象通過CameraManager來獲取,用於描述特定攝影機所支援的各種特性。
  • CameraDevice:代表系統攝影機設備。
  • CameraDevice.StateCallback:該類是CameraDevice的內部類,其中定義了 onOpened, onDisconnected, onError三個方法,這三個方法需要用戶來實現。系統會根據打開 Camera 設備的狀態結果,回調三個不同的方法。

  1. onOpened:表式成功打開了 Camera 。
  2. onDisconnected:表式關閉了與 Camera 的連接。
  3. onError:表式打開 Camera 失敗。
  • CameraCaptureSession:該類代表 APP 與 Camera 設備之間的連接。就好像 APP 與某個 Camera 設備之間建了一個通道,你的APP無論是拍照,攝像等都可以通過這個通道向 Camera 設備發命令請求,Camera接收請求後做相應的工作。這是典型的非同步工作方式。
  • CameraCaptureSession.StateCallback:該類是CameraCaptureSession的內部類,其中定義了 onConfigured 和 onConfigureFailed 兩個方法,這兩個方法需要用戶自己來實現,系統會根據 Session 的創建狀態結果回調不同的方法:
    1. onConfigured:表式 Session 創建成功。
    2. onConfigureFailed:表式 Session 創建失敗。
  • CameraCaptureSession.CaptureCallback:該類是CameraCaptureSession的另一個內部類,其中定義了 onCaptureCompleted 和 onCaptureProgressed 兩個方法,這兩個方法也需要用戶自己來實現,系統會根據 Session 捕獲圖片的不同階段來回調這兩個不同的方法:
    1. onCaptureCompleted:圖片捕獲完成。
    2. onCaptureProgressed:圖片正在處理中。
  • CameraRequest:代表了一次捕獲請求,用於描述捕獲圖片的各種參數設置,比如對焦模式、曝光模式等等,APP需要對捕獲的所做的各種控制,都通過CameraRequest參數進行設置。
  • CameraRequest.Builder:負責生成CameraRequest對象。

使用 Camera2 基本流程

  • 創建一個專門的執行緒用於Camera的具體操作。Android系統已經為我們提供了 HandlerThread類,以方便我們創建 Hander 類型的執行緒。對於 HanderThread我們專門再寫一篇與之相關的文章。
  • 創建一個預覽view,它可以是GLSurfaceView或TextureView(這兩個View的區別我也會再寫一篇文章來介紹),用於影片採集時觀看採集到的結果。當APP接收到preview創建成功後,就可以開始Camera設備相關的操作了。
  • 在CameraManager中找到一個合適的 Camera 設備,得到其設備號。通過 CameraID 得到該設備的各種參數,我們可以再根據這些參數調整preview。
  • 調用CameraManager的openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)方法打開指定攝影機。

  1. 該方法的第一個參數代表要打開的攝影機ID;
  2. 第二個參數 callback 用於監聽攝影機的狀態;
  3. 第三個參數代表執行callback的Handler,如果程式希望直接在當前執行緒中執行callback,則可將handler參數設為null。
  • 當攝影機被打開之後,系統就會回調 CameraDevice.StateCallback 類中的 onOpened 方法,在該方法中 APP 可獲取 CameraDevice 對象。
  • 拿到CameraDevice設備後,調用它的createCaptureRequest(int templateType)方法創建CaptureRequest.Builder對象。CaptureRequest.Builder是一個非常重要的對象,它主要包括兩方面的作用,一是可以把預覽或錄製的Surface給它,這樣每個Surface就可以從Camera拿到採集到的圖片原始數據,這是一個典型的觀察者模式,二是可以給Camera設備設置自動對焦,光圈大小等Camera設備參數。另外templateType 參數也要強調一下,包括下面三種類型:

  1. TEMPLATE_PREVIEW(預覽)
  2. TEMPLATE_RECORD(拍攝影片)
  3. TEMPLATE_STILL_CAPTURE(拍照)等參數。
  • 然後調用CameraDevice的createCaptureSession(List<Surface> outputs, CameraCaptureSession.StateCallback callback,Handler handler)方法來創建CameraCaptureSession。

  1. 該方法的第一個參數是一個List集合,封裝了所有需要從該攝影機獲取圖片的Surface;
  2. 第二個參數 StateCallback 用於監聽CameraCaptureSession的創建過程;
  3. 第三個參數代表執行callback的Handler,如果程式希望直接在當前執行緒中執行callback,則可將handler參數設為null。
  • 如果 CameraCaptureSession 創建成功,系統會回調 StateCallback 的 onConfigured 方法。在該方法中我們可以拿到創建好的 CameraCaptureSession對象。
  • 再調用CameraCaptureSession對象的setRepeatingRequest(CaptureRequest request, CaptureCallback callback, Handler handler)方法,向Camera發送命令請求。

  1. 第一個參數是由前面講的 createCaptureRequest 創建的 CaptureRequest.Builder對象生成的。
  2. 第二個參數callback是Camera捕獲時的回調對象。
  3. 第三個參數代表執行callback的Handler,如果程式希望直接在當前執行緒中執行callback,則可將handler參數設為null。

通過以上的步驟,就可以從Camera設備中獲取到影片了。我們還可以通過Android的MediaRecorder類將獲取到的影片錄製下來進行回看。對於MediaRecorder我會在另一篇文章中再做介紹。

小結

通過上面對 Camera2 API 使用的分析,我們們可以看到 Camera2 完全採用了非同步的架構模式,在完成 Camera 每一步操作後系統都會通知用戶,用戶可以在回調時做下一步的操作,而不用一直等待。採用這種模式的優點是可以大大提高APP的工作效率,缺點是不那麼直觀,增加了一些學習和開發成本。

參考資料

  1. google sample android-Camera2video
  2. http://blog.csdn.net/lushuo9156/article/details/58059516

Tags: