我正在用Android相机实现视频录制。我使用MediaCodec对onPreviewFrame()回调中的帧进行编码。
现在我想录制慢动作视频如何设置相机捕获速率或帧速率我可以在哪里设置这些参数,例如,如果我想以120fps录制,并以30fps播放?
以下是我研究的内容:
我用MOTO X(内置慢动作视频录制功能)录制了一段慢动作视频,并使用FFmpeg检查其fps。我发现它的录制速度为110帧/秒(接近120帧/秒),播放速度为30帧/秒。这证明了它为高fps的录制提供了硬件支持。
然而,当我使用getSupportedPreviewFpsRange检查其支持的fps范围时,只有4组支持的fpss范围,没有一组大于30fps:
最小值:15.0,最大值:15.0
最小值:15.0,最大值:20.0
最小值:15.0,最大值:30.0
最小值:24.0,最大值:30.0
我使用setPreviewFpsRange将fps设置得更高,但它仍然不超过30fps。我还尝试设置MediaFormat的KEY_FRAME_RATE和KEY_CAPTURE_RATE。但它仍然不起作用。
我还通过设置CamcorderProfile或使用MediaRecorder设置VideoFrameRate来搜索解决方案。但我在做MediaCodec。
有人能帮我解决这个问题吗?
以更高的速率捕获视频帧并不能解决这个问题。如果您以120帧/秒的速度拍摄并以120帧的速度回放,则可以以正常速率高速播放视频。
您要做的是修改时间戳。MediaCodec支持VFR(可变帧速率)视频。你不需要花1秒的时间录制60帧以每秒30帧的速度回放,而是每秒录制30帧以每秒15帧的速度播放。
由MediaCodec的AVC编码器生成的H.264流根本不包括时间戳。当您将输出馈送到MediaMuxer并生成.mp4文件时,您可以为每帧指定时间戳。大多数示例代码只需获取从Camera获得的时间戳,然后通过MediaCodec将其传递给MediaMuxer,但您可以对其进行调整。唯一不能做的是允许时间戳向后移动。
如果你看看Grafika中"八个矩形"电影的生成方式,你可以看到它是用输出时间戳播放的,以使电影播放得更慢或更快。
在不改变帧速率的情况下完成相同任务的另一种简单方法是将帧加倍。对于慢动作部分,只需多次将同一帧交给编码器即可。同样,您需要调整每帧的演示时间戳,但您的视频将具有一致的30fps。(如果插值帧会更好,但这要困难得多。)
用于慢速录制。
mMediaRecorder.setVideoFrameRate(QUALITY_HIGHT_SPEED_LOW);
用于高速记录。
mMediaRecorder.setVideoFrameRate(QUALITY_HIGH_SPEED_HIGH);
我认为这个问题包含两个独立的问题。
- 如何激活比60FPS更快的高速捕获模式
- 如何降低
MediaCodec
编码器生成的FPS速度
第二部分很简单。如本答案所述,您可以插入插值/伪帧,也可以修改时间戳。第一部分的特殊之处在于,大多数样本代码处理正常模式的捕获,而不是本用例中所需的高速捕获(通常高于60FPS,一般来说,我们处理的是120~240FPS)
关于问题的第一部分,我想让你看看关于Camera2约束的高速捕获API的描述,比如这样。不幸的是,对于这样一个API,似乎只有小众的需求,我无法收集到关于我自己的发现的太多信息,我目前正在处理精神上繁重的项目,以自己创建一个示例代码。然而,从它与普通电影录制和连拍镜头的相似性来看,我不认为导出这样的用例会有那么复杂。