更改ffmpeg中的帧速率而无需重新编码


14

我有23.976 fps(24000/1001)的mkv(h264)视频,但我想将其转换为25fps,而无需重新编码和质量下降。我知道mkvmerge可以做到这一点(使用--default-duration'0:25fps'选项),但是我想尽可能直接从ffmpeg做到这一点。根据文档,这应该可以工作:

ffmpeg -i input.mkv -r 25 -vcodec copy output.mkv

但是当我执行它时,我只会得到相同的视频fps。在ffmpeg中正确的方法是什么(如果存在)?


1
我认为目前无法使用FFmpeg。-r与流复制不兼容,也没有用于更改帧速率的位流过滤器。
2016年

1
太糟糕了。我每次都必须使用mkvmerge。谢谢
phate89 '16

1
有一种复杂的方法可以使用常规ffmpeg来实现,而直接的方法可以通过ffmpeg的旧改进版来实现。如果您有兴趣,我会写出来作为答案。
Gyan

1
是的,谢谢。.我想不用额外的工具来做(我已经需要ffmpeg)
phate89'6

1
@Mulvya你在说这个吗?我犹豫要不要链接它,但是它已经很老了。
2016年

Answers:


15

这是使用FFmpeg当前版本的方法。它依赖于concat多路分配器不对第一个文件之后的输入的PTS进行缩放,而仅应用固定的偏移量。假设您有一个30 fps的流,其时标为15360(典型值为FFmpeg输出)。这意味着框架0具有PTS 0,框架30具有PTS 15360。如果我们可以将时标更改为23040不影响PTS值,则它将变成45 fps流。

本质上,这就是下面的方法。

1。标识源属性。

Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1171 kb/s,
       30 fps, 30 tbr, 15360 tbn (default)

您要注意源属性,尤其是分辨率和tbn


2a。(可选)将时间刻度更改为方便的名称,以使计算更简单。

ffmpeg -i in.mp4 -c copy -an -video_track_timescale 30 in-v30.mp4

这让我们

Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1171 kb/s, \
       30 fps, 30 tbr, 30 tbn (default

如果执行此步骤,则新的时间刻度应等于或等于原始帧速率的整数倍。

2b。计算所需的时间尺度,以便对于目标帧速率xx源中帧#的PTS 应该具有与new相同的值tbn。如果执行了步骤2a,这将非常容易,并且仅仅是新的帧速率。因此,对于目标fps 45,new tbn应该是45


3。生成虚拟视频。

ffmpeg -f lavfi -i color=s=1280x720:r=45:d=1 -profile:v main -video_track_timescale 45 0.mp4

所有属性都应相同,例如分辨率,H.264配置文件,像素格式,引用计数..等,以获得最佳效果。


4合并视频。

首先制作一个文本文件

file '0.mp4'
file 'in-v30.mp4'

然后,concat

ffmpeg -f concat -i list.txt -c copy -video_track_timescale 45 45fps.mp4

输出文件将以45 fps播放第二个视频。

5。现在,切断假人预卷

ffmpeg -ss 1.1 -i 45fps.mp4 -c copy -avoid_negative_ts make_zero in45.mp4

你有

Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1757 kb/s, \
       45 fps, 45 tbr, 11520 tbn (default)

我确实说这很麻烦!


1
非常聪明,很好的答案。
Rowe Morehouse
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.