首先简单介绍一下 代码功能
1. 该工具录制 桌面应用的,需打开待录制应用(在桌面运行),如游戏,办公软件
2. 打开该工具,输入待录制的应用名称,成功识别后,会自动填充 待录制的区域,也就是 待录制的应用在桌面的位置及大小,默认录制整个应用在桌面的大小
3. 有定时录制功能
4. 可选择录制时长,该时长在定时功能下 生效
5. 可选择保存图片
6.废话不多说,上代码吧
import sys
import os
import cv2
import numpy as np
import pyautogui
import pywintypes
import win32gui
import time
import random
from datetime import datetime
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QLabel, QComboBox, QSlider, QHBoxLayout, QCheckBox, QLineEdit
from PyQt5.QtCore import QThread, pyqtSignal,QTimer, QSettings, Qt
class GameWindowsFind():
def __init__(self):
super().__init__()
self.hwnd_title = dict()
self.hwnd = None
def find_window(self,part_title):#查找窗口
for hwnd, title in self.hwnd_title.items():
if part_title in title:
return hwnd
def get_all_hwnd(self,hwnd, mouse):#得到活动所有句柄
if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
self.hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)})
def find(self,name='QQ飞车2.0',sub_name='在线送A车',sub_name2='点券',sub_name3='倍开启'):#
win32gui.EnumWindows(self.get_all_hwnd, 0)
handle = self.find_window(name)
if handle:
self.hwnd = handle
if sub_name == None or sub_name2 == None or sub_name3 == None:
return True
speed_window_name = win32gui.GetWindowText(handle)
if len(speed_window_name) > 0:
for sub_name in speed_window_name:
return True
for sub_name2 in speed_window_name:
return True
for sub_name3 in speed_window_name:
return True
else:
return False
def clean_find_res(self):
self.hwnd_title.clear()
def get_windows_handle(self):
return self.hwnd
def GetWindowRect(self):#目标进程(窗口大小坐标)#left, top, right, bottom
return win32gui.GetWindowRect(self.hwnd)
# 录制线程
class ScreenRecorder(QThread):
recording_done = pyqtSignal()
def __init__(self, region, output_file, fps=20, format_code="XVID", save_images=False, images_per_sec=1, duration=None):
super().__init__()
self.region = region
self.output_file = output_file
self.fps = fps
self.format_code = format_code
self.save_images = save_images
self.images_per_sec = images_per_sec
self.duration = duration
self.recording = False
def run(self):
fourcc = cv2.VideoWriter_fourcc(*self.format_code)
out = cv2.VideoWriter(self.output_file, fourcc, self.fps, (self.region[2], self.region[3]))
self.recording = True
start_time = time.time()
last_image_save_time = 0
while self.recording:
img = pyautogui.screenshot(region=self.region)
frame = np.array(img)
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
out.write(frame)
if self.save_images:
current_time = time.time()
if current_time - last_image_save_time >= 1 / self.images_per_sec:
last_image_save_time = current_time
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
random_suffix = random.randint(1000, 9999)
img_filename = f"screenshot_{timestamp}_{random_suffix}.png"
img.save(img_filename)
print(f"图片已保存: {img_filename}")
if self.duration and (time.time() - start_time >= self.duration):
#print('timeout ')
break
time.sleep(1 / self.fps)
out.release()
self.recording_done.emit()
def stop(self):
self.recording = False
# 主窗口
class RecorderApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.load_settings()
self.FGW = GameWindowsFind()
def initUI(self):
self.setWindowTitle("屏幕录制")
self.setGeometry(100, 100, 400, 300)
layout = QVBoxLayout()
self.status_label = QLabel("状态: 未录制")
layout.addWidget(self.status_label)
hlayout = QHBoxLayout()
# 视频格式选择
self.format_label = QLabel("选择视频格式:")
hlayout.addWidget(self.format_label)
self.format_dropdown = QComboBox()
self.format_dropdown.addItems(["XVID", "MJPG", "MP4V", "DIVX"])
hlayout.addWidget(self.format_dropdown)
layout.addLayout(hlayout)
h2layout = QHBoxLayout()
# 帧率选择
self.fps_label = QLabel("选择帧率 (1-20):")
h2layout.addWidget(self.fps_label)
self.fps_slider = QSlider(Qt.Horizontal)
self.fps_slider.setRange(1, 20)
self.fps_slider.setValue(20)
h2layout.addWidget(self.fps_slider)
layout.addLayout(h2layout)
# 保存图片选项
self.save_image_checkbox = QCheckBox("保存截图")
layout.addWidget(self.save_image_checkbox)
h3layout = QHBoxLayout()
# 每秒图片保存数量选择
self.image_rate_label = QLabel("每秒保存图片数量 (1-5):")
h3layout.addWidget(self.image_rate_label)
self.image_rate_slider = QSlider(Qt.Horizontal)
self.image_rate_slider.setRange(1, 5)
self.image_rate_slider.setValue(1)
h3layout.addWidget(self.image_rate_slider)
layout.addLayout(h3layout)
# 定时录制选项
self.timed_recording_checkbox = QCheckBox("定时录制")
layout.addWidget(self.timed_recording_checkbox)
#add
h4layout = QHBoxLayout()
# 定时录制时间设置
self.scheduled_time_label = QLabel("设置定时时间:")
h4layout.addWidget(self.scheduled_time_label)
self.hour_input = QLineEdit()
self.hour_input.setPlaceholderText("小时")
h4layout.addWidget(self.hour_input)
self.minute_input = QLineEdit()
self.minute_input.setPlaceholderText("分钟")
h4layout.addWidget(self.minute_input)
self.second_input = QLineEdit()
self.second_input.setPlaceholderText("秒")
h4layout.addWidget(self.second_input)
layout.addLayout(h4layout)
#end
h5layout = QHBoxLayout()
# 定时录制时间选择
self.timed_duration_label = QLabel("定时录制时长:")
h5layout.addWidget(self.timed_duration_label)
self.timed_duration_dropdown = QComboBox()
self.timed_duration_dropdown.addItems(["15秒", "30秒", "1分钟", "2分钟", "3分钟"])
h5layout.addWidget(self.timed_duration_dropdown)
layout.addLayout(h5layout)
h6layout = QHBoxLayout()
# 录制区域输入
self.region_label = QLabel("设置录制区域 (x, y, width, height):")
h6layout.addWidget(self.region_label)
self.x_input = QLineEdit()
self.x_input.setPlaceholderText("左上角X坐标")
h6layout.addWidget(self.x_input)
self.y_input = QLineEdit()
self.y_input.setPlaceholderText("左上角Y坐标")
h6layout.addWidget(self.y_input)
self.width_input = QLineEdit()
self.width_input.setPlaceholderText("宽度")
h6layout.addWidget(self.width_input)
self.height_input = QLineEdit()
self.height_input.setPlaceholderText("高度")
h6layout.addWidget(self.height_input)
layout.addLayout(h6layout)
# 开始和停止按钮
button_layout = QHBoxLayout()
self.start_button = QPushButton("开始录制")
self.start_button.clicked.connect(self.start_recording)
button_layout.addWidget(self.start_button)
self.stop_button = QPushButton("停止录制")
self.stop_button.clicked.connect(self.stop_recording)
button_layout.addWidget(self.stop_button)
self.find_game_button = QPushButton("查找游戏")
self.find_game_button.clicked.connect(self.find_gaming)
button_layout.addWidget(self.find_game_button)
self.claer_data_button = QPushButton("数据清空")
self.claer_data_button.clicked.connect(self.clear_data)
button_layout.addWidget(self.claer_data_button)
layout.addLayout(button_layout)
self.setLayout(layout)
# 创建录制线程
self.recorder = None
def find_gaming(self):
if self.FGW.find():
left, top, right, bottom = self.FGW.GetWindowRect()
self.x_input.setText(str(left))
self.y_input.setText(str(top))
self.width_input.setText(str(right-left))
self.height_input.setText(str(bottom-top))
def start_recording(self):
# format_code = self.format_dropdown.currentText()
# fps = self.fps_slider.value()
# save_images = self.save_image_checkbox.isChecked()
# images_per_sec = self.image_rate_slider.value()
# duration = None
if self.timed_recording_checkbox.isChecked():
duration = self.get_timed_duration()
self.start_button.setEnabled(False) # 禁用开始按钮,直到录制结束
# 获取用户设置的录制区域
try:
x = int(self.x_input.text())
y = int(self.y_input.text())
width = int(self.width_input.text())
height = int(self.height_input.text())
region = (x, y, width, height)
Timing_time_hour = int(self.hour_input.text())
Timing_time_minute = int(self.minute_input.text())
Timing_time_second = int(self.second_input.text())
Timing_time = (Timing_time_hour,Timing_time_minute,Timing_time_second)
except ValueError:
self.status_label.setText("状态: 输入区域无效")
return
# 获取用户输入的定时开始时间
if self.timed_recording_checkbox.isChecked():
try:
hour = int(self.hour_input.text())
minute = int(self.minute_input.text())
second = int(self.second_input.text())
start_time = datetime.now().replace(hour=hour, minute=minute, second=second)
if start_time <= datetime.now():
self.status_label.setText("状态: 定时时间无效,请输入未来的时间")
return
time_to_wait = (start_time - datetime.now()).total_seconds()
QTimer.singleShot(int(time_to_wait * 1000), self.begin_recording)
self.status_label.setText("状态: 定时录制将于 " + start_time.strftime("%H:%M:%S") + " 开始")
except ValueError:
self.status_label.setText("状态: 输入的定时时间无效")
else:
self.begin_recording()
def begin_recording(self):
format_code = self.format_dropdown.currentText()
fps = self.fps_slider.value()
save_images = self.save_image_checkbox.isChecked()
images_per_sec = self.image_rate_slider.value()
duration = None
if self.timed_recording_checkbox.isChecked():
duration = self.get_timed_duration()
self.start_button.setEnabled(False) # 禁用开始按钮,直到录制结束
# 获取用户设置的录制区域
try:
x = int(self.x_input.text())
y = int(self.y_input.text())
width = int(self.width_input.text())
height = int(self.height_input.text())
region = (x, y, width, height)
Timing_time_hour = int(self.hour_input.text())
Timing_time_minute = int(self.minute_input.text())
Timing_time_second = int(self.second_input.text())
Timing_time = (Timing_time_hour,Timing_time_minute,Timing_time_second)
except ValueError:
self.status_label.setText("状态: 输入区域无效")
return
# 生成输出文件名
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
random_suffix = random.randint(1000, 9999)
output_file = f"recorded_video_{timestamp}_{random_suffix}.avi"
# 保存用户选择
self.save_settings(format_code, fps, save_images, images_per_sec, self.timed_recording_checkbox.isChecked(), self.timed_duration_dropdown.currentIndex(), region,Timing_time)
self.status_label.setText("状态: 正在录制...")
self.recorder = ScreenRecorder(
region,
output_file,
fps,
format_code,
save_images,
images_per_sec,
duration
)
self.recorder.recording_done.connect(self.recording_finished)
self.recorder.start()
def stop_recording(self):
if self.recorder:
self.recorder.stop()
self.status_label.setText("状态: 停止录制中...")
def recording_finished(self):
self.status_label.setText("状态: 录制已停止")
self.start_button.setEnabled(True) # 启用开始按钮
print("录制结束,视频已保存为:", self.recorder.output_file)
def get_timed_duration(self):
duration_mapping = {
"15秒": 15,
"30秒": 30,
"1分钟": 60,
"2分钟": 120,
"3分钟": 180
}
return duration_mapping[self.timed_duration_dropdown.currentText()]
def save_settings(self, format_code, fps, save_images, images_per_sec, timed_recording, duration_index, region,Timing_time):
settings = QSettings("MyApp", "ScreenRecorder")
settings.setValue("video_format", format_code)
settings.setValue("fps", fps)
settings.setValue("save_images", save_images)
settings.setValue("images_per_sec", images_per_sec)
settings.setValue("timed_recording", timed_recording)
settings.setValue("duration_index", duration_index)
settings.setValue("region", f"{region[0]},{region[1]},{region[2]},{region[3]}")
settings.setValue("Timing_time", f"{Timing_time[0]},{Timing_time[1]},{Timing_time[2]}")
def load_settings(self):
settings = QSettings("MyApp", "ScreenRecorder")
format_code = settings.value("video_format", "XVID")
fps = int(settings.value("fps", 20))
save_images = settings.value("save_images", False, type=bool)
images_per_sec = int(settings.value("images_per_sec", 1))
timed_recording = settings.value("timed_recording", False, type=bool)
duration_index = int(settings.value("duration_index", 0))
# 加载录制区域设置
region = settings.value("region", "100,100,800,600").split(',')
self.x_input.setText(region[0])
self.y_input.setText(region[1])
self.width_input.setText(region[2])
self.height_input.setText(region[3])
self.format_dropdown.setCurrentText(format_code)
self.fps_slider.setValue(fps)
self.save_image_checkbox.setChecked(save_images)
self.image_rate_slider.setValue(images_per_sec)
self.timed_recording_checkbox.setChecked(timed_recording)
self.timed_duration_dropdown.setCurrentIndex(duration_index)
Timing_time = settings.value("Timing_time", "00,00,00").split(',')
self.hour_input.setText(Timing_time[0])
self.minute_input.setText(Timing_time[1])
self.second_input.setText(Timing_time[2])
def delete_files_by_extension(self,folder_path, extension):
for filename in os.listdir(folder_path):
if filename.endswith(extension):
file_path = os.path.join(folder_path, filename)
os.remove(file_path)
def clear_data(self):
self.delete_files_by_extension('.','png')
self.delete_files_by_extension('.','avi')
self.delete_files_by_extension('.','mp4')
self.delete_files_by_extension('.','jpeg')
self.delete_files_by_extension('.','jpg')
self.status_label.setText("数据已清空...")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = RecorderApp()
window.show()
sys.exit(app.exec_())
可结合你自己的需求,改动代码,转载需注明出处!!
2万+

被折叠的 条评论
为什么被折叠?



