用Python进行屏幕录制的实现

 更新时间:2024年04月18日 10:14:04   作者:鹅毛在路上了  
关于屏幕录制这个功能需求,之前用过基于ffmpeg的Capture录屏软件,但是fps拉高以后会变得很卡,声音也同样出现卡顿,所以本文给大家介绍了用Python进行屏幕录制的实现,感兴趣的朋友可以参考下

引言

关于屏幕录制这个功能需求,之前用过基于ffmpeg的Capture录屏软件,但是fps拉高以后会变得很卡,声音也同样出现卡顿。也自己尝试过在python中调用ffmpeg的库函数,效果也不尽人意。网络上下载了几款录屏软件,不是要收费就是下载到捆绑软件或广告很是心累,因此想借此机会重新研究一下屏幕录制软件的工作原理,同时当作一个小项目练手。

gpt3.5给出的代码

当我还在犹豫是否要精心翻阅一下ffmpeg的说明书时,没想到gpt已果断给出了参考答案,可以使用Python的PyAutoGUI库来实现录屏功能。以下是一个简单的示例代码:

import pyautogui
import cv2
import numpy as np

# 获取屏幕分辨率
screen_size = (1920, 1080)

# 设置视频编码器
fourcc = cv2.VideoWriter_fourcc(*"XVID")

# 创建视频写入对象
out = cv2.VideoWriter("output.avi", fourcc, 20.0, screen_size)

# 开始录屏
while True:
    # 获取屏幕截图
    img = pyautogui.screenshot()

    # 将截图转换为OpenCV格式
    frame = np.array(img)
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # 写入视频
    out.write(frame)

    # 按下q键退出录屏
    if cv2.waitKey(1) == ord("q"):
        break

# 释放资源
out.release()
cv2.destroyAllWindows()

从给出的代码看来,屏幕录制的工作原理就是以一定的帧率不断地截图,然后将截取的图片以相同的帧率合成一个视频

放在安装了pyautogui的python环境里运行后,果然不出意外的话就要出意外了。gpt3.5给出的代码卡在运行中的界面纹丝不动,按’q’回车也并未退出循环,再问gpt也死活给不出修改方案。

查阅资料后发现要先imshow()之后,在ui窗口区域内按键才能有效终止循环:

import numpy as np
import pyautogui
import cv2

# 设置录制参数
SCREEN_SIZE = (1920, 1080)
FILENAME = 'recorded_video.avi'
FPS = 30.0

# 开始录制
fourcc = cv2.VideoWriter_fourcc(*"XVID")
out = cv2.VideoWriter(FILENAME, fourcc, FPS, SCREEN_SIZE)

while True:
    # 获取屏幕截图
    img = pyautogui.screenshot()
    # 转换为OpenCV格式
    frame = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    # 写入视频文件
    out.write(frame)
    cv2.imshow('Frame', frame)
    cv2.resizeWindow('Frame', 1920, 1080)

    # 检测按键
    if cv2.waitKey(1) == ord('q'):
        break

# 停止录制
out.release()
cv2.destroyAllWindows()

程序是能运行了,但是效果依旧不好,窗口一直有递归的效果,而且导出的视频其实是无法播放的。

在这里插入图片描述

更换截图函数——ImageGrab.grab

pyautogui虽然能实现截图,并在imshow里展示出来,但是导出的视频却无法播放,考虑肯能涉及到具体视频编解码参数问题,有懂的朋友请在评论区分享。这里采用更换PIL库中的截图函数ImageGrab.grab,可以实现截图并导出视频了,接下来最大的问题就是解决递归现象。

import numpy as np
import pyautogui
import cv2

# 设置录制参数
SCREEN_SIZE = (1920, 1080)
FILENAME = 'recorded_video.avi'
FPS = 30.0

# 开始录制
fourcc = cv2.VideoWriter_fourcc(*"XVID")
out = cv2.VideoWriter(FILENAME, fourcc, FPS, SCREEN_SIZE)

while True:
    # 获取屏幕截图
    img = pyautogui.screenshot()
    # 转换为OpenCV格式
    frame = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    # 写入视频文件
    out.write(frame)
    cv2.imshow('Frame', frame)
    cv2.resizeWindow('Frame', 1920, 1080)

    # 检测按键
    if cv2.waitKey(1) == ord('q'):
        break

# 停止录制
out.release()
cv2.destroyAllWindows()

在这里插入图片描述

禁用imshow解决递归现象

视频处理时的递归现象其实非常常见,除了物理中的镜面效应(观察两个平行放置的镜子会出现递归的现象),

将摄像头对准显示器,显示器上的画面也会观察到递归的现象:

在这里插入图片描述

经尝试,将imshow()禁用后,改为帧计数的方式自定义终止循环就不会出现递归的问题了:

import numpy as np
from PIL import ImageGrab
import cv2

# 设置录制参数
SCREEN_SIZE = (1920, 1080)
FILENAME = 'recorded_video.avi'
FPS = 30.0

