題 在沒有重新編碼的情況下更改ffmpeg中的幀速率


我有一個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中執行此操作(如果存在)的正確方法是什麼?


8
2018-06-12 17:02


起源


我相信目前FFmpeg是不可能的。 -r 與流複製不兼容,並且沒有比特流過濾器來更改幀速率。 - Ely
太糟糕了。我每次都要使用mkvmerge。謝謝 - phate89
使用常規ffmpeg以及使用舊版本的ffmpeg進行此操作的直接方法,有一種令人費解的方法。如果你有興趣,我會把它寫成答案。 - Gyan
是的,謝謝..我想沒有額外的工具(我已經需要ffmpeg) - phate89
你正在談論@Mulvya 這個 對 ?我猶豫要把它聯繫起來,但它現在已經老了。雖然對於常規的FFmpeg有興趣以復雜的方式做到這一點。 - Ely


答案:


這是使用當前版本的FFmpeg的方法。它依賴於concat demuxer在第一個文件之後不重新調整輸入的PTS,而只是應用固定的偏移量。假設您有30 fps的流,其時間尺度為 15360 (典型的FFmpeg輸出)。這意味著框架 0 有PTS 0 和框架 30 有PTS 15360。如果我們可以將時間刻度更改為,則這將成為45 fps流 23040 而不影響PTS值。

基本上,這就是下面的方法。

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。計算所需的時間刻度,以便達到目標幀速率 x,幀的PTS# x 在源中應該具有與新的相同的值 tbn。 如果你執行了步驟2a,這很容易,它只是新的幀率。所以,對於目標fps 45,新的 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 Concat視頻。

首先製作一個文本文件

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

然後,concat

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

輸出文件將以45 fps播放第二個視頻。

。現在,切斷虛擬預卷

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)

我確實說這很複雜!


8
2018-06-17 12:55



非常聰明,很好的答案。 - Rowe Morehouse