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

Python录屏程序帧率异常、实际时长与设置不符的问题求助

Python录屏程序帧率异常、实际时长与设置不符的问题求助

我最近在做一个Python录屏程序,目标是能指定录制时长(比如10秒)和帧率(比如30FPS),但遇到了两个头疼的问题:

  • 录出来的视频要么快进5倍,要么帧率特别低,明明设置的是30FPS
  • 时长完全不对,设置10秒实际只有6秒左右

这是我目前用的代码:

import pyautogui
import cv2
import numpy as np
import time

screen_width, screen_height = pyautogui.size()
fps = 30
duration = 10  # Set duration to 10 seconds

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, fps, (screen_width, screen_height))

start_time = time.time()
while True:
    screenshot = pyautogui.screenshot()
    frame = np.array(screenshot)
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
    out.write(frame)
    
    if time.time() - start_time > duration:
        break

out.release()
cv2.destroyAllWindows()

遇到的具体问题:

  • 帧率/播放速度异常:播放时要么快得离谱(5倍速),要么帧率很低,和设置的30FPS完全不符
  • 时长不匹配:设置10秒的录制时长,实际视频只有约6秒

我已经尝试过的方法:

  • 调整fps参数,没用
  • 更换视频编码格式,没效果
  • 在帧之间加sleep延迟,也没改善

问题原因分析

其实核心问题是你没有控制每帧的捕获间隔:
pyautogui.screenshot()和后续的帧转换、写入操作是需要时间的,比如假设每帧处理耗时0.05秒,那实际每秒只能捕获20帧,但你告诉cv2.VideoWriter要按30FPS来编码。播放器会用30FPS的速度播放实际只有20帧的内容,10秒录制周期内你只捕获了200帧,200÷30≈6.7秒,所以播放时长就变短了,内容也会显得快进。

解决方案:控制帧间隔+固定总帧数

我们可以通过计算每帧的理想间隔,同时限制总帧数(fps × duration)来解决这个问题,这样既能保证录制时长准确,又能让实际帧率接近设置值。

修改后的代码如下:

import pyautogui
import cv2
import numpy as np
import time

screen_width, screen_height = pyautogui.size()
fps = 30
duration = 10  # 目标录制时长
total_frames = fps * duration  # 总帧数
frame_interval = 1.0 / fps  # 每帧的理想间隔时间

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, fps, (screen_width, screen_height))

start_time = time.time()
for _ in range(total_frames):
    # 记录当前帧开始的时间
    frame_start = time.time()
    
    # 捕获并处理帧
    screenshot = pyautogui.screenshot()
    frame = np.array(screenshot)
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
    out.write(frame)
    
    # 计算需要等待的时间,确保每帧间隔符合设置
    elapsed = time.time() - frame_start
    sleep_time = frame_interval - elapsed
    if sleep_time > 0:
        time.sleep(sleep_time)

out.release()
cv2.destroyAllWindows()

代码改动说明:

  1. 固定总帧数:通过total_frames = fps * duration计算出需要录制的总帧数,循环固定次数,从根本上保证录制的内容对应目标时长
  2. 控制帧间隔:计算每帧的理想间隔frame_interval = 1.0 / fps,然后减去当前帧处理耗时,用time.sleep()补足剩余时间,确保每秒捕获的帧数尽可能接近设置的30FPS
  3. 避免无限循环的误差:原来的while True循环会因为判断时间的微小误差导致多录或少录,固定循环次数更准确

如果你的电脑性能有限,pyautogui.screenshot()耗时超过frame_interval,那sleep时间会是负数,这时候就不会sleep,这种情况下实际帧率会低于设置值,但播放时长还是会和目标一致(因为总帧数是固定的),不会出现快进的情况。

备注:内容来源于stack exchange,提问作者Philip Neumair

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:57:59