窗口录屏工具

窗口录制工具的使用说明与详细介绍

概述

此脚本是一个基于 TkinterOpenCV 的简单窗口录制工具,允许用户录制当前屏幕的活动内容并保存为视频文件。用户可以通过图形界面(GUI)进行录制控制,并选择所需的帧率。

个人博客

个人博客直达地址
网站不断完善中里面拥有大量的脚本,并且源码完全开放 欢迎纯白嫖。关注公众私信可免费写脚本

功能说明

1. 窗口录制类 WindowRecorder

此类封装了窗口录制工具的所有功能,包括界面创建、录制控制、帧捕捉、视频保存等。

2. 初始化方法 __init__

  • 应用窗口设置:设置应用的标题、窗口大小,并禁止调整窗口大小。
  • 录制状态标志:初始化录制状态标志,用于控制录制的开始和停止。
  • 帧率设置:通过下拉框选择用户设置的帧率。

3. 创建界面方法 create_context

  • 按钮创建:创建“开始/停止录制”和“退出”两个按钮,用户可以通过这些按钮控制录制操作和关闭应用。
  • 下拉框创建:创建帧率选择下拉框,用户可以选择不同的帧率(fps)。
  • 定时器标签:显示录制时间的定时器标签,实时更新录制时长。
  • 根菜单与文件菜单:创建菜单栏,包括关于应用和退出功能。

4. 启动应用方法 start

调用 Tkintermainloop 方法启动应用的主循环,等待用户操作。

5. 开始录制方法 start_recording

  • 初始化录制:设置录制状态为 True,创建用于存储视频帧的列表,并最小化应用窗口。
  • 更新按钮状态:在开始录制后,将“开始”按钮更改为“停止”,并禁用帧率选择下拉框。
  • 调用录制帧方法:开始捕捉屏幕内容并保存为视频帧。

6. 停止录制方法 stop

  • 停止录制:将录制状态设置为 False,弹出文件保存对话框,允许用户选择保存视频文件的位置和名称。
  • 保存视频文件:使用 OpenCVVideoWriter 类将捕捉到的帧保存为视频文件。
  • 更新按钮状态:停止录制后,将“停止”按钮更改回“开始”,并重新启用帧率选择下拉框。

7. 关闭应用方法 destroy

调用 Tkinterdestroy 方法关闭应用窗口。

8. 录制帧方法 record_frames

  • 屏幕捕捉:使用 PILImageGrab 模块捕捉屏幕内容,并将其转换为适合 OpenCV 处理的格式。
  • 帧列表保存:将捕捉到的每一帧保存到帧列表中。
  • 定时器更新:更新定时器标签,显示当前录制时间。
  • 循环录制:如果录制状态为 True,则继续捕捉下一帧。

9. 帧率选择控制器 on_select_listener

当用户在下拉框中选择不同的帧率时,更新录制的帧率设置。

10. 关于对话框 about

弹出“关于”对话框,显示应用的基本信息。

使用说明

  1. 启动应用

    • 双击或通过命令行运行脚本,窗口将会弹出,用户可以在界面中进行操作。
  2. 选择帧率

    • 在界面右侧的下拉框中选择所需的帧率(默认为 30 fps)。
  3. 开始录制

    • 点击“开始录制”按钮,应用将最小化并开始录制当前屏幕内容。
  4. 停止录制并保存

    • 点击“停止录制”按钮,录制将停止,并弹出文件保存对话框,用户可以选择保存的视频文件路径和名称。
  5. 退出应用

    • 通过点击“退出”按钮或菜单栏中的“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()  # 启动应用

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脚本小能手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值