背景
音视频学习的视频学习部分,必须熟练掌握Camera API的原理即使用,而Android在5.0(API>=21)就提供了Camera2 API,并且建议应用使用Comera2 API,在androidX支持库中还提供了CameraX包,本文主要就是介绍Camera API、Camera2 API 以及androidX中CameraX的使用
- [x] 音视频基础0——目录
- [x] 音视频基础1——AudioTrack、AudioRecorder、MediaRecorder音频数据采集播放处理
- [ ] 音视频基础2——Android Camera API及Camera2 API的使用
- [ ] 音视频基础3——Android Camera API及Camera2 采集视频数据
- [ ] 音视频基础4——Android MediaCodec API学习
- [ ] 音视频基础5——Android 实现rtmp推流
- [x] 音视频基础6——交叉编译动态库
- [ ] [音视频基础7——MacOs下编译FFMpeg4.2.2
Camera API使用
简介
在Google提出Camera2 API之前,所有的相机操作,都是通过Camera这个类完成的,Camera类独自承接了以下以下工作:
- Camera的直接操作,如获取实例open,释放实例release,开始预览startPreview,停止预览stopPreview,拍照takePicture等等。
- Camera的参数配置,则在Camera的内部类Parameters来实现,如图片格式设置、图片尺寸设置、闪光灯设置等配置信息,大都可以通过该类找到。
- 功能回调都有相应的内部类实现,如:
- PreviewCallback,向调用者提供预览的一组帧数据;
- AutoFocusCallback,向调用者提供自动对焦的结果信息(是否对焦成功)
- PictureCallback,向调用者提供拍照回调(包括拍照的byte[] 数据)
- OnZoomChangeListener和FaceDetectionListener,缩放和人脸识别监听
代码虽然多,但是看起来简单,用起来更简单。
常用操作
1 | Camera camera = Camer.open(CAMERA_ID);// CAMERA_ID通常为Camera.CameraInfo.CAMERA_FACING_BACK或CAMERA_FACING_FRONT |
注意事项
- 切换相机是记得先调用释放掉之前的相机,再开启新的相机;
- 配合
SurfaceView
抓取视频数据时,需要再SurfaceView
创建后再初始化相机,并在SurfaceView
销毁时释放相机资源; - 开始录屏的时候,需要停止预览,然后在停止录屏的时候恢复预览。录屏的时候还要注意
lock()
/unlock()
的调用,具体可以看看两个函数的说明;
Camera2 API使用
简介
Camera2 虽然功能比Camera强大,但类结构也复杂了不少,不过好在各个类的职责还是比较明确的。CameraMamager负责获取CameraDevice,CameraDevice负责获取可以创建CaptureRequest的CaptureRequest.Builder,而且可以建立数据接收者Surface和数据收集者CameraDevice之间的会话,并在会话成功建立后,通过CaptureRequest来对相机进行配置。至于使用者是想进行拍照还是进行录屏,只要在创建CaptureRequest指定不同的模板,并在建立会话是传递不同的数据接收者就可以了。分工明确,流程清楚。
主要对核心类进行说明:
CameraManager
,系统服务(需要通过Context
的getSystemService
方法来获取,用来对CameraDevice
进行检测(是否有新的Camera)、控制(如何打开等)、连接、闪光灯控制等,是Camera2
的核心类。getCameraIdList
,查询可用的Camera列表,如前置后置;AvailabilityCallback
,Camera可用性回调通知;TorchCallback
,闪光灯状态回调;openCamera
(),打开Camera;getCameraCharacteristics
,查询到这个连接的相机支持哪些功能;
CameraDevice
,代表的就是一个链接到Android设备的Camera,通过Camera Device
你可以创建CameraCaptureSession
,创建CaptureRequest
;CameraCharacteristics
,CameraDevice
的属性描述文件,类似于Camera.Parameters,但包含更多的属性配置。
注意事项
- 切换相机是记得先调用释放掉之前的相机,再开启新的相机;
- 配合
SurfaceView
抓取视频数据时,需要再SurfaceView
创建后在获取CameraDevice,并在SurfaceView
销毁时释放CameraDevice; - 在获取CameraDevice时,为防止一直打不开的情形,最好设置一把超时锁。
- 创建会话时需要传递一个Handler,这个Handler最好是子线程的looper创建而来。
- 重新创建会话前,记得先关闭之前的会话,释放之前申请的资源;
错误集锦
E/MediaRecorder: stop called in an invalid state: 0
,MediaRecorder: stop failed :-1007
,MediaRecorder: start failed: -38
,说明Camera
正在被使用,有可能是别的MediaRecorder
没有释放,有可能是用来预览的CaptureSession
没有关闭,我的原因是后者,开始录屏时一定要关闭预览的CameraCaptureSession
java.lang.IllegalArgumentException: CaptureRequest contains unconfigured Input/Output Surface!