如何使用 FFmpeg 更改视频帧速率,无损并保持相同的总帧数?
How can I change a video frame rate with FFmpeg, lossless and keeping the same total number of frames?
我一直在 Stack Overflow 上寻找答案并到处谷歌搜索...尽管它对我来说似乎应该是一个非常简单的命令行,但我在任何地方都找不到答案。
我想使用 FFmpeg 将视频的帧速率从 23.976fps 更改为 24fps,无损并保持总帧数。
为了更简单:
假设我有一个 25fps 视频,总长度为 100 帧。
如何使用 FFmpeg、lossless 和 将帧速率更改为 50fps 保持相同的 100 帧总长度?
这是迄今为止我遇到的最好的解决方案(可以在 here 找到):
Extract the frames as rawvideo:
ffmpeg -i input.mov -f rawvideo -b 50000000 -pix_fmt yuv420p -vcodec
rawvideo -s 1920x1080 -y temp.raw
Recreate the video with new framerate:
ffmpeg -f rawvideo -b 50000000 -pix_fmt yuv420p -r 24 -s 1920x1080 -i
temp.raw -y output.mov
注意 1: 在使用新帧重新创建视频时,我不得不删除 "-b 50000000"率,以使其正常工作。
它完全符合我的预期,但我仍然想知道是否有更简单的方法来做到这一点?我曾尝试将它们仅用管道连接在一起,正如 post 中所建议的那样,但无法正常工作。
注意 2: 尽管它完全符合我的要求,但我后来才意识到使用这种方法存在质量损失,这我宁愿避免。
先谢谢大家了!
如果您的视频编解码器是 H.264/5,那么这种两步法就可以了,而且是无损的。
#1 解复用到原始比特流
ffmpeg -i in.mov -c copy in.264
#2 具有新帧率的 Remux
ffmpeg -r 24 -i in.264 -c copy out.mov
对于其他编解码器,如果有可用的原始比特流格式,则无需转码即可完成。
如果转码没问题,下面的一步就可以了:
ffmpeg -r 24 -i in.mov -vsync 0 -c:v <codecname> out.mov
当然,您需要指定比特率等参数来控制质量。
已接受的答案掉了音频?
如果那是真的,我认为下面的 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
希望有更好的方法来保留所有帧和音频。
我一直在 Stack Overflow 上寻找答案并到处谷歌搜索...尽管它对我来说似乎应该是一个非常简单的命令行,但我在任何地方都找不到答案。
我想使用 FFmpeg 将视频的帧速率从 23.976fps 更改为 24fps,无损并保持总帧数。
为了更简单:
假设我有一个 25fps 视频,总长度为 100 帧。
如何使用 FFmpeg、lossless 和 将帧速率更改为 50fps 保持相同的 100 帧总长度?
这是迄今为止我遇到的最好的解决方案(可以在 here 找到):
Extract the frames as rawvideo:
ffmpeg -i input.mov -f rawvideo -b 50000000 -pix_fmt yuv420p -vcodec rawvideo -s 1920x1080 -y temp.raw
Recreate the video with new framerate:
ffmpeg -f rawvideo -b 50000000 -pix_fmt yuv420p -r 24 -s 1920x1080 -i temp.raw -y output.mov
注意 1: 在使用新帧重新创建视频时,我不得不删除 "-b 50000000"率,以使其正常工作。
它完全符合我的预期,但我仍然想知道是否有更简单的方法来做到这一点?我曾尝试将它们仅用管道连接在一起,正如 post 中所建议的那样,但无法正常工作。
注意 2: 尽管它完全符合我的要求,但我后来才意识到使用这种方法存在质量损失,这我宁愿避免。
先谢谢大家了!
如果您的视频编解码器是 H.264/5,那么这种两步法就可以了,而且是无损的。
#1 解复用到原始比特流
ffmpeg -i in.mov -c copy in.264
#2 具有新帧率的 Remux
ffmpeg -r 24 -i in.264 -c copy out.mov
对于其他编解码器,如果有可用的原始比特流格式,则无需转码即可完成。
如果转码没问题,下面的一步就可以了:
ffmpeg -r 24 -i in.mov -vsync 0 -c:v <codecname> out.mov
当然,您需要指定比特率等参数来控制质量。
已接受的答案掉了音频?
如果那是真的,我认为下面的 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
希望有更好的方法来保留所有帧和音频。