简体   繁体   English

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

[英]How can I change a video frame rate with FFmpeg, lossless and keeping the same total number of frames?

I've been searching for an answer here on Stack Overflow and googling everywhere... even though it seems like it should be a very simple command line to me, I just can't find an answer anywhere.我一直在 Stack Overflow 上寻找答案并到处搜索……尽管对我来说它应该是一个非常简单的命令行,但我在任何地方都找不到答案。

I would like to change the frame rate of a video from 23.976fps to 24fps with FFmpeg, lossless and keeping the total number of frames.我想使用 FFmpeg 将视频的帧速率从 23.976fps 更改为 24fps,无损并保持总帧数。

To make it simpler:为了使它更简单:

Let's say I have a 25fps video with a total lenght of 100 frames .假设我有一个25fps 的视频总长度为 100 帧

How can I change it's frame rate to 50fps , with FFmpeg , lossless and keeping the same total lenght of 100 frames ?如何使用FFmpeg将其帧速率更改为 50fps无损保持 100 帧的总长度相同

This was so far the best solution I came across with (which can be found here ):这是迄今为止我遇到的最好的解决方案(可以在这里找到):

Extract the frames as rawvideo:将帧提取为 rawvideo:

ffmpeg -i input.mov -f rawvideo -b 50000000 -pix_fmt yuv420p -vcodec rawvideo -s 1920x1080 -y temp.raw 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 ffmpeg -f rawvideo -b 50000000 -pix_fmt yuv420p -r 24 -s 1920x1080 -i temp.raw -y output.mov

Note 1: I had to remove "-b 50000000" when recreating the video with the new frame rate, in order to get it to work properly.注意 1:在使用新的帧速率重新创建视频时,我必须删除“-b 50000000” ,以使其正常工作。

It did exactly what I intended it to do, but I'm still wondering if there is any simpler way to do this?它完全符合我的意图,但我仍然想知道是否有更简单的方法来做到这一点? I've tried to pipe them together in one line only, as suggested in the same post, but couldn't get it to work.正如同一篇文章中所建议的那样,我尝试将它们仅在一行中连接在一起,但无法使其正常工作。

Note 2: Even though it does exactly what I wanted it to do, I've just later realized there is quality loss using this method, which I would prefer to avoid.注 2:尽管它完全符合我的要求,但我后来才意识到使用这种方法会造成质量损失,我宁愿避免这种情况。

Thanks everyone in advance!提前谢谢大家!

If your video codec is H.264/5, then this two-step method works, and is lossless.如果您的视频编解码器是 H.264/5,则此两步方法有效且无损。

#1 Demux to raw bitstream #1解复用到原始比特流

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

#2 Remux with new framerate #2使用新帧率重新混合

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

For other codecs, if there's a raw bitstream format available, then it can be done without transcoding.对于其他编解码器,如果有可用的原始比特流格式,则无需转码即可完成。

If transcoding is fine, the following single step works:如果转码没问题,以下单步工作:

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

Of course, you'll want to specify parameters like bitrate..etc to control quality.当然,您需要指定比特率等参数来控制质量。

The accepted answer drops the audio?接受的答案会丢弃音频吗?

If that's true, I think the following python code did the same thing, just set a new FPS and rewrite video files:如果这是真的,我认为下面的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))

Here I have also change the video scale to 800:-1.在这里,我还将视频比例更改为 800:-1。

Hope there is a better way to keep both all frames and audio.希望有更好的方法来保留所有帧和音频。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ffmpeg-如何在保留视频总帧数的同时缩放视频? - ffmpeg - how can I scale the video while perserving the total frames in it? 如何使用FFMPEG将视频的第一帧转换为I帧,然后将其余部分转换为P帧? - How can I convert the first frame of a video to an I-frame and the rest to P-frames with FFMPEG? FFmpeg:如何使用 C++ 代码更改视频文件的帧速率? - FFmpeg: how to use C++ code to change the frame rate of a video file? Directshow:如何更改视频的大小和帧速率? - Directshow : How to change Size and frame rate of video? 如何使用ffmpeg从YUV视频中提取帧(或垂直帧) - How to extract frames(or a perticular frame) from a YUV video using ffmpeg 如何使用ffmpeg按帧数(包括视频和音频)裁剪视频的一部分? - How can I use ffmpeg to crop a part of a video by frames numbers including video and audio? 使用ffmpeg提取每一帧以形成可变帧率视频 - Extract every frame form a variable-frame-rate video with ffmpeg ffmpeg-从视频中提取确切的帧数 - ffmpeg - extract exact number of frames from video FFMPEG:视频比特率的动态变化 - FFMPEG: Dynamic change of bit_rate for Video ffmpeg:相同的视频,相同的帧速率,不同数量的输出帧。 为什么? - ffmpeg: same video, same framerate, different number of output frames. Why?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM