如何使用FFmpeg更改视频帧速率,无损并保持相同的总帧数?

时间:2017-05-27 14:58:40

标签: video ffmpeg frame frame-rate rate

我一直在寻找Stack Overflow上的答案并在谷歌上搜索...即使它看起来对我来说应该是一个非常简单的命令行,但我无法在任何地方找到答案

我想用FFmpeg将视频的帧速率从23.976fps更改为24fps,无损并保持帧总数。

使其更简单:

假设我的 25fps视频总长度为100帧

如何将帧速率更改为50fps FFmpeg 无损保持相同的总数长度为100帧

这是迄今为止我遇到的最佳解决方案(可以找到here):

  

将帧提取为rawvideo:

     

ffmpeg -i input.mov -f rawvideo -b 50000000 -pix_fmt yuv420p -vcodec   rawvideo -s 1920x1080 -y temp.raw

     

使用新的帧速率重新制作视频:

     

ffmpeg -f rawvideo -b 50000000 -pix_fmt yuv420p -r 24 -s 1920x1080 -i   temp.raw -y output.mov

注1: 在使用新的帧速率重新创建视频时,我必须删除" -b 50000000" ,以便让它正常工作。

它完全符合我的意图,但我仍然想知道是否有更简单的方法可以做到这一点?我试图将它们一起排在一条线上,正如同一篇文章中所建议的那样,但无法让它发挥作用。

注2: 尽管它确实完全符合我的要求,但我后来才意识到使用此方法存在质量损失,我宁愿避免

提前感谢大家!

2 个答案:

答案 0 :(得分:2)

如果你的视频编解码器是H.264 / 5,那么这个两步法是有效的,并且是无损的。

#1 Demux to raw bitstream

ffmpeg -i in.mov -c copy in.264

#2 使用新帧速率重新启动

ffmpeg -r 24 -i in.264 -c copy out.mov

对于其他编解码器,如果有可用的原始比特流格式,则无需转码即可完成。

如果转码很好,则以下单步操作:

ffmpeg -r 24 -i in.mov -vsync 0 -c:v <codecname> out.mov 

当然,您需要指定bitrate..etc等参数来控制质量。

答案 1 :(得分:0)

接受的答案会掉音频吗?

如果是这样,我认为以下python代码做了同样的事情,只需设置一个新的FPS并重写视频文件即可:

import cv2 as cv
import time

time0 = time.time()
vid = cv.VideoCapture('input.flv')
fps = vid.get(cv.CAP_PROP_FPS)
frame_width = round(vid.get(cv.CAP_PROP_FRAME_WIDTH))
frame_height = round(vid.get(cv.CAP_PROP_FRAME_HEIGHT))
frame_count = round(vid.get(cv.CAP_PROP_FRAME_COUNT))

target_fps = fps
target_width = 800
target_height = frame_height * target_width // frame_width

out = cv.VideoWriter('output.mp4',
                     cv.VideoWriter_fourcc(*'avc1'), target_fps, (target_width,target_height))

time1 = time.time()
print('Time passed is %.3fs' % (time1 - time0))

ret, frame = vid.read()

i = 0
while ret:
    i += 1
    if frame_width != target_width:
        frame = cv.resize(frame, (target_width, target_height), interpolation=cv.INTER_LINEAR)
    out.write(frame)
    ret, frame = vid.read()

out.release()
vid.release()

print("COST: %.3fs" %(time.time() - time1))

在这里,我还将视频比例更改为800:-1。

希望有更好的方法同时保留所有帧和音频。