写点什么

这可能是全网关于 Camera 慢动作录像(SlowMotion)介绍最全的文章了

用户头像
小驰嘻嘻
关注
发布于: 2021 年 03 月 31 日


这是一篇关于慢动作录像(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、查询当前硬件是否支持高帧率录像

通过 CONTROLAVAILABLEHIGH_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(SCALERSTREAMCONFIGURATION_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.CONTROLAETARGETFPSRANGE, 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,

VEDIOHIGHSPEEDFRAMERATE);


mMediaRecorder.setVideoEncodingBitRate(bitRate);

mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate);

mMediaRecorder.setCaptureRate(VEDIOHIGHSPEEDFRAMERATE);

```


四、调试 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·


https://mp.weixin.qq.com/s?_biz=MzA3ODMzMTM1NA==&mid=2247484390&idx=1&sn=c919af11c48ba405445db1eebf99c7f2&chksm=9f452f53a832a6452a24b001295d81b591c9793c4f2e5a927b5545a1706f22a0f1ab32a52bd2&token=522091552&lang=zhCN#rd


发布于: 2021 年 03 月 31 日阅读数: 14
用户头像

小驰嘻嘻

关注

公众号: 小驰笔记 2021.03.30 加入

14年开始从事Android Camera相关软件开发 做过车载、手机、执法记录仪~

评论

发布
暂无评论
这可能是全网关于Camera慢动作录像(SlowMotion)介绍最全的文章了