2025年2月24日 星期一 甲辰(龙)年 腊月廿四 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

python --录屏工具开发

时间:08-15来源:作者:点击数:34

该文章描述了一个使用Python实现的GUI录屏工具,主要利用Tkinter库构建界面,支持倒计时功能和帧率设置。用户可以通过菜单栏进行开始、暂停和结束录屏操作,录屏视频保存至桌面,倒计时默认为3秒,帧率默认为12fps,可自定义调整。

  • import os
  • from datetime import datetime
  • import time
  • from threading import Thread, Event
  • from tkinter import Tk, Menu, Frame, Label, IntVar, Toplevel, Entry, Scale, HORIZONTAL, messagebox
  • import numpy as np
  • import cv2
  • import pyautogui
  • class Window(Tk):
  • def __init__(self):
  • super().__init__()
  • # 倒计时标签对象
  • self.lb = None
  • # 倒计时标签数值
  • self.lbNum = IntVar()
  • self.lbNum.set(3)
  • # 倒计时数值备份
  • self.lbNumBack = 3
  • # 帧率
  • self.fps = 12
  • # 录屏状态
  • self.screencapState = False
  • # 暂停状态
  • self.screencapWaitState = Event()
  • # 取消暂停
  • self.screencapWaitState.set()
  • # 倒计时状态
  • self.countdownState = False
  • self.gui()
  • self.menu()
  • def gui(self):
  • """
  • 主窗体
  • :return:
  • """
  • # 设置窗体背景色
  • self["background"] = "Crimson"
  • # 设置Crimson色为透明
  • self.attributes('-transparentcolor', 'Crimson')
  • # 设置窗体透明度为80%
  • self.attributes("-alpha", 0.8)
  • # 获取主屏幕宽高
  • mainWidth = self.winfo_screenwidth()
  • mainHeight = self.winfo_screenheight()
  • # 窗口宽高
  • width = int(mainWidth * 0.4)
  • height = int(mainHeight * 0.4)
  • # 设置窗口大小与显示位置
  • self.geometry(f'{width}x{height}+{int((mainWidth - width) / 2)}+{int((mainHeight - height) / 2)}')
  • # 标题
  • self.title("录屏工具")
  • # 图标
  • self.iconbitmap("logo.ico")
  • # 倒计时标签
  • f = Frame(self)
  • self.lb = Label(
  • f,
  • textvariable=self.lbNum,
  • fg='red',
  • bg='Crimson',
  • font=('微软雅黑', 66, 'bold')
  • )
  • self.lb.pack()
  • # 水平垂直居中
  • f.pack(expand=1)
  • def menu(self):
  • """
  • 菜单栏
  • :return:
  • """
  • menubar = Menu(self)
  • # 操作
  • operate = Menu(menubar, tearoff=0)
  • menubar.add_cascade(label="操作", menu=operate)
  • operate.add_command(label='开始', command=self.startScreencap)
  • operate.add_command(label='暂停', command=self.waitScreencap)
  • operate.add_separator()
  • operate.add_command(label='结束', command=self.stopScreencap)
  • # 操作
  • setting = Menu(menubar, tearoff=0)
  • menubar.add_cascade(label="设置", menu=setting)
  • setting.add_command(label='倒计时', command=self.setCountdown)
  • setting.add_separator()
  • setting.add_command(label='帧率', command=self.setFps)
  • # 关于
  • about = Menu(menubar, tearoff=0)
  • menubar.add_cascade(label='关于', menu=about)
  • about.add_command(label='说明', command=self.instruction)
  • about.add_separator()
  • about.add_command(label='作者', command=self.author)
  • self.config(menu=menubar)
  • def setCountdown(self):
  • """
  • 设置倒计时弹窗
  • :return:
  • """
  • # 设置主窗口不可操作
  • self.attributes("-disabled", 1)
  • # 弹窗
  • t = Toplevel(self)
  • # 弹窗宽高
  • width = 250
  • height = 120
  • # 获取主屏幕宽高
  • mainWidth = t.winfo_screenwidth()
  • mainHeight = t.winfo_screenheight()
  • # 设置窗口大小与显示位置
  • t.geometry(f'{width}x{height}+{int((mainWidth - width) / 2)}+{int((mainHeight - height) / 2)}')
  • # 禁止窗口缩放
  • t.resizable(0, 0)
  • # 标题
  • t.title("倒计时设置")
  • # 图标
  • t.iconbitmap("logo.ico")
  • # 输入框
  • e = Entry(t,
  • width=2,
  • fg='red',
  • font=('微软雅黑', 30, 'bold')
  • )
  • e.pack(pady=30)
  • # 设置输入框焦点
  • e.focus_set()
  • # 设置输入框值
  • e.insert(0, self.lbNumBack)
  • # 绑定弹窗关闭事件
  • t.protocol("WM_DELETE_WINDOW", lambda: self.setCountdownClose(e, t))
  • def setCountdownClose(self, e, t):
  • """
  • 设置倒计时弹窗关闭事件
  • :param e: 设置倒计时弹窗输入框对象
  • :param t: 设置倒计时弹窗对象
  • :return:
  • """
  • try:
  • # 获取输入框数据
  • num = int(e.get())
  • # 更新倒计时标签数值
  • self.lbNum.set(num)
  • # 备份倒计时设置数值
  • self.lbNumBack = num
  • # 销毁设置倒计时数值弹窗
  • t.destroy()
  • # 设置主窗口可操作
  • self.attributes("-disabled", 0)
  • # 窗口保持在前面
  • self.lift()
  • except ValueError:
  • pass
  • def setFps(self):
  • """
  • 设置帧率弹窗
  • :return:
  • """
  • # 设置主窗口不可操作
  • self.attributes("-disabled", 1)
  • # 弹窗
  • t = Toplevel(self)
  • # 弹窗宽高
  • width = 250
  • height = 120
  • # 获取主屏幕宽高
  • mainWidth = t.winfo_screenwidth()
  • mainHeight = t.winfo_screenheight()
  • # 设置窗口大小与显示位置
  • t.geometry(f'{width}x{height}+{int((mainWidth - width) / 2)}+{int((mainHeight - height) / 2)}')
  • # 禁止窗口缩放
  • t.resizable(0, 0)
  • # 标题
  • t.title("帧率设置")
  • # 图标
  • t.iconbitmap("logo.ico")
  • # 输入框
  • e = Scale(t,
  • width=60,
  • from_=6,
  • to=60,
  • orient=HORIZONTAL)
  • e.pack()
  • e.set(self.fps)
  • # 绑定弹窗关闭事件
  • t.protocol("WM_DELETE_WINDOW", lambda: self.setFpsClose(e, t))
  • def setFpsClose(self, e, t):
  • """
  • 设置倒计时弹窗关闭事件
  • :param e: 设置滚动条对象
  • :param t: 设置帧率弹窗对象
  • :return:
  • """
  • try:
  • # 获取滚动条数据
  • num = int(e.get())
  • self.fps = num
  • # 销毁设置帧率弹窗
  • t.destroy()
  • # 设置主窗口可操作
  • self.attributes("-disabled", 0)
  • # 窗口保持在前面
  • self.lift()
  • except ValueError:
  • pass
  • @staticmethod
  • def instruction():
  • messagebox.showinfo('说明',
  • '1、录屏区域为本软件窗口区域\n\n'
  • '2、菜单栏进行录屏操作\n\n'
  • '3、录屏视频位于桌面\n\n'
  • '4、倒计时设置秒值-默认:3\n\n'
  • '5、帧率常为12~24-默认:12')
  • @staticmethod
  • def author():
  • messagebox.showinfo('作者', '小丫')
  • def screencap(self):
  • """
  • 录屏
  • :return:
  • """
  • # 倒计时
  • self.countdown()
  • # 编码格式
  • fourcc = cv2.VideoWriter_fourcc(*'XVID')
  • video = cv2.VideoWriter(os.path.join(os.path.join(os.path.expanduser("~"), 'Desktop'), datetime.now().strftime('%Y-%m-%d %H-%M-%S') + '.mp4'),
  • fourcc,
  • self.fps,
  • pyautogui.screenshot(region=(
  • self.winfo_x() + 4, self.winfo_y(), self.winfo_width(),
  • self.winfo_height())).size
  • )
  • while self.screencapState:
  • # 暂停
  • self.screencapWaitState.wait()
  • # 转为opencv的BGR格式
  • imm = cv2.cvtColor(
  • np.array(pyautogui.screenshot(
  • region=(self.winfo_x() + 4, self.winfo_y(), self.winfo_width(), self.winfo_height()))),
  • cv2.COLOR_RGB2BGR
  • )
  • # 写入视频
  • video.write(imm)
  • # 保存视频
  • video.release()
  • def startScreencap(self):
  • """
  • 开始录屏
  • :return:
  • """
  • # 判断暂停状态
  • if self.screencapWaitState.isSet():
  • # 判断录屏状态
  • if not self.screencapState:
  • # 录制状态开启
  • self.screencapState = True
  • # 取消缩放
  • self.resizable(0, 0)
  • # 录屏
  • ts = Thread(target=self.screencap)
  • ts.daemon = True
  • ts.start()
  • else:
  • # 判断倒计时状态
  • if not self.countdownState:
  • # 倒计时初始化
  • self.lbNum.set(self.lbNumBack)
  • # 显示标签
  • self.lb.configure(fg="red")
  • # 继续录屏
  • tc = Thread(target=self.continueScreencap)
  • tc.daemon = True
  • tc.start()
  • def continueScreencap(self):
  • """
  • 继续录屏
  • :return:
  • """
  • # 倒计时
  • self.countdown()
  • # 取消暂停
  • self.screencapWaitState.set()
  • def waitScreencap(self):
  • """
  • 暂停录屏
  • :return:
  • """
  • # 判断录屏状态与倒计时状态
  • if self.screencapState and not self.countdownState:
  • self.screencapWaitState.clear()
  • # 暂停指示
  • self.lbNum.set(0)
  • # 显示标签
  • self.lb.configure(fg="red")
  • def stopScreencap(self):
  • """
  • 停止录屏
  • :return:
  • """
  • # 判断录屏状态与倒计时状态
  • if self.screencapState and not self.countdownState:
  • # 取消暂停
  • self.screencapWaitState.set()
  • # 录屏状态关闭
  • self.screencapState = False
  • # 倒计时初始化
  • self.lbNum.set(self.lbNumBack)
  • # 显示标签
  • self.lb.configure(fg="red")
  • # 开启缩放
  • self.resizable(1, 1)
  • def countdown(self):
  • """
  • 倒计时
  • :return:
  • """
  • # 倒计时状态开
  • self.countdownState = True
  • time.sleep(1)
  • while self.lbNum.get() > 1:
  • self.lbNum.set(self.lbNum.get() - 1)
  • time.sleep(1)
  • # 隐藏标签
  • self.lb.configure(fg="Crimson")
  • # 倒计时状态关
  • self.countdownState = False
  • if __name__ == '__main__':
  • root = Window()
  • root.mainloop()
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