窗口录制工具的使用说明与详细介绍
概述
此脚本是一个基于 Tkinter
和 OpenCV
的简单窗口录制工具,允许用户录制当前屏幕的活动内容并保存为视频文件。用户可以通过图形界面(GUI)进行录制控制,并选择所需的帧率。
个人博客
个人博客直达地址
网站不断完善中里面拥有大量的脚本,并且源码完全开放 欢迎纯白嫖。关注公众私信可免费写脚本
功能说明
1. 窗口录制类 WindowRecorder
此类封装了窗口录制工具的所有功能,包括界面创建、录制控制、帧捕捉、视频保存等。
2. 初始化方法 __init__
- 应用窗口设置:设置应用的标题、窗口大小,并禁止调整窗口大小。
- 录制状态标志:初始化录制状态标志,用于控制录制的开始和停止。
- 帧率设置:通过下拉框选择用户设置的帧率。
3. 创建界面方法 create_context
- 按钮创建:创建“开始/停止录制”和“退出”两个按钮,用户可以通过这些按钮控制录制操作和关闭应用。
- 下拉框创建:创建帧率选择下拉框,用户可以选择不同的帧率(fps)。
- 定时器标签:显示录制时间的定时器标签,实时更新录制时长。
- 根菜单与文件菜单:创建菜单栏,包括关于应用和退出功能。
4. 启动应用方法 start
调用 Tkinter
的 mainloop
方法启动应用的主循环,等待用户操作。
5. 开始录制方法 start_recording
- 初始化录制:设置录制状态为
True
,创建用于存储视频帧的列表,并最小化应用窗口。 - 更新按钮状态:在开始录制后,将“开始”按钮更改为“停止”,并禁用帧率选择下拉框。
- 调用录制帧方法:开始捕捉屏幕内容并保存为视频帧。
6. 停止录制方法 stop
- 停止录制:将录制状态设置为
False
,弹出文件保存对话框,允许用户选择保存视频文件的位置和名称。 - 保存视频文件:使用
OpenCV
的VideoWriter
类将捕捉到的帧保存为视频文件。 - 更新按钮状态:停止录制后,将“停止”按钮更改回“开始”,并重新启用帧率选择下拉框。
7. 关闭应用方法 destroy
调用 Tkinter
的 destroy
方法关闭应用窗口。
8. 录制帧方法 record_frames
- 屏幕捕捉:使用
PIL
的ImageGrab
模块捕捉屏幕内容,并将其转换为适合OpenCV
处理的格式。 - 帧列表保存:将捕捉到的每一帧保存到帧列表中。
- 定时器更新:更新定时器标签,显示当前录制时间。
- 循环录制:如果录制状态为
True
,则继续捕捉下一帧。
9. 帧率选择控制器 on_select_listener
当用户在下拉框中选择不同的帧率时,更新录制的帧率设置。
10. 关于对话框 about
弹出“关于”对话框,显示应用的基本信息。
使用说明
-
启动应用:
- 双击或通过命令行运行脚本,窗口将会弹出,用户可以在界面中进行操作。
-
选择帧率:
- 在界面右侧的下拉框中选择所需的帧率(默认为 30 fps)。
-
开始录制:
- 点击“开始录制”按钮,应用将最小化并开始录制当前屏幕内容。
-
停止录制并保存:
- 点击“停止录制”按钮,录制将停止,并弹出文件保存对话框,用户可以选择保存的视频文件路径和名称。
-
退出应用:
- 通过点击“退出”按钮或菜单栏中的“Exit”选项关闭应用。
注意事项
- DPI 感知:脚本设置了 DPI 感知,这对高分辨率屏幕很重要,以确保捕捉的屏幕内容清晰。
- 录制过程:录制过程中,应用窗口将自动最小化,请确保在录制过程中不操作其他窗口,否则可能影响录制效果。
- 保存视频:保存视频时,请选择适当的文件名和路径,以避免覆盖已有文件。
- 性能要求:在录制高分辨率屏幕时,系统资源占用可能较高,请确保有足够的内存和 CPU 资源可用。
- 支持格式:目前仅支持保存为
.mp4
格式,如果需要其他格式,可根据需求修改代码。
from tkinter.ttk import Combobox
from tkinter import Tk, Button, filedialog, messagebox, Label, Menu
from PIL import ImageGrab
from cv2 import VideoWriter, VideoWriter_fourcc, cvtColor, resize, COLOR_BGR2RGB
from ctypes import windll
import time
import numpy as np
# 窗口录制类
class WindowRecorder:
def __init__(self):
self.__app = Tk()
self.__app.title(app_name) # 设置应用标题
self.__app.geometry(app_window_size) # 设置窗口大小
self.__app.resizable(0, 0) # 禁止窗口调整大小
self.__is_recording = False # 录制状态标志
self.__frame_per_sec = fps_combo_box[default_cmbox_value] # 帧率设置
# 创建界面
def create_context(self):
self.__btn_start_stop = Button(self.__app, text=btn_start_txt, width=btn_start_width, command=self.start_recording, bg='green', fg='white', bd=0)
self.__btn_start_stop.pack(pady=10)
self.__btn_exit = Button(self.__app, text=btn_exit_txt, width=btn_close_width, command=self.destroy, fg='white', bg='blue', bd=0)
self.__btn_exit.pack()
''' 下拉框 '''
self.__cmb_box = Combobox(self.__app, values=fps_combo_box, width=5)
self.__cmb_box.pack(side='right', padx=5, pady=5)
cmb_label = Label(self.__app, text='fps')
cmb_label.pack(side='right')
self.__cmb_box.current(default_cmbox_value) # 设置下拉框默认值
self.__cmb_box.bind('<<ComboboxSelected>>', self.on_select_listener) # 绑定选择事件
''' 定时器标签 '''
self.__timer = Label(text='00:00:00')
self.__timer.pack(side='left', padx=5)
''' 根菜单 '''
self.__root_menu = Menu(master=self.__app)
self.__app.config(menu=self.__root_menu)
''' 文件菜单 '''
self.__file_menu = Menu(self.__root_menu, tearoff=0)
self.__file_menu.add_command(label='About', command=self.about)
self.__file_menu.add_command(label='Contact us', command=self.contact_us)
self.__file_menu.add_separator()
self.__file_menu.add_command(label='Exit', command=self.destroy)
self.__root_menu.add_cascade(label='Menu', menu=self.__file_menu)
# 启动应用
def start(self):
self.__app.mainloop()
# 开始录制操作
def start_recording(self):
self.__is_recording = True
self.__temp_video_frames = list() # 存储录制的视频帧
self.__btn_start_stop.configure(text=btn_close_txt, command=self.stop, bg='red') # 更新按钮状态
self.__cmb_box['state'] = 'disabled' # 禁用下拉框
self.count = 0
self.min = 0
self.sec = 0
self.__app.iconify() # 最小化应用窗口
self.record_frames() # 开始录制帧
# 停止录制操作
def stop(self):
self.__is_recording = False
file = filedialog.asksaveasfile(defaultextension="*.*", filetypes=[('mp4', '.mp4'),]) # 弹出保存对话框
if file:
if file.name:
print(file.name)
shape = self.__temp_video_frames[0].shape
print(shape)
fourcc = VideoWriter_fourcc(*codec) # 编解码器设置
video_writer = VideoWriter(file.name, fourcc, self.__frame_per_sec, (shape[1], shape[0]), True) # 创建视频写入对象
if self.__temp_video_frames:
for frame in self.__temp_video_frames:
video_writer.write(frame) # 写入视频帧
del self.__temp_video_frames
video_writer.release() # 释放视频写入对象
self.__btn_start_stop.configure(text=btn_start_txt, command=self.start_recording, bg='green') # 更新按钮状态
self.__cmb_box['state'] = 'normal' # 启用下拉框
# 关闭应用
def destroy(self):
self.__app.destroy()
# 录制帧
def record_frames(self):
screen = np.array(ImageGrab.grab()) # 捕捉屏幕
screen = cvtColor(screen, COLOR_BGR2RGB) # 转换颜色空间
screen = resize(screen, video_res) # 调整帧大小
self.__temp_video_frames.append(screen) # 添加帧到列表
self.count += 1
dur = (self.count / self.__frame_per_sec)
self.min = int(dur / 60)
self.sec = dur % 60
self.__timer['text'] = time.strftime('%H:%M:%S', time.gmtime(self.min * 60 + self.sec)) # 更新定时器标签
if self.__is_recording:
self.__app.after(call_record_after, self.record_frames) # 定时调用录制函数
# 选择控制器
def on_select_listener(self, event=None):
if event:
self.__frame_per_sec = int(event.widget.get()) # 更新帧率
# 应用详情
def about(self):
messagebox.showinfo('About', about_msg) # 弹出关于对话框
if __name__ == '__main__':
# 执行
user_32 = windll.user32
user_32.SetProcessDPIAware() # 设置DPI感知
app = WindowRecorder()
app.create_context() # 创建界面
app.start() # 启动应用