无需重新编码即可更改 ffmpeg 中的帧率

pha*_*e89 19 video ffmpeg framerate

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

ffmpeg -i input.mkv -r 25 -vcodec copy output.mkv
Run Code Online (Sandbox Code Playgroud)

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

Gya*_*yan 17

这是使用当前版本的 FFmpeg 的方法。它依赖于 concat demuxer,不会在第一个文件之后重新调整输入的 PTS,而是简单地应用一个固定的偏移量。假设您有一个 30 fps 的流,时间刻度为15360(典型的 FFmpeg 输出)。这意味着 frame0有 PTS0并且 frame30有 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)
Run Code Online (Sandbox Code Playgroud)

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


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

ffmpeg -i in.mp4 -c copy -an -video_track_timescale 30 in-v30.mp4
Run Code Online (Sandbox Code Playgroud)

这让我们

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

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

2b。计算所需的时间刻度,以便对于目标帧率xx源中帧 # 的 PTS应与新的tbn. 如果您执行了第 2a 步,这很容易,它只是新的帧速率。因此,对于目标 fps 45, newtbn应该是45.


3 . 生成虚拟视频。

ffmpeg -f lavfi -i color=s=1280x720:r=45:d=1 -profile:v main -video_track_timescale 45 0.mp4
Run Code Online (Sandbox Code Playgroud)

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


4连接视频。

首先制作一个文本文件

file '0.mp4'
file 'in-v30.mp4'
Run Code Online (Sandbox Code Playgroud)

然后,连接

ffmpeg -f concat -i list.txt -c copy -video_track_timescale 45 45fps.mp4
Run Code Online (Sandbox Code Playgroud)

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

5 . 现在,切掉虚拟预卷

ffmpeg -ss 1.1 -i 45fps.mp4 -c copy -avoid_negative_ts make_zero in45.mp4
Run Code Online (Sandbox Code Playgroud)

你有

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

我确实说过这很复杂!

  • 很聪明,很好的答案。 (2认同)

小智 13

ffmpeg -itsscale 1.0427083 -i input.mp4 -codec copy output.mp4
Run Code Online (Sandbox Code Playgroud)

这可以正确地将 Handbrake 从 PAL DVD 源创建的 25 fps mp4 减慢到 23.974 fps。原始节目是 NTSC。在 47 分钟的播放时间内,音频始终保持同步。由于没有进行解码/编码,因此速度非常快。然而,整个过程中每隔大约 3 秒就会出现音频故障(丢失)。替换编解码器的结果相同vcodec,除了视频未重新编码时,音频以原始比特率的一半重新编码,并且仍然存在丢失毛刺。

ffmpeg -itsscale 1.0427083 -i input.mp4 -vcodec copy -filter:a "atempo=0.959041" output.mp4
Run Code Online (Sandbox Code Playgroud)

这消除了音频丢失,但会重新编码音频。这比重新编码视频要快得多。剩下的缺点是它默认为原始音频比特率的一半。需要弄清楚如何设置重新编码的音频比特率。


ula*_*ekh 6

用于-itsscale输入视频以实现有效的帧速率更改。它与-vcodec copy.

  • @Barbara:不,会没事的。存储的 FPS 值主要是信息性的;演示时间戳才是真正重要的。 (2认同)