我用我的 GoPro Hero10 拍摄了一段 30 秒 240fps 的视频。现在我想用它制作一个“慢动作”,速度应该是 1/4。因此输出将是 2 分钟 @ 60fps。(声音也应该转换 - 我知道这会让音调变低,没关系)
经过一些研究,我得出了以下结论:
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=4.0*PTS[v];[0:a]atempo=0.5,atempo=0.5[a]" -map "[v]" -map "[a]" output-0.25.mp4
但经检查后ffmpeg -i output-0.25.mp4
我发现,fps 仍然是 240(虽然长度是正确的,但它是慢动作,声音还可以,但文件大小很大,而且 - 如上所述 - 在目标设备上播放的 fps 太多了)。
因此我再次搜索并添加,-r 60
最终得到:
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=4.0*PTS[v];[0:a]atempo=0.5,atempo=0.5[a]" -map "[v]" -map "[a]" -r 60 output-0.25.mp4
现在检查也显示了正确的 fps,但似乎“不够慢”并且声音刺耳。
我需要做什么?
我想要的是“取出所有原始帧并将其放入一个文件中,以‘正常速度’播放”。
答案1
有 setpts 模式和转换为原始模式。
使用 setpts 将是这样的:
ffmpeg input.mkv -map_metadata -1 -filter_complex "[0:v:0]setpts=PTS*4[v];[0:a:0]atempo=0.5,atempo=0.5[a]" -map [v] -map [a] -c:v libx265 -vtag hvc1 -c:a libmp3lame -shortest "output.mp4"
- 使用好的编解码器来减小文件大小,如 H.265(libx265)
- 我怀疑是因为原始视频的元数据显示为 240 FPS,而元数据在转换过程中未被删除,所以输出视频也显示 240 FPS,但实际上为 60 FPS。-map_metadata -1 选项将删除元数据。
使用转换为原始模式将是这样的:
在这个例子中,我假设原始视频是 H.264 编解码器:
ffmpeg -i input.mp4 -map 0:v -c:v copy -bsf:v h264_mp4toannexb raw.h264
ffmpeg -fflags +genpts -r 60 -i "raw.h264" -i input.mp4 -map 0:v -map 1:a -filter:a "atempo=0.5,atempo=0.5" -c:v libx265 -vtag hvc1 "output.mp4"
在第一个命令中,原始视频被转换为原始视频,在第二个命令中,生成新的时间戳,使视频播放速度减慢 4 倍,将原始视频中的音频添加到原始视频中,将音频速度降低 4 倍,最后将原始视频转换为 H.265 以减小文件大小。
答案2
这是一个无需重新编码视频的解决方案:
- 将视频流提取为 HEVC(H.265)“原始”视频流:
ffmpeg -y -an -i testfile.mp4 -c copy input_video.h265
- 使用比特流过滤器将其修改
tick_rate
为60
“每秒刻数”hevc_metadata
:
ffmpeg -y -i input_video.h265 -c copy -bsf:v hevc_metadata=tick_rate=60:num_ticks_poc_diff_one=1 input_video2.h265
input_video2.h265
与“放慢速度”的音频合并:
ffmpeg -y -i input_video2.h265 -vn -i testfile.mp4 -map_metadata -1 -af "atempo=0.5,atempo=0.5" -c:v copy -vtag hvc1 -c:a aac -shortest "output.mp4"
“减慢”的音频听起来很奇怪,但我找不到比使用atempo
两次更好的解决方案。