You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MoviePy处理Windows游戏栏录制视频时画面倍速音频正常的问题

MoviePy处理Windows游戏栏录制视频时画面倍速、音频正常的问题

问题现象

使用MoviePy处理Windows游戏栏录制的视频时,仅执行读取后直接重写的操作,输出视频画面播放速度翻倍,但音频保持正常。其他来源的视频无此异常。

读取重写测试代码:

full_video = VideoFileClip(input_video_path)
full_video.write_videofile("output.mp4")
quit()

进一步排查确认问题出在视频读取阶段:预览时画面同样倍速,打印出的帧率与实际不符。
预览测试代码:

full_video = VideoFileClip(input_video_path)
print(full_video.fps)
full_video.preview(fps=full_video.fps)
quit()

根因分析

Windows游戏栏录制的视频默认采用**可变帧率(VFR)**编码,目的是在保证录屏性能的同时动态调整帧率。而MoviePy的VideoFileClip默认按固定帧率(CFR)解析视频,会错误识别VFR视频的帧率(通常取到平均帧率或峰值帧率),导致画面播放速度异常,而音频因为是固定码率/采样率,不受影响。

解决方案

1. 临时修复:分离音视频后调整视频速度

通过分离音视频,将视频减速至正常速度后重新合并,代码示例:

from moviepy.editor import *

full_video = VideoFileClip(input_video_path)
# 分离音频轨道
audio = full_video.audio
# 将视频减速50%抵消倍速问题
video = full_video.set_speed(0.5)
# 重新合并音视频
fixed_clip = video.set_audio(audio)
fixed_clip.write_videofile("fixed_output.mp4")

2. 根本解决:强制解析正确帧率

方法一:手动指定正确帧率

先通过FFmpeg命令获取视频的实际平均帧率:

ffmpeg -i input.mp4 -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1

将得到的帧率值(比如30/1)转换为浮点数(30),然后在VideoFileClip初始化时手动指定:

full_video = VideoFileClip(input_video_path, fps=30)

方法二:转码为固定帧率(CFR)

先用FFmpeg将VFR视频转成固定帧率的视频,再用MoviePy处理:

ffmpeg -i input.mp4 -r 30 -c:v libx264 -crf 23 -c:a copy fixed_input.mp4

之后用fixed_input.mp4作为输入源,MoviePy处理就不会出现速度异常。

修正后的完整处理代码

结合你的剪辑需求,修改后的完整代码如下(加入手动指定帧率的处理):

from moviepy.editor import *

# 配置参数
times_path = "times.txt"
input_video_path = "input.mp4"
# 替换为你通过FFmpeg获取的实际帧率
CORRECT_FPS = 30

offset_time = 0
clip_length = float(input("Enter clip length: "))

def get_times(path, offset):
    dash_times_str = []
    with open(path, "r") as file:
        dash_times_str = file.readlines()

    temp = [line.strip() for line in dash_times_str]
    dash_times = [float(time) + offset for time in temp]
    return dash_times

dash_times = get_times(times_path, offset_time)

def get_offset_time():
    a = float(input("Enter time for first dash in video: "))
    b = dash_times[0]
    return a - b

offset_time = get_offset_time()

# 手动指定正确帧率读取视频
full_video = VideoFileClip(input_video_path, fps=CORRECT_FPS)

counter = 0
times_count = len(dash_times)
clips = []
for dash_time in dash_times:
    clip = full_video.subclip(dash_time, dash_time + clip_length)
    clips.append(clip)
    counter += 1
    print(f"Clip {counter} out of {times_count}")

final_clip = concatenate_videoclips(clips)
final_clip.write_videofile("output.mp4")

内容的提问来源于stack exchange,提问作者Jay Mehta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 09:18:28