如何将Python实现的录屏程序帧率从15FPS提升至60FPS?
录屏程序FPS提升问题
我正在尝试用Python编写录屏程序,但当前程序仅能达到15FPS,希望提升至60FPS。以下是我的代码:
import cv2 import numpy as np import pyautogui import time from win32api import GetSystemMetrics width = GetSystemMetrics(0) # 获取系统默认分辨率宽度 height = GetSystemMetrics(1) dim = (width,heigth) # 拼写错误:heigth → height f = cv2.VideoWriter_fourcc(*"XVID") # 视频编码格式的四字符代码 output = cv2.VideoWriter("test.mp4",f,60.0,dim) # 参数说明:输出文件名、编码格式、帧率、分辨率 try: # 当前循环每秒仅能捕获15帧,导致输出视频实际为15FPS,但设置了60FPS,播放时会加速 while True: image = pyautogui.screenshot() # 截图操作是性能瓶颈 frame_1 = np.array(image) # 转换为numpy数组 frame = cv2.cvtColor(frame_1,cv2.COLOR_BGR2RGB) # 转换颜色空间 output. Write(frame) # 语法错误:output.write(frame)(去掉空格) # 打印当前时间观察循环速度,但会拖慢性能 print(i+"\r") i = time.ctime() # 变量i未初始化,会报错 except KeyboardInterrupt: pass output. Release() # 语法错误:output.release()(去掉空格)
问题说明:我的代码每秒仅能捕获15帧,但视频输出设置为60FPS,导致播放时画面速度加快,请问该如何解决?
解决方法
1. 先修正代码基础错误
先把代码里的拼写和语法问题修复,保证程序正常运行:
- 将
heigth改为height - 去掉
output. Write(frame)和output. Release()中的空格,改为output.write(frame)和output.release() - 初始化变量
i(比如循环前加i = ""),或者直接删除打印时间的代码(频繁打印会拖慢循环速度)
2. 替换高速截图工具(核心优化)
pyautogui.screenshot()速度很慢,换成专门做高速屏幕捕获的mss库,能大幅提升帧率:
首先安装库:
pip install mss
替换截图部分的代码:
# 替换原pyautogui导入,新增mss导入 from mss import mss # 初始化mss对象 sct = mss() # 定义全屏捕获区域 monitor = {"top": 0, "left": 0, "width": width, "height": height} while True: # 高速截图 sct_img = sct.grab(monitor) # 转换为numpy数组 frame = np.array(sct_img) # 将mss返回的BGRA格式转为cv2支持的BGR格式 frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR) output.write(frame)
3. 控制循环帧率,匹配输出设置
即使截图速度提升,也要保证每秒稳定输出60帧,避免画面快进:
target_fps = 60 # 计算每帧的间隔时间 frame_interval = 1 / target_fps last_frame_time = time.time() while True: current_time = time.time() # 计算需要等待的时间,保证每帧间隔一致 sleep_duration = frame_interval - (current_time - last_frame_time) if sleep_duration > 0: time.sleep(sleep_duration) last_frame_time = current_time # 这里放入截图和写入视频的代码
4. 优化视频写入效率
- 删掉循环内的
print操作,若需观察帧率,可改为每秒打印一次 - 替换为更高效的视频编码,比如将
XVID改为mp4v,代码如下:
该编码在写入速度和文件体积上都更有优势f = cv2.VideoWriter_fourcc(*"mp4v")
5. 降低分辨率(硬件不足时可选)
若硬件性能有限,无法达到60FPS,可适当降低录制分辨率,比如将宽高减半:
width = GetSystemMetrics(0) // 2 height = GetSystemMetrics(1) // 2 dim = (width, height)
这样截图和处理的工作量减少一半,帧率会明显提升
内容的提问来源于stack exchange,提问作者brad therookie
相关产品推荐
相关产品推荐

