这是一篇对于 慢动作录像(slowmotion)的文章,看完后置信你对慢动作录像不会再感到生疏了~
这篇文章针对上面几点来开展:
1)写这篇文章的原由?
2)什么是慢动作录像(SlowMotionRecord)?
3)Android 上如何实现慢动作录像?
4)调试 demo 下载地址?
5)调试遇到的问题及解决?
一、写这篇文章的原由?
2 月份的时候,在一个音视频开发的学习交换群里, 有位网友问到“Android 相机有啥设置能够做到 slow motion?”, 我认真的想了下,而后又简略看了下高通的晓龙相机源码,大略晓得是怎么实现后,给了下思路。
前面我还始终在想这个事件,觉的本人给的思路太简略了,有工夫还是得再钻研钻研,本人得敲下代码跑通下才好,于是就有了这篇文章。
二、什么是慢动作录像(SlowMotionRecord)?
通常咱们人眼可能承受的最好的视频帧速率是 24 帧 / 每秒左右。那如果咱们用 120 帧 / 秒拍摄一个动作,再用 24 帧每秒来播放的话,视频就加快了 5 倍,这个就是慢动作录像了。
慢动作录像 ,又叫 高帧率录像(HFR), 也就是以高 fps(运行速率)捕捉、编码并保留为 30 fps(指标速率),这种状况运行速率大于指标速率。
(还有一种模式叫做高速录制(HSR) : 即以高 fps(运行速率)捕捉、编码并保留为高 fps(指标速率), 运行速率等于指标速率。)
这篇文章只介绍慢动作录像。(调试环境基于高精通龙 865 芯片 Android9.0)
三、Android 上如何实现视频慢动作?
有了下面对于慢动作的概念后,那在 Android 上如何用代码来实现呢?说到录像,那咱们应该要想到 MediaRecorder 了。慢动作,也就是高帧率录像,那必定得调用 mediaRecorder 设置高帧率了。
好了,咱们还得再有一个概念,数据是从摄像头 sensor 进去的,那咱们须要 120fps, 总得摄像头反对才行吧。所以呢,就有一个先决条件了,硬件得反对才行,上面会讲如何查问以后硬件是否反对。
假如硬件反对的状况下,咱们来看下软件上利用的调用状况。
1、新类 CameraConstrainedHighSpeedCaptureSession
查看 Android 的开发文档,咱们能够看到,从 Android 6.0 开始,Camera 相干的,增加了一个新的类CameraConstrainedHighSpeedCaptureSession,从形容上看,咱们就能够晓得,这个是专门为高速、高帧率录像筹备的。换一句话说,也就是 Android 6.0 以上,Android 自身才反对这个高速、高帧率录像。(我在本人早年用的 nubiya 手机上看了下,Android 5.1 的零碎,零碎相机也带了慢动作性能,不过它这个慢动作应该是厂家本人定制开发的,那会 Android 还没提供相干接口)
2、查问以后硬件是否反对高帧率录像
通过 CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS 来获取 available size。如果存在 available,则判断为反对。
public static boolean hasHighSpeedVideoConfigs(Context context, String cameraId) {
try {CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
HighSpeedVideoConfiguration[] highSpeedVideoConfigs = characteristics.get(CameraCharacteristics.CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS);
return highSpeedVideoConfigs != null && highSpeedVideoConfigs.length > 0;
} catch (Exception e) { }
return false;
}
3、获取反对的高帧率录像 videoSize
从 map.getHighSpeedVideoSizes()中获取反对的 videoSize, 而后抉择个适合的 size, 留神这里的 previewSize 须要和 videoSize 保持一致。
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics
.get(SCALER_STREAM_CONFIGURATION_MAP);
mVideoSize = chooseVideoSize(map.getHighSpeedVideoSizes());
mPreviewSize = mVideoSize;// 这里须要放弃 previewSize 和 videoSize 统一
4、CONTROL_AE_TARGET_FPS_RANGE 设置为高帧率范畴(120,120)
Range aeFps = new Range(120, 120);
mPreviewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, aeFps);
5、创立 session 采纳 createConstrainedHighSpeedCaptureSession
高帧率录像创立 session,应用专门提供的 api 接口。
// Start a capture session
mCameraDevice.createConstrainedHighSpeedCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {......}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {......}
}, mBackgroundHandler);
6、采纳 setRepeatingBurst
session configure 胜利后,调用 setRepeatingBurst 不停的 request,这个和失常模式有点区别,失常模式是调用的 setRepeatingRequest。
CaptureRequest request = mPreviewBuilder.build();
List<CaptureRequest> slowMoRequests = ((CameraConstrainedHighSpeedCaptureSession) mPreviewSession)
.createHighSpeedRequestList(request);
mPreviewSession.setRepeatingBurst(slowMoRequests, null,
mBackgroundHandler);
7、MediaRecorder 相干参数设置为对应的高帧率参数
绝对应的,mediaRecorder 的一些参数也须要设置为高帧率参数。
mProfile = getProfile();
int bitRate = getHighSpeedVideoEncoderBitRate(mProfile,
mProfile.videoFrameRate,
VEDIO_HIGH_SPEED_FRAME_RATE);
mMediaRecorder.setVideoEncodingBitRate(bitRate);
mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate);
mMediaRecorder.setCaptureRate(VEDIO_HIGH_SPEED_FRAME_RATE);
四、调试 Demo 下载地址
原本想着上传到 github 的,奈何 github 不给力,拜访不了。先上传到百度网盘先,须要的能够自行下载参考。(关注 ” 小驰笔记 ”,回复 ” 慢动作录像 ” 即可获取代码下载地址)
五、调试遇到的问题及解决办法
》》》》问题 1:
Process: com.xcbj.camera, PID: 21818
java.lang.IllegalArgumentException: Surface size 1440x1080 is not part of the high speed supported size list [1280x720, 720x480, 640x480, 1920x1080]
at android.hardware.camera2.utils.SurfaceUtils.checkConstrainedHighSpeedSurfaces(SurfaceUtils.java:193)
at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSessionInternal(CameraDeviceImpl.java:881)
at android.hardware.camera2.impl.CameraDeviceImpl.createConstrainedHighSpeedCaptureSession(CameraDeviceImpl.java:627)
[剖析]
》》》》问题 2:Fps rang[30,30] in the request is not a supported hight speed fps range…
Process: com.xcbj.camera, PID: 27138
java.lang.IllegalArgumentException: Fps range [30, 30] in the request is not a supported
high speed fps range [[120, 120], [240, 240], [480, 480], [30, 120], [30, 240], [30, 480]]
at android.hardware.camera2.utils.SurfaceUtils.checkConstrainedHighSpeedSurfaces(SurfaceUtils.java:180)
at android.hardware.camera2.impl.CameraConstrainedHighSpeedCaptureSessionImpl.createHighSpeedRequestList(CameraConstrainedHighSpeedCaptureSessionImpl.java:89)
[剖析]
* 自己从事 Android Camera 相干开发已有 5 年,
* 目前在深圳下班,
* 欢送关注我的微信公众号 ” 小驰笔记 ”
* 心愿和更多的小伙伴一起交换 ~
——– 2021.03.25 深圳 00:53·