# 开始录制
fourcc = cv2.VideoWriter_fourcc(*"XVID")
out = cv2.VideoWriter(FILENAME, fourcc, FPS, SCREEN_SIZE)

cnt = 0
while True:
    # 获取屏幕截图
    # img = pyautogui.screenshot()
    img = ImageGrab.grab(bbox=(0, 0, 1920, 1080))
    print('recordin..')
    # 转换为OpenCV格式
    frame = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    # 写入视频文件
    out.write(frame)
    # cv2.imshow('Frame', frame)
    # cv2.resizeWindow('Frame', 1920, 1080)

    # # 检测按键
    # if cv2.waitKey(1) == ord('q'):
    #     break

    cnt = cnt + 1

    if cnt == 100:  #满100帧后终止循环
        break

# 停止录制
out.release()
cv2.destroyAllWindows()

在这里插入图片描述

通过修改img = ImageGrab.grab(bbox=(0, 0, 2560, 1600))中的参数可以自定义录屏区域,x,y,w,h分别代表左上角坐标(起始坐标)和图片宽度、高度。比如我的屏幕分辨率是2560*1600,那么设置为0, 0, 2560, 1600就是录制全屏:

在这里插入图片描述

这样,我们就可以基本实现用Python进行屏幕录制的功能了。动态图预览看上去分辨率不高是因为用的格式工厂把录制的视频转了gif,压缩前录制的视频其实蛮清楚的。

通过修改fps的值,我们还可以自行录制一些高刷新率的电影、游戏画面,fps越高,画面越流畅哦。

摄像头录制代码

类似的,也可以用python实现相机录像的功能:

import cv2
import cv2 as cv

# 打开摄像头
cap = cv2.VideoCapture(0)

fourcc = cv.VideoWriter_fourcc(*'XVID')
file_name = 'output'
output = cv.VideoWriter((file_name + '.avi'), fourcc, 24.0, (640, 480))  #设置文件名,fps,分辨率

while cap.isOpened():

    res, frame = cap.read()
    if not res:
        print("Frame Cannot Be Received")
        break

    # Flipping the frame horizontally to get correct orientation
    frame = cv2.flip(frame, 90)

    # Displaying the current frame
    output.write(frame)
    cv2.imshow('Frame', frame)

    # If no input is received for 1ms, or if the key 'x' is pressed, interpreter goes outside of the loop
    if cv2.waitKey(1) == ord('x'):
        break

# Releasing everything after coming out of loop
cap.release()
output.release()
cv2.destroyAllWindows()

后期需求

现在屏幕录制的问题基本解决了,要想做一个实用的屏幕录制软件,还需要加上音频录制,并设计一个便捷的UI界面。

小结

到此这篇关于用Python进行屏幕录制的实现的文章就介绍到这了,更多相关Python屏幕录制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python3显式变量类型typing的实现

    python3显式变量类型typing的实现

    这篇文章主要介绍了python3显式变量类型typing的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Python实现上课点名器系统

    Python实现上课点名器系统

    今天给大家分享一个读者粉丝投稿的,关于上课点名的实战案例,对Python上课点名器实现过程感兴趣的朋友,一起来看看是如何实现的吧
    2021-10-10
  • pycharm 取消默认的右击运行unittest的方法

    pycharm 取消默认的右击运行unittest的方法

    今天小编就为大家分享一篇pycharm 取消默认的右击运行unittest的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-11-11
  • Python数据类型和常用操作

    Python数据类型和常用操作

    这篇文章主要介绍了Python数据类型和常用操作,数值数据类型用于存储数值,数据类型不可改变,改变会分配一个新的对象,下文更多相关内容介绍需要的小伙伴可以参考一下
    2022-04-04
  • python实现计数排序与桶排序实例代码

    python实现计数排序与桶排序实例代码

    这篇文章主要介绍了python计数排序与桶排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • python logging类库使用例子

    python logging类库使用例子

    这篇文章主要介绍了python logging类库使用例子,本文讲解了简单使用、logging的level、Handlers、FileHandler + StreamHandler等内容,需要的朋友可以参考下
    2014-11-11
  • Python机器学习NLP自然语言处理基本操作关键词

    Python机器学习NLP自然语言处理基本操作关键词

    本文是Python机器学习NLP自然语言处理系列文章,带大家开启一段学习自然语言处理 (NLP) 的旅程. 本文主要学习NLP自然语言处理关键词的操作
    2021-09-09
  • python输出后面多一个None问题

    python输出后面多一个None问题

    在Python中,函数如果没有显式指定返回值,会默认返回`None`,例如,计算一个数的平方根并输出,如果没有处理`None`,会输出结果后跟`None`
    2024-11-11
  • python如何实现DES加密

    python如何实现DES加密

    这篇文章主要介绍了python如何实现DES加密,帮助大家更好的理解和学习密码学,感兴趣的朋友可以了解下
    2020-09-09
  • Python实现CET查分的方法

    Python实现CET查分的方法

    这篇文章主要介绍了Python实现CET查分的方法,实例分析了Python操作链接查询的技巧,需要的朋友可以参考下
    2015-03-03

最新评论