日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android camera2 采集,视频采集:Android平台基于Camera 2的实现

發布時間:2024/7/23 Android 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android camera2 采集,视频采集:Android平台基于Camera 2的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

這篇文章簡單介紹下移動端Android系統下利用Camera2相關API進行視頻采集的方法。

Camera2是谷歌在Android 5.0新增的用來替代Camera1操作攝像頭的一個全新的API。

按照慣例先上一份源碼AndroidVideo。

Camera2調用攝像頭采集視頻的核心實現在Camera2Capture.java。

權限配置

使用Android平臺提供的攝像頭,首先必須在配置文件中添加如下權限配置:

獲取攝像頭信息

打開攝像頭管理器

CameraManager是一個用于檢測、連接和描述攝像頭設備的一個系統服務,可以通過調用Context.getSystemService(java.lang.String)方法來獲取一個CameraManager的實例:

CameraManager mManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);

獲取攝像頭列表信息

通過調用CameraManager.getCameraIdList()方法,可以得到一個攝像頭id的列表:

String[] cameraIds = mCameraManager.getCameraIdList();

for (String id : cameraIds) {

//TODO

}

可以通過相對應的ID從CameraManager獲取到對應攝像頭的屬性集合CameraCharacteristics。

在CameraCharacteristics可以獲取到諸如前后置情況、支持的輸出size、支持的輸出格式等等之類的。

for (String id : cameraIds) {

//傳入攝像頭id,獲取對應攝像頭的參數集

CameraCharacteristics characteristics = mManager.getCameraCharacteristics(id);

//獲取攝像頭的支持等級

Integer level = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);

//如果是LEGACY等級,不建議使用該攝像頭

if (level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)

{

continue;

}

//獲取攝像頭的朝向

Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);

//篩選出前置攝像頭

if (facing != CameraCharacteristics.LENS_FACING_FRONT) {

continue;

}

//StreamConfigurationMap包含了該攝像頭支持的size、format等信息

StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

//獲取輸出格式為YUV_420_888時兼容的size

Size[] size = map.getOutputSizes(ImageFormat.YUV_420_888);

//獲取輸出View為SurfaceView時兼容的size

//Size[] size = map.getOutputSizes(SurfaceHolder.class);

//TODO 其他的參數,例如輸出格式、輸出幀率上下限等

}

PS:對于Camera2采集系統來說,每個攝像頭都有一個支持等級:

INFO_SUPPORTED_HARDWARE_LEVEL_3 支持YUV再處理和原始數據采集功能,并且具備先進的功能。

INFO_SUPPORTED_HARDWARE_LEVEL_FULL支持先進的攝像頭功能。

INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED向后兼容模式,底層等同于Camera1的實現。

INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY 隨機贈送的功能支持,支持性不足。

PS:總的來說如果攝像頭等級是LEVEL_3和LEVEL_FULL才建議使用Camera2進行采集,否則推薦采用兼容性更好的Camera1進行視頻采集。

打開攝像頭

通過攝像頭信息,我們可以找到所需要的CameraId,接下來就用這個ID去獲取我們的攝像頭設備CameraDevice。

函數原型是public void openCamera(String cameraId, final CameraDevice.StateCallback callback, Handler handler),

cameraId是需要打開的攝像頭的id,為了監聽攝像頭的情況,需要傳入一個回調,也就是第二個參數CameraDevice.StateCallback,當然如果我們不想讓open操作占用UI線程的時間的話,

我們可以通過構造一個HandlerThread的帶Looper的子線程,然后將其Handler傳入即可。

//打開攝像頭,正常打開會回調到CameraDeviceStateCallback的onOpened方法

mManager.openCamera(mCameraId, new CameraDevice.StateCallback() {

@Override

public void onOpened(@NonNull CameraDevice camera) {

//攝像頭成功連接

//camera也就是我們需要獲取的攝像頭設備

mCameraDevice = camera;

}

@Override

public void onDisconnected(@NonNull CameraDevice camera) {

//攝像頭斷開連接

}

@Override

public void onError(@NonNull CameraDevice camera, int error) {

//打開錯誤

}

}, mHandler);

創建采集會話

在成功打開攝像頭,獲取到相應的CameraDevice,我們需要創建一個采集會話來提供程序與攝像頭的交流。

其函數原型是public abstract void createCaptureSession(List outputs,CameraCaptureSession.StateCallback callback, Handler handler) throws CameraAccessException。

第一個參數傳入的是需要采集的Surface,為了監聽會話創建情況,我們需要傳入一個CameraCaptureSession.StateCallback回調,當然第三個參數也就是讓操作能在對應Handler所在的線程中進行。

//獲取一個采集Session會話,正常流程回回調到CameraCaptureSessionStateCallback的onConfigured方法

mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceView.getHolder().getSurface()), new CameraCaptureSession.StateCallback() {

@Override

public void onConfigured(@NonNull CameraCaptureSession session) {

//會話創建成功

//mCameraCaptureSession也就是新創建的會話

mCameraCaptureSession = session;

}

@Override

public void onConfigureFailed(@NonNull CameraCaptureSession session) {

//會話創建失敗

}

}, mHandler);

PS:對于一些業務需求需要提高采集幀率(120fps及以上),createConstrainedHighSpeedCaptureSession()這個會話能良好的支持該功能。

發送采集請求

當需要開始采集時,需要構造一個采集請求,然后將這個請求發送給采集會話。

//創建一個基于錄制的請求

mRequest = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);

//將需要的目標Surface加入Target列表

mRequest.addTarget(surface);

//重復發送這個請求,進行持續的采集

mCameraCaptureSession.setRepeatingRequest(mRequest.build(), NULL, mHandler);

原始數據回調

在Camera1的采集中,我們一般通過設置setPreviewCallbackWithBuffer()和addCallbackBuffer()來獲取到采集的原始數據,那么在Camera2中將如何實現該功能呢?

我們可以用到ImageReader這個類:

//ImageReader是一個數據回調模塊,類似于Camera1的setPreviewCallbackWithBuffer

mReader = ImageReader.newInstance(mConfig.mWidth, mConfig.mHeight, mConfig.mFormat, 2);

mReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {

@Override

public void onImageAvailable(ImageReader reader) {

Image image = reader.acquireNextImage();

//數據處理

image.close();

}

}, mHandler);

我們需要在createCaptureSession()的第一個參數中將ImageReader的Surface傳進去:

//通過ImageReader.getSurface()獲取一個Surface并將其傳給Session中

mCameraDevice.createCaptureSession(Arrays.asList(mReader.getSurface())//....);

然后在CaptureRequest添加這個Target:

//當然,構造請求時,需要將該Surface同時加入到Request的Target列表中

mRequest.addTarget(mReader.getSurface());

參考資料

結語

這篇文章簡單介紹了Android平臺基于Camera2的api進行攝像頭采集的功能。

Camera2雖然是谷歌當前建議使用的采集框架,但是由于廠商的兼容性問題導致Camera2的api功能相對不穩定;

所以筆者還是建議開發以Camera1為主要采集、Camera2為輔助采集的架構實現比較靠譜。

本文同步發布于簡書、CSDN。

End!

總結

以上是生活随笔為你收集整理的android camera2 采集,视频采集:Android平台基于Camera 2的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。