# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'Screenshot_GUI.ui' # # Created by: PyQt5 UI code generator 5.15.4 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. import shutil import sys from datetime import datetime from pathlib import Path from PIL import ImageGrab from PyQt5.QtCore import QRect, Qt, QPoint, QMetaObject, QThread from PyQt5.QtGui import QIcon, QFont, QColor, QImage, QPixmap, QPen, QPainter from PyQt5.QtWidgets import (QMainWindow, QApplication, QDesktopWidget, QWidget, QFrame, QLabel, QPushButton, QComboBox, QCheckBox, QSpinBox, QDialog, QFileDialog, QMessageBox) from py7zr import pack_7zarchive, unpack_7zarchive from Screenshot.Audio_record import AudioRecord from Screenshot.Screenshot_record import Screenshot, file_path def unpack_7zip_to_exe(filename): file_basename = Path(file_path(f'{filename}.exe')) if file_basename.exists(): return True elif file_basename.with_suffix('.7z').exists(): shutil.unpack_archive(file_basename.with_suffix('.7z'), file_basename.parent) return unpack_7zip_to_exe(file_basename.stem) else: return False class Thread_screenshot(QThread): def __init__(self): super().__init__() self.offset_x = 0 self.offset_y = 0 self.draw_mouse = 1 self.filename = '' self.screen = Screenshot() def config_modify(self, **kwargs): self.screen.width = kwargs.get('width', self.screen.width) self.screen.height = kwargs.get('height', self.screen.height) self.screen.fps = kwargs.get('fps', self.screen.fps) self.offset_x = kwargs.get('offset_x', self.offset_x) self.offset_y = kwargs.get('offset_y', self.offset_y) self.draw_mouse = kwargs.get('draw_mouse', self.draw_mouse) self.filename = kwargs.get('filename', self.filename) def compose(self): video = self.filename + '.mp4' audio = self.filename + '.mp3' self.screen.compose_audio(video, audio, video.replace('缓存', '')) QThread.sleep(1) self.stop() Path(audio).unlink() Path(video).unlink() def run(self): if not self.filename: raise Exception('请输入filename!') filename = self.filename + '.mp4' self.screen.record(filename, self.offset_x, self.offset_y, self.draw_mouse) def stop(self): self.screen.terminate() class Ui_MainWindow1(QMainWindow): """主体窗口设置""" def __init__(self): super().__init__() self.setObjectName("MainWindow") self.setWindowTitle('屏幕录制') windowico = file_path('gui_svg.svg') self.setWindowIcon(QIcon(windowico)) self.resize(512, 352) self.setFixedSize(512, 352) self._dir = '.' self.fname = '' self.offset_x, self.offset_y = 0, 0 self.screen_x, self.screen_y = ImageGrab.grab().size self.audio = AudioRecord() self.audio.get_in_out_devices() self.device_name = None self.record_audio = True if self.audio.input_dict else False self.hotkey_start = False self.screenshot = Thread_screenshot() self.setupUi() ffmpeg_exists = unpack_7zip_to_exe('ffmpeg') if not ffmpeg_exists: QMessageBox.warning(self, '请下载ffmpeg!', '请将ffmpeg.exe放在resource目录下再录制!') self.show() def setupUi(self): self.centralwidget = QWidget(self) self.centralwidget.setObjectName("centralwidget") self.label0 = QLabel(self.centralwidget) self.label0.setGeometry(QRect(0, 0, 421, 351)) self.label0.setObjectName("scrollArea") # 添加边框 self.label0.setFrameShape(QFrame.Box) self.label0.setFrameShadow(QFrame.Sunken) self.get_screen_grab((0, 0, self.screen_x, self.screen_y)) self.label0.setAlignment(Qt.AlignCenter) self.label_1 = QLabel(self.centralwidget) font = QFont() font.setBold(True) self.label_1.setGeometry(QRect(430, 0, 85, 31)) self.label_1.setTextFormat(Qt.AutoText) self.label_1.setFont(font) self.label_1.setScaledContents(True) self.label_1.setObjectName("屏幕录制器") self.label_6 = QLabel(self.centralwidget) self.label_6.setGeometry(QRect(430, 20, 85, 31)) self.label_6.setTextFormat(Qt.AutoText) self.label_6.setScaledContents(True) self.label_6.setObjectName("注释1") self.checkbox = QCheckBox(self.centralwidget) self.checkbox.setGeometry(QRect(430, 100, 85, 20)) self.checkbox.setChecked(True) self.checkbox.stateChanged.connect(self.mouse_draw) self.checkbox.setObjectName("录制鼠标") self.comboBox = QComboBox(self.centralwidget) self.comboBox.setGeometry(QRect(430, 200, 85, 20)) self.comboBox.setEditable(False) self.comboBox.addItems(self.audio.input_dict.keys()) self.comboBox.addItems(['无']) self.comboBox.setMaxVisibleItems(9) self.comboBox.currentTextChanged.connect(self.change_combox) self.comboBox.setObjectName("音频来源") self.comboBox_3 = QComboBox(self.centralwidget) self.comboBox_3.setGeometry(QRect(430, 260, 80, 20)) self.comboBox_3.addItems(['双声道', '单声道']) self.comboBox_3.currentIndexChanged.connect(self.change_combox) self.comboBox_3.setObjectName("声道设置") self.pushButton = QPushButton(self.centralwidget) self.pushButton.setGeometry(QRect(470, 320, 41, 31)) self.pushButton.clicked.connect(self.stop) self.pushButton.setObjectName("停止") self.pushButton_2 = QPushButton(self.centralwidget) self.pushButton_2.setGeometry(QRect(430, 320, 41, 31)) self.pushButton_2.setObjectName("开始") self.pushButton_2.clicked.connect(self.start) self.pushButton_3 = QPushButton(self.centralwidget) self.pushButton_3.setGeometry(QRect(430, 290, 80, 23)) self.pushButton_3.setObjectName("保存目录") self.pushButton_3.clicked.connect(self.open_dirpath) self.pushButton_4 = QPushButton(self.centralwidget) self.pushButton_4.setGeometry(QRect(430, 70, 80, 23)) self.pushButton_4.setCheckable(True) self.pushButton_4.setObjectName("Size") self.pushButton_4.clicked.connect(self.get_screen_area) self.spinBox = QSpinBox(self.centralwidget) self.spinBox.setValue(15) self.spinBox.setRange(10, 60) self.spinBox.setGeometry(QRect(430, 145, 80, 20)) self.spinBox.valueChanged.connect(self.screen_fps_mofify) self.spinBox.setObjectName("spinBox") self.label_2 = QLabel(self.centralwidget) self.label_2.setGeometry(QRect(430, 50, 54, 16)) self.label_2.setTextFormat(Qt.AutoText) self.label_2.setObjectName("选择区域") self.label_3 = QLabel(self.centralwidget) self.label_3.setGeometry(QRect(430, 125, 54, 16)) self.label_3.setObjectName("帧率") self.label_4 = QLabel(self.centralwidget) self.label_4.setGeometry(QRect(430, 240, 54, 16)) self.label_4.setObjectName("声道设置") self.label_5 = QLabel(self.centralwidget) self.label_5.setGeometry(QRect(430, 180, 54, 16)) self.label_5.setObjectName("音频来源") self.setCentralWidget(self.centralwidget) self.retranslateUi() QMetaObject.connectSlotsByName(self) def retranslateUi(self): self.pushButton.setText("停止") self.pushButton_2.setText("开始") self.pushButton_3.setText("保存目录") self.pushButton_4.setText("Size*Size") self.checkbox.setText("录制鼠标") self.label_1.setText("屏幕录制器") self.label_2.setText("选择区域:") self.label_3.setText("帧率:") self.label_4.setText("声道设置:") self.label_5.setText("音频来源:") self.label_6.setText("F7:开始/停止") def keyPressEvent(self, event): """监测键盘是否按下F3,如果已开始录制则停止,否则开始录制""" if event.key() == Qt.Key_F7: if not self.hotkey_start: self.start() else: self.stop() def change_combox(self, event): sendername = self.sender().objectName() if sendername == '声道设置': self.channels = 2 if event == 0 else 1 elif sendername == '音频来源': if event == '无': self.record_audio = False else: self.record_audio = True self.device_name = event def get_screen_grab(self, crop_size): # 获取屏幕截图并更新至self.label0中 screen = ImageGrab.grab().convert('RGBA') screen = screen.crop(box=crop_size) # box=(left, upper, right, lower) data = screen.tobytes("raw", "RGBA") qim = QImage(data, screen.size[0], screen.size[1], QImage.Format_RGBA8888) pix = QPixmap.fromImage(qim).scaled(self.label0.size(), aspectRatioMode=Qt.KeepAspectRatio) pix.detach() # QPixmap为另开线程操作的,避免程序崩溃,使用detach方法使用一个QImage对象直到QPixmap对象销毁 self.label0.setPixmap(pix) self.label0.repaint() return screen.size def get_screen_area(self): # 获取截图区间 SizeScreen = MousePaint() SizeScreen.exec_() self.offset_x, self.offset_y = SizeScreen.lastpoint end_x, end_y = SizeScreen.endpoint self.screen_x, self.screen_y = self.get_screen_grab((self.offset_x, self.offset_y, end_x, end_y)) self.screenshot.config_modify(offset_x=self.offset_x, offset_y=self.offset_y, width=self.screen_x, height=self.screen_y) self.pushButton_4.setText(f'{self.screen_x}*{self.screen_y}') def screen_fps_mofify(self, fps): self.screenshot.config_modify(fps=fps) def mouse_draw(self, checked): draw_mouse = 1 if checked else 0 self.screenshot.config_modify(draw_mouse=draw_mouse) def open_dirpath(self): fdir = QFileDialog.getExistingDirectory(self, '选择目录', self._dir) if not fdir: return None self._dir = fdir self.set_filename() def set_filename(self): self.fname = f'{self._dir}/屏幕录制缓存_{int(datetime.now().replace(microsecond=0).timestamp())}' self.screenshot.config_modify(filename=self.fname) self.audio = AudioRecord() self.setWindowTitle(f'屏幕录制 {self.fname}') def start(self): if self.hotkey_start: return if not self.fname: QMessageBox.warning(self, '请选择保存目录!', '请选择保存目录!') return self.screenshot.start() if self.record_audio: self.audio.stop_flag = False self.audio.run(filename=self.fname + '.mp3', name=self.device_name) self.hotkey_start = True def stop(self): if not self.hotkey_start: return self.audio.stop_flag = True self.hotkey_start = False self.screenshot.stop() if self.record_audio: self.screenshot.compose() else: filename = self.fname + '.mp4' target = filename.replace('缓存', '') Path(filename).replace(target) self.set_filename() class MousePaint(QDialog): """移动鼠标获取屏幕捕获范围""" def __init__(self): super().__init__() self.setMouseTracking(True) # 设置窗口布满整个屏幕 self.showFullScreen() # 设置窗体无边框 self.setWindowFlags(Qt.FramelessWindowHint) # 窗口置顶,无边框 # 设置背景透明 self.setWindowOpacity(0.5) self.initUI() self.setFocus() def initUI(self): self.setGeometry(*(QDesktopWidget().screenGeometry()).getRect()) self.pix = QPixmap() self.lastpoint = QPoint() self.endpoint = QPoint() self.pos = None self.bline = 0 def mousePressEvent(self, event): # 监听鼠标按压事件 if event.button() == Qt.LeftButton: self.lastpoint = event.x(), event.y() self.bline = 1 elif event.button() == Qt.RightButton: self.close() event.accept() def mouseReleaseEvent(self, event): # 监听鼠标释放事件 self.endpoint = event.x(), event.y() self.bline = 0 event.accept() self.close() def mouseMoveEvent(self, event): # 监听鼠标移动事件 if self.bline == 1: self.pos = event.x(), event.y() event.accept() self.update() def paintEvent(self, event): # 绘画事件 if self.bline == 1: pp = QPainter(self) pen = QPen() # 定义笔格式对象 pen.setWidth(5) # 设置笔的宽度 pen.setColor(QColor(255, 0, 0)) pp.setPen(pen) lpx, lpy = self.lastpoint pp.drawRect(lpx, lpy, self.pos[0] - lpx, self.pos[1] - lpy) event.accept() # def main(): # """运行函数""" # # 将7zip压缩格式添加到shutil中 # shutil.register_archive_format('7zip', pack_7zarchive, description='7zip archive') # shutil.register_unpack_format('7zip', ['.7z'], unpack_7zarchive, description='7zip archive') # app = QApplication(sys.argv) # app.setAttribute(Qt.AA_UseHighDpiPixmaps) # ui = Ui_MainWindow1() # sys.exit(app.exec_()) #if __name__ == '__main__': # main()