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

日博365.tv ⌛ 2025-08-20 00:37:28 👤 admin 👁️ 3092 ❤️ 793
Android手机如何实现慢动作录制

HUAWEI P40 Pro的录制超级慢动作

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

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

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

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

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

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

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

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

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

查询CameraMetaData代码语言:javascript代码运行次数:0运行复制// 遍历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

代码语言:javascript代码运行次数:0运行复制// 慢动作录制视频的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回调......)代码语言:javascript代码运行次数:0运行复制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的支持情况代码语言:javascript代码运行次数:0运行复制// 比如华为P40 Pro上1920x1080支持的fps为:

// [30, 120], [30, 240], [120, 120], [240, 240]

map.getHighSpeedVideoFpsRangesFor(size);在设备支持慢动作的前提下就可以配置预览流程了

代码语言:javascript代码运行次数:0运行复制// 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(录制慢动作和延时摄影时都不用配置音频)

代码语言:javascript代码运行次数:0运行复制// 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开启录制了

代码语言:javascript代码运行次数:0运行复制// 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~~

相关文章

365外围用手机注册吗 东海漫画

东海漫画

⌛ 07-28 👁️ 963

友情链接