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!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/503232.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java虚拟机组成详解

一、jvm的主要组成部分 类加载器(ClassLoader)运行时数据区(Runtime Data Area)执行引擎(Execution Engine)本地库接口(Native Interface) 接下来我们来看以上4个主要组成部分的用途…

取消android所有动画,android studio 取消BottomNavigationView的动画等

app:labelVisibilityMode"labeled"布局文件上添加上此句就可以让标签文字也显示出来了,但是缩放动画,还是会存在。那么回到初始化view的activity中BottomNavigationView navView findViewById(R.id.nav_view);//设置选中时的效果navView.setI…

android addtextchangedlistener参数,【Android】关于addTextChangedListener()方法的上机记录...

自己在学习控件的时候,学到关于EditText的addTextChangedListener()方法,想做一个类似发微博限制字数为140那样的功能,以此文记录上机过程中发现的一些问题。在做这个的时候,是第五节课视频刚提到addTextChangedListener()这个方法…

android 开源 数据库,Android开源数据库框架-LitePal的使用

简介LitePal是一款开源的Android数据库框架,采用了关系映射的模式。LitePal在github上的项目地址:github.com/LitePalFram…配置LitePaldependencies {....compile org.litepal.android:core:1.5.1}复制代码在app/src/main 目录下新建目录assets&#xf…

signature=095ed28e83b68620637b3a67436b0f8f,SMB 3.1.1 Encryption in Windows 10

SMB 3.1.1 Encryption in Windows 1009/09/201513 分钟可看完本文内容SMB 3 encryption offers data packet confidentiality and prevents an attacker from both tampering with and eavesdropping on any data packet. Encryption has been enhanced in SMB 3.1.1. The ciph…

鸿蒙系统打通iOS,库克真的做到了!正式官宣确认截胡鸿蒙OS系统:软硬件生态全打通...

【4月25日讯】相信大家都知道,自从苹果正式举办完春季新品发布会以后,很多网友们都纷纷吐槽到“苹果的黑科技就是以换色为本,iPhone12推出紫色版本,而iMac也变成了彩虹色,很好的继承了诺基亚“科技以换壳为本”理念”&…

html标签中的文本框的值,HTML文本框的值分配给div标签的标题

线2:#msdhoni我want-什么,当用户输入一些东西在文本框(以行1)应该成为div的标题(在第2行)点击botton(在第1行)。其实想要用代码中的文本输入替换#msdhoni。jQuery代码我米使用:(请建议在这段代码的变化,使这成为可能)String.proto…

快速了解Java集合框架

1. 简介 JDK1.2 引入了 Java 集合框架,包含一组数据结构。与数组不同,这些数据结构的存储空间会随着元素添加动态增加。其中,一些支持添加重复元素另一些不支持,一些支持 null,一些能自动升序打印元素。 所有这些数据…

html分类页面,CSS网页设计 把HTML标记分类

p、h1、或div等元素常常称为块级元素,这些元素显示为一块内容;Strong,span等元素称为行内元素,它们的内容显示在行中,即“行内框”。(可以使用displayblock将行内元素转换成块元素,displaynone表示生成的元素根本没有框…

html点击图片产生事件,jquery – 图像单击HTML5 Canvas中的事件

我有一个HTML5画布,我在其中添加了一个图像,我想调用图像的点击事件,但事件不会触发.我正在写一个HTML代码和jqmobile的一些代码This text is displayed if your browser does not shown.$(function () {var ctx document.getElementById("canvas1").getContext(&qu…

html代码里面换图片不显示不出来了,微擎 Ueditor 百度编辑器 替换图片不显示问题...

问题:最近在使用微擎添加公众号平台文章时,上传图片可以显示,但是点击 html(编辑器的按钮,可以显示html代码) 时出现图片不显示问题。我是用的135编辑器挑选的图文模板,我替换完模板中的图片后,图片的链接失效&#xf…

找通项公式在线计算机,在线硬盘分区计算器工具

一、什么是分区?分区从实质上说就是对硬盘的一种格式化。当我们创建分区时,就已经设置好了硬盘的各项物理参数,指定了硬盘主引导记录(即Master Boot Record,一般简称为MBR)和引导记录备份的存放位置。而对于文件系统以及其他操作系…

湖南大学计算机网络实验,湖南大学《计算机网络》实验报告

实验一应用协议与数据包分析实验(使用Wireshark)一、实验目的通过本实验,熟练掌握Wireshark的操作和使用,学习对HTTP协议进行分析。二、实验内容1.HTTP 协议简介HTTP 是超文本传输协议(Hyper Text Transfer Protocol)的缩写,用于W…

html中dl标签和ul标签,html中dl,dt,dd,ul,li,ol标签区别和使用

html中dl,dt,dd,ul,li,ol标签区别和使用时间:2013-04-12 21:48 来源:未知 | 作者:易享学习网| 本文已影响 人ul: unordered listsol: ordered listsli: Listsol 有序列表:………………表现为:1……2……3……ul 无序列表,表现为li前面是大圆点…

国家开放计算机应用基础模块1答案,完整word版,《国家开放大学学习指南》计算机应用基础网上作业答案(完整版)...

作业1(本次作业覆盖“模块1 Windows 7 操作系统”的内容,请在学完模块1后完成本次作业,要求第8周内完成。满分为40分,其中基础知识部分10分,Windows 7部分20分,网络部分10分。单选题50道、填空题50道)基础知识选择题(共…

webview 本地 html空白,WKWebView加载本地html遇到的坑与解决办法

1、字体变小解决办法Swiftlet headerString ""self.wkwebview.loadHTMLString(headerString.appending(html), baseURL: nil)Objective-CNSString *headerString "";[strongSelf.contentWebView loadHTMLString:[headerString stringByAppendingString:m…

偷用计算机作文,偷玩电脑作文5篇

偷玩电脑作文5篇篇一:偷玩电脑的滋味星期天,我在家里看电视,妈妈很晚才回来,我只好在家等,看了一会,电视节目没了,我把电视关掉,看了会书消磨时间,我又写了会作业&#x…

中科院计算机学院王宏,王宏-中国科学院大学-UCAS

发表论文(1) SIL verification for SRS with diverse redundancy based on system degradation using reliability block diagram, Reliability Engineering and System Safety, 2017, 第 2 作者(2) New considerations for SIL verification of functional safety fieldbus co…

钢铁厂计算机相关岗位需要倒班吗,钢铁厂工人倒班的三个阶段,请对号入座!...

原标题:钢铁厂工人倒班的三个阶段,请对号入座!刚开始钢铁厂倒班工作,感觉倒班好,夜班有啥,通宵可以感受夜的宁静,深夜闲暇之余还可以仰望星空,思考人生,白天自由时间多&a…

计算机文化基础B卷期末,《计算机文化基础》上机试卷B

课程代码: 座位号:新疆大学2008- 2009 学年度第一学期期末考试《计算机文化基础》上机试卷姓名: 学号: 专业:学院: 班级:2008年 12月注意事项:在试卷上必须注明学号、姓名否则成绩以“零”分计算完成以下各题后,将应用程序窗口最小…