前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android手机如何实现慢动作录制

Android手机如何实现慢动作录制

作者头像
雪月清
发布2022-07-11 12:06:44
1.3K0
发布2022-07-11 12:06:44
举报
文章被收录于专栏:雪月清的随笔雪月清的随笔

HUAWEI P40 Pro的录制超级慢动作

一般的电影都是采用24帧/秒的制式标准,当电影放映机和摄影机转换频率同步时就是正常速度的画面

如果在拍摄时以每秒48帧进行录制,播放时仍以每秒24帧播放,那么同样的画面播放速率也就放慢了一倍,即时长增加一倍,此时就会出现慢动作。这样的拍摄手法通常称为「慢镜头」或「升格摄影」

最著名的慢镜头当属《黑客帝国》中的「子弹时间」了

随着手机拍摄能力的持续创新,慢动作也成为了各大手机厂商旗舰机的标配功能,在抖音、B站等平台中我们可以看到一些用手机拍摄的比较炫酷的慢镜头vlog和短视频(比如矮脚猫跳高这个场景是非常适合用慢动作来拍摄的)

除了系统相机能提供慢动作的能力外,第三方应用开发能否支持慢动作呢?答案是肯定的,但是大部分机型其实是不支持的......

就国内华米OV四家影像能力开放来说,通过camera2 api支持自家能力,华为对第三方开发者来说是算比较友好的

(荣耀现在独立,具体情况研究较少,总体不太了解,有清楚的小伙伴可以来一起交流交流)

本文介绍的慢动作功能采用Camera2+MediaRecorder+SurfaceView实现,预览流程和常规的camera2预览流程是一致的,只是创建会话和请求request有些许不同,详细步骤可以参考Android Camera2详解,下面仅说说流程的关键点,详细代码可以参考文末的「参考2」

启动预览前需要先检查一下当前设备是否支持慢动作

  • 查询CameraMetaData
// 遍历capabilities是否存在CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO
int[] capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
  • 找到预览支持size list和高帧率video size list的交集并选择一个最佳的size作为预览size和录制size
// 慢动作录制视频的video size必须和preview size保持一致
// 所以需要从两个list中找到交集
map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
highSpeedVideoSizes = map.getHighSpeedVideoSizes();
previewSizes = getOutputSizes(SurfaceHolder.class);
  • 根据video size查询是否存在high speed相关的CamcorderProfile,如果不存在说明不支持,手头华为支持,OPPO则不支持(不支持的机型强行启动预览后喜提Camera的onError回调......)
for (int quality = CamcorderProfile.QUALITY_HIGH_SPEED_LOW; quality <= CamcorderProfile.QUALITY_HIGH_SPEED_2160P; quality++) {
    if (CamcorderProfile.hasProfile(quality)) {
        if (size.getWidth() == profile.videoFrameWidth && size.getHeight() == profile.videoFrameHeight) {
           return profile;
        }
    }
}
  • 根据video size查询fps的支持情况
// 比如华为P40 Pro上1920x1080支持的fps为:
// [30, 120], [30, 240], [120, 120], [240, 240]
map.getHighSpeedVideoFpsRangesFor(size);

在设备支持慢动作的前提下就可以配置预览流程了

// 1. open camera
cameraManager.openCamera(...);

// 2. prepare surfaces
surfaceList.add(mSurfaceHolder.getSurface);

// prepare media recorder
// mMediaRecorder的参数配置来自前面的higt speed profile
mMediaRecorder.prepare();
surfaceList.add(mMediaRecorder.getSurface)

// 3. create high speed session
cameraDevice.createConstrainedHighSpeedCaptureSession(surfaceList,...);

// 4. trigger request
mPreviewBuilderBurst = session.createHighSpeedRequestList(mPreviewBuilder.build());
session.setRepeatingBurst(mPreviewBuilderBurst, null, null);

其中配置MediaRecorder时不配置Audio(录制慢动作和延时摄影时都不用配置音频)

// only config video stream
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setOrientationHint(90);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(profile.fileFormat);
mMediaRecorder.setVideoEncoder(profile.videoCodec); 
mMediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight); mMediaRecorder.setVideoEncodingBitRate(profile.videoBitRate);
mMediaRecorder.setVideoFrameRate(profile.videoFrameRate);

预览起来后就可以通过MediaRecorder开启录制了

// start record
mMediaRecorder.start();

// stop record
mMediaRecorder.stop();

以手上机器设置帧率【30,120】为例,录制的一个test视频如下

FAQ

Q1: 为什么慢动作启动预览时需要保持video size和preview size一致

A1: 因为在创建request list时会校验每个surface的size是否支持设定的fps

fpsRange一定是不为null的,如果为null,后续流程就NPE了

Q2: 类似华为P40 Pro提供的这种32X对应到960帧/S是怎么算的

A2: session每次请求的request list数量为设置的fps最大值除以30,UI显示的倍数乘以30就是录制的最大的fps

参考

1.【录制超级慢动作视频 (HUAWEI P40 Pro)】

https://consumer.huawei.com/cn/emui10-1/tips/entertainment-list/article17/

2.【Android-Slow-Motion-Camera2】

https://github.com/thesleort/Android-Slow-Motion-Camera2

3.【华为相机能力】

https://developer.huawei.com/consumer/cn/CameraKit/

4.【Android源码9.0】

http://androidxref.com/9.0.0_r3/xref/frameworks

~~END~~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-06-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 雪月清的随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档