ffmpeg将可变帧率.webm转换为恒定帧率视频

时间:2019-07-08 14:47:44

标签: opencv image-processing video ffmpeg video-processing

我有一个游戏录制速度为.fps的.webm文件。但是,在尝试使用OpenCV处理视频时,似乎视频是以可变帧率录制的,因此,当我尝试使用OpenCV通过获取第16帧来每秒获取一帧时,由于视频,该视频将无法工作流将过早结束。

因此,我正在尝试将声称帧速率为16 fps的可变帧.webm视频转换为具有恒定帧的视频,因此我可以每秒提取一帧。我从https://ffmpeg.zeranoe.com/forum/viewtopic.php?t=5518尝试了以下ffmpeg命令:

ffmpeg -i input.webm -c:v copy -b:v copy -r 16 output.webm

但是,会发生以下错误:

[NULL @ 00000272ccbc0c40] [Eval @ 000000bc11bfe2f0] Undefined constant or missing '(' in 'copy'
[NULL @ 00000272ccbc0c40] Unable to parse option value "copy"
[NULL @ 00000272ccbc0c40] Error setting option b to value copy.

Error setting up codec context options.

这是我每秒用来处理一帧的代码:

video = cv2.VideoCapture(test_mp4_vod_path)
print("Opened ", test_mp4_vod_path)
print("Processing MP4 frame by frame")

# forward over to the frames you want to start reading from.
# manually set this, fps * time in seconds you wanna start from
video.set(1, 0)
success, frame = video.read()
#fps = int(video.get(cv2.CAP_PROP_FPS))  # this will return 0!
fps = 16  # hardcode fps
total_frame_count = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
print("Loading video %d seconds long with FPS %d and total frame count %d " % (total_frame_count/fps, fps, total_frame_count))

count = 1
while video.isOpened():
    success, frame = video.read()
    if not success:
        break

    if count % fps == 0:
        print("%dth frame is %d seconds on video"%(count, count/fps))
    count += 1

由于视频的FPS并不恒定,因此代码会在接近视频结尾之前完成。 如何将可变FPS视频转换为恒定FPS视频?

2 个答案:

答案 0 :(得分:0)

可能的解决方案(2M是一个测试值,请针对您的视频进行调整):

ffmpeg -i input.we -c:v libvpx-vp9 -minrate 2M -maxrate 2M -b:v 2M -pix_fmt yuv420p -r 16 output.webm

答案 1 :(得分:0)

首先,来自VC的另一个答案是您需要的答案。但是,这并不是您问题的确切答案。

您的命令有一个小错误,这就是引发该错误的原因。 -b:v告诉ffmpeg应该将v理想b itrate设置为给定值。在输入中,将其设置为copy。这不是此选项的有效值。比特率选项需要一个数字,可能是一个数量级,例如320k320000

要么打算复制音频编解码器(在这种情况下应为-c:a copy),要么打算复制视频比特率。对于后者,只需完全删除该参数即可; -c:v copy 产生(选择的部分)视频流的精确副本,其中包括比特率,帧数,帧率和时间戳以及所有其他视频数据。

要将输出设置为具有与输入相同的视频比特率而不进行复制,请使用ffprobe首先检查流的比特率。