FFmpeg:在任何编解码器(不仅仅是 H264)上强制重新生成 PTS(即在不重新编码的情况下改变帧速率)?

FFmpeg:在任何编解码器(不仅仅是 H264)上强制重新生成 PTS(即在不重新编码的情况下改变帧速率)?

基本上,我想强制更改文件的帧速率不是使用 H.264 编码。使用 H.264 我可以执行以下操作:

# Assume I want to take a 30FPS file and make it 60FPS, effectively doubling the speed.

# Extract the H264 stream from the source file to a raw H264 stream
ffmpeg -i source.mp4 -map 0:v -vcodec copy -bsf:v h264_mp4toannexb source-video.h264

# Force FFMPEG to regenerate the PTS values for the H264 stream
ffmpeg -fflags +genpts -r 60 -i source-video.h264 -vcodec copy output.mp4

这种技术由 FFmpeg 自己记录并且已经解释过了超级用户这也与您在 Google 上搜索时会找到的结果非常相似。

但是假设我的源流是非 H.264 或 H.265 格式,因此我无法使用该命令序列。例如,假设我有一个 FFV1 流(来自存档源),或一个 MPEG2 流(来自 DVD),甚至一个 MPEG1 流(来自 VideoCD 等)。假设我想将视频保留在其原始编解码器中,因此编码为 H.264,进行帧速率转换,然后转换回原始格式是两代额外的有损压缩,这绝对不符合“无需重新编码”的条件。

我尝试过在其他编解码器(如 FFV1)上使用 vsync-drop 和 setpts,但似乎不起作用:

# source is FFV1 at 30fps
# this produces a 1.5 second output for 60 seconds of video
# output is only the first few frames of source, still at 30fps
# ffprobe also shows 30fps for the output file

ffmpeg -vsync drop -fflags +genpts -i ffv1video.mkv -map 0:v -c copy ffv1fastvideo.mkv 

# removing -vsync drop results in an identical output file
ffmpeg -fflags +genpts -i ffv1video.mkv -map 0:v -c copy -r 60 ffv1fastvideo.mkv

# adding a frame rate to the input changes nothing
ffmpeg -r 60 -vsync drop -fflags +genpts -i ffv1video.mkv -map 0:v -c copy -r 60 ffv1fastvideo.mkv

# you can't use -vf setpts=... if you are using -c copy

如果我还使用 mpeg2 之类的编解码器,则上述所有方法都适用。基本上,我只想在每个帧上重新生成 PTS,而不重新编码整个流。

似乎这是 FFmpeg 应该能够在 h.264 和 h.265 以外的流上做的事情 - 我可以做到吗?

答案1

您可以使用比特流过滤器 来实现这一点setts。这是因为虽然您不能将普通过滤器与编解码器复制 ( -c:v copy) 一起使用(因为它们在解码的视频流上工作),但您可以使用在编码流上工作的比特流过滤器。

我在这里有一篇关于此内容的更详细的帖子:无需重新编码即可更改 ffmpeg 中的帧速率

相关内容