From 12b5fdaa3e992b2c0da1c21075ce17fcbb38f060 Mon Sep 17 00:00:00 2001 From: linxiao <chunjinge@gmail.com> Date: Sun, 24 Jun 2018 22:25:28 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=AA=97=E5=8F=A3=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BF=9D=E5=AD=98=E5=92=8C=E5=8F=96=E6=B6=88=E6=8C=89?= =?UTF-8?q?=E9=92=AE,=E6=B7=BB=E5=8A=A0cpu=E7=BA=BF=E7=A8=8B=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=EF=BC=9B=E8=AE=BE=E7=BD=AE=E4=BF=AE=E6=94=B9=E5=AE=9E?= =?UTF-8?q?=E6=97=B6=E7=94=9F=E6=95=88=EF=BC=9B=E4=BB=A3=E7=A0=81=E7=AE=80?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- RecordConfig.py | 2 +- RecordVideo.py | 109 ++++++++++++++--- RecordWindow.py | 112 ++++++++++++----- SettingWindow.py | 289 +++++++++++++++++++++++++++++++------------- configByLinxiao.ini | 22 ++-- 5 files changed, 387 insertions(+), 147 deletions(-) diff --git a/RecordConfig.py b/RecordConfig.py index 64182d7..92df421 100644 --- a/RecordConfig.py +++ b/RecordConfig.py @@ -45,7 +45,7 @@ class RecordConfig(): conf.add_section('author') conf.set('author', 'name', 'linxiao') - conf.set('author', 'mail', '940950943@qq.com') + conf.set('author', 'mail', '940950943@qqqqqqqqqqqqqqqqqqqqqqqqqqqq.com') self.config = conf self.write() diff --git a/RecordVideo.py b/RecordVideo.py index f43430f..583d59f 100644 --- a/RecordVideo.py +++ b/RecordVideo.py @@ -1,4 +1,4 @@ -import datetime,time,sys,os,signal,re +import datetime,time,sys,os,signal,re,winreg from datetime import datetime import subprocess,threading from subprocess import CalledProcessError @@ -12,6 +12,7 @@ from RecordConfig import * import logging import RunCMD from RunCMD import get_ffmpeg_path +from winreg import HKEY_CURRENT_USER, OpenKey, QueryInfoKey, EnumValue, SetValueEx, CloseKey, REG_SZ, KEY_READ, KEY_SET_VALUE class RecordVideo(): @@ -38,21 +39,24 @@ class RecordVideo(): self.record_thread=None self.file_dir = '' - self.load_config() - - - def load_config(self): + self.load() + def load(self): #日志 self.logger = logging.getLogger(__name__) self.logger.setLevel(level = logging.INFO) handler = logging.FileHandler('log.txt') handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') - handler.setFormatter(formatter) + handler.setFormatter(formatter) self.logger.addHandler(handler) + self.load_config() + + + def load_config(self): + rc = RecordConfig() self.config = rc.config @@ -92,11 +96,19 @@ class RecordVideo(): self.logger.info('录制中...') # print('cmd:\n%s' % cmd) start_time = datetime.now() - self.process=subprocess.Popen(cmd, shell=shell, universal_newlines = True, stdin = subprocess.PIPE, stderr = subprocess.STDOUT, stdout = subprocess.PIPE) + self.process=subprocess.Popen(cmd, shell=shell, universal_newlines = False, stdin = subprocess.PIPE, stderr = subprocess.STDOUT, stdout = subprocess.PIPE) line = '' while self.recording: - - line += self.process.stdout.readline() + + # print(cmd) + # tmp_out = self.process.stdout.readline() + # print('test tmp out:%s' % tmp_out) + # line += self.process.stdout.readline() + #文字输出编码错误记录 + #异常:UnicodeDecodeError: 'gbk' codec can't decode byte 0xb4 in position 2881: illegal multibyte sequence + #原因:cmd输出包含中文字符 + #解决方案:universal_newlines = False + now = datetime.now() if (now - start_time).total_seconds() >2: # self.logger.info('recording...') @@ -104,6 +116,7 @@ class RecordVideo(): if self.process: ffmpeg_running = self.process.poll() is None log_text = 'ffmpeg 运行状态:%s' % ('运行中' if ffmpeg_running else '终止') + print(log_text) self.logger.info(log_text) @@ -118,14 +131,14 @@ class RecordVideo(): raise CalledProcessError(self.process.returncode, cmd) # self.logger.info(line) - print(line) + # print(line) line = '' start_time = now # print(line) if not self.recording: - self.process.stdin.write('q') + self.process.stdin.write(b'q') print(self.process.communicate()) break @@ -147,7 +160,7 @@ class RecordVideo(): print('cmd: \n%s' % cmd) self.logger.info('record cmd:\n %s' % cmd) self.record_thread = Thread(name=self.record_thread_name, target= target, args = (cmd,), daemon=True) - th.start() + self.record_thread.start() self.recording=True self.exception_exit = False @@ -231,8 +244,72 @@ class RecordVideo(): print(l_msg) self.logger.info(l_msg) return ready - + + + def check_run_state(self): + #验证运行有效性逻辑: + #一、判断是否正常安装 + #判断条件:软件安装时在注册表“HKEY_CURRENT_USER\\SOFTWARE\\Gutin\\Record“记录下安装目录 + #二、非正常安装有效时间为三个月,且只能发生一次 + + #验证当前运行目录是否存在注册表中 + qualified = False + run_dir = os.path.abspath('.') + # print('run_dir:%s' % run_dir) + reg_path = 'SOFTWARE\\Gutin\\Record' + feature_name ='InstallDir' + key = OpenKey(HKEY_CURRENT_USER, reg_path, access = KEY_READ) + items = QueryInfoKey(key) + for i in range(items[1]): + item = EnumValue(key, i) + name = item[0] + value = item[1] + type = item[2] + if name and name.find(feature_name)>=0: + if os.path.samefile(value, run_dir): + qualified = True + break; + + if not qualified: + #查找非正常安装目录记录 + #记录以运行目录的hash值作为键名,值为首次运行的时间 + time_format= '%Y-%m-%d %H:%M:%S' + run_time = None + unqualified_key_name = 'Unqualified' + has_unqualified = False + for i in range(items[1]): + item = EnumValue(key, i) + name = item[0] + value = item[1] + type = item[2] + if name == unqualified_key_name: + has_unqualified = True + run_time = value + + if not has_unqualified: + #如果不存在,创建 + run_time = datetime.now().strftime(time_format) + key = OpenKey(HKEY_CURRENT_USER, reg_path, access = KEY_SET_VALUE) + SetValueEx(key, unqualified_key_name, 0, REG_SZ, run_time) + + #判断时限 + # now = datetime.strptime('2018-06-22 12:11:51', time_format) + now = datetime.now() + run_time_obj = datetime.strptime(run_time, time_format) + print('first run_time:%s' % run_time) + print('now:%s' % now.strftime(time_format)) + # qual_days = 1 - (now - run_time_obj).days + # print('qualified days:%d' % (qual_days)) + qual_hours = (now - run_time_obj).total_seconds() // 3600 + # if qual_days > 0: + if 5 - qual_hours > 0: + qualified = True + + CloseKey(key) + return qualified + + def debug_camera(self): try: play_cmd = ['ffplay','-f','dshow','-i','video={}'.format(self.camera_name),'-window_title','按q退出','-noborder'] @@ -262,17 +339,19 @@ class RecordVideo(): def get_file_name(self): date_dir = datetime.now().strftime('%Y-%m-%d') - time_str = datetime.now().strftime('%H_%M') + time_str = datetime.now().strftime('%Y-%m-%d-%H%M%S') video_type_name = '' if self.record_type == RecordType.Camera: + # video_type_name = 'camera' video_type_name = '摄像头' if self.record_type == RecordType.Screen: video_type_name = '屏幕' + # video_type_name = 'screen' today_file_dir = os.path.join(self.file_dir, date_dir) if not os.path.exists(today_file_dir): os.mkdir(today_file_dir) - file_name = os.path.join(today_file_dir, '{}-{}-{}{}'.format(video_type_name, time_str, self.resolution, self.file_suffix)) + file_name = os.path.join(today_file_dir, '{}-{}{}'.format(video_type_name, time_str, self.file_suffix)) print('recording file name: %s' % file_name) return file_name diff --git a/RecordWindow.py b/RecordWindow.py index 8ca7aec..424e242 100644 --- a/RecordWindow.py +++ b/RecordWindow.py @@ -25,7 +25,7 @@ class RecordWindow(QtWidgets.QWidget): self.load_modules() #更新设置 self.need_update_config = False - self.need_hide = True + # self.need_hide = True #初始化状态 print('初始化状态...') self.update_state() @@ -48,8 +48,9 @@ class RecordWindow(QtWidgets.QWidget): # print('close window.') # self.close_signal.emit() # self.close() - # if self.recording: - + if self.recording: + + self.stop_record(force = True) # question = QMessageBox(self) # question.setText('系统正在录制中,确定要退出吗?') # question.setWindowTitle('提示') @@ -275,7 +276,10 @@ class RecordWindow(QtWidgets.QWidget): self.rti.update_state(self.recording, self.record_type) def stop_record(self, force = False): - + #force应用在两种情况: + #1.timer实时刷新ffmpeg进程状态,当出现异常退时force=true,即force=exception_exit。 + #2.应用退出时 + if self.recording or force: self.stop_timer() @@ -318,23 +322,37 @@ class RecordWindow(QtWidgets.QWidget): self.start_timer() self.update_state() else: - self.need_hide = False - question = QMessageBox.information(self, '提示', '检测到录制设备缺失,无法进行录制,请先完善设备设置。', QMessageBox.Yes) + # self.need_hide = False + # question = QMessageBox.information(self, '提示', '检测到录制设备缺失,无法进行录制,请先完善设备设置。', QMessageBox.Yes) # self.need_hide = True - # question = QMessageBox() - # question.setText('检测到录制设备缺失,无法进行录制,请先完善设备设置。') - # question.setWindowTitle('提示') - # question.setIcon(QMessageBox.Question) - # question.addButton(QMessageBox.Yes) + question = QMessageBox() + question.setText('检测到录制设备缺失,无法进行录制,请先完善设备设置。') + question.setWindowTitle('提示') + question.setIcon(QMessageBox.Question) + question.addButton(QMessageBox.Yes) + tmp_btn = question.button(QMessageBox.Yes) + tmp_btn.setText('确定') + + question.adjustSize() + screen_center = QApplication.desktop().screenGeometry() + question.move(((screen_center.width() - question.width()) /2), ((screen_center.height() - question.height())/2)) + # question.addButton(QMessageBox.No) # question.setDefaultButton(QMessageBox.No) - # ret = question.exec() + ret = question.exec() # if ret == QMessageBox.Yes: # print('软件将退出.') def show_setting(self): - self.need_hide = False + # QWidget.connect(self.sw, update_setting(bool), self, self.update_setting(bool)) + self.sw.update_setting.connect(self.update_setting) self.sw.showSettingWindow() + + def update_setting(self, changed): + if changed: + print('update setting..') + self.rv.load_config() + '''' 鼠标拖动窗体 @@ -376,27 +394,55 @@ class RecordWindow(QtWidgets.QWidget): def monitor_shortcut(self): - sc = Shortcut() + if self.rv.check_run_state(): - camera_key_group = self.rc.config.get('shortcut','camera') - screen_key_group = self.rc.config.get('shortcut','screen') - stop_record_key_group = self.rc.config.get('shortcut','stop') - - camera_shortcut = [int(key) for key in camera_key_group.split(',')] - screen_shortcut = [int(key) for key in screen_key_group.split(',')] - stop_shortcut = [int(key) for key in stop_record_key_group.split(',')] - - print('camera shortcut: %s' % camera_shortcut) - print('screen shortcut: %s' % screen_shortcut) - print('stop shortcut: %s' % stop_shortcut) - - if camera_key_group: - sc.add(1, camera_shortcut, lambda: self.record(RecordType.Camera)) - if screen_key_group: - sc.add(2, screen_shortcut, lambda: self.record(RecordType.Screen)) - if stop_record_key_group: - sc.add(3, stop_shortcut, self.stop_record) - sc.monitor() + sc = Shortcut() + + camera_key_group = self.rc.config.get('shortcut','camera') + screen_key_group = self.rc.config.get('shortcut','screen') + stop_record_key_group = self.rc.config.get('shortcut','stop') + + camera_shortcut = [int(key) for key in camera_key_group.split(',')] + screen_shortcut = [int(key) for key in screen_key_group.split(',')] + stop_shortcut = [int(key) for key in stop_record_key_group.split(',')] + + print('camera shortcut: %s' % camera_shortcut) + print('screen shortcut: %s' % screen_shortcut) + print('stop shortcut: %s' % stop_shortcut) + + if camera_key_group: + sc.add(1, camera_shortcut, lambda: self.record(RecordType.Camera)) + if screen_key_group: + sc.add(2, screen_shortcut, lambda: self.record(RecordType.Screen)) + if stop_record_key_group: + sc.add(3, stop_shortcut, self.stop_record) + + + sc.monitor() + + else: + question = QMessageBox(self) + question.setText('检测到软件非正常运行,以下功能将被禁用(如有疑问,请联系开发商):<br/><ul><li>快捷键</li></ul>') + question.setWindowTitle('限制使用模式') + question.setIcon(QMessageBox.Warning) + question.addButton(QMessageBox.Yes) + # question.setButtonText(QMessageBox.Yes, QString('确定')) + btn = question.button(QMessageBox.Yes) + # print(btn.text()) + btn.setText('确定') + # question.addButton('确定', QMessageBox.ButtonRole.AcceptRole) + + # print('screen x:%d,y:%d; question x:%d,y:%d.' % (screen_center.x(), screen_center.y(), question.x(), question.y())) + # print(question.frameGeometry()) + question.adjustSize() + screen_center = QApplication.desktop().screenGeometry() + #居中x和y的值计算与我想的不一样 + #原因:question在exec之前无法准确的获取其size。(485,170)是exec之后的实际size。 + question.move(((screen_center.width() - 485)/2), ((screen_center.height() - 170)/2)) + # question.move((screen_center.width() / 2 - question.width()), (screen_center.height() /2 - question.height())) + # print('screen x:%d,y:%d; question x:%d,y:%d; question width:%d,height:%d.' % (screen_center.width(), screen_center.height(), question.geometry().width(), question.geometry().height(), question.width(), question.height())) + # question.move(QApplication.desktop().screenGeometry().center()- self.rect().center()) + ret = question.exec() ''' 窗体事件 diff --git a/SettingWindow.py b/SettingWindow.py index 92321a4..809fb5f 100644 --- a/SettingWindow.py +++ b/SettingWindow.py @@ -7,19 +7,25 @@ from DevicesInfo import * import RecordConfig from RecordConfig import * from PyQt5.QtWidgets import QMessageBox +import resource +import psutil class SettingWindow(QDialog): + + update_setting = pyqtSignal(bool) def __init__(self, parent = None): super(SettingWindow,self).__init__(parent) + + self.changed = False self.setupUi() self.load() def setupUi(self): self.setObjectName("SettingWindow") - self.resize(386, 238) + self.setFixedSize(383, 280) icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap("resource/gutin.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon.addPixmap(QtGui.QPixmap(":/resource/gutin.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.setWindowIcon(icon) self.tabWidget = QtWidgets.QTabWidget(self) self.tabWidget.setGeometry(QtCore.QRect(10, 10, 371, 221)) @@ -108,11 +114,12 @@ class SettingWindow(QDialog): self.tab_record = QtWidgets.QWidget() self.tab_record.setObjectName("tab_record") self.gridLayoutWidget = QtWidgets.QWidget(self.tab_record) - self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 321, 161)) + self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 311, 161)) self.gridLayoutWidget.setObjectName("gridLayoutWidget") self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setHorizontalSpacing(0) + self.gridLayout.setVerticalSpacing(16) self.gridLayout.setObjectName("gridLayout") self.label_14 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_14.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) @@ -166,6 +173,28 @@ class SettingWindow(QDialog): self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") + + self.threads_label = QtWidgets.QLabel(self.gridLayoutWidget) + self.threads_label.setLayoutDirection(QtCore.Qt.LeftToRight) + self.threads_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.threads_label.setObjectName("threads_label") + self.gridLayout.addWidget(self.threads_label, 5, 0, 1, 1) + self.threads_spinBox = QtWidgets.QSpinBox(self.gridLayoutWidget) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.threads_spinBox.sizePolicy().hasHeightForWidth()) + self.threads_spinBox.setSizePolicy(sizePolicy) + self.threads_spinBox.setObjectName("record.threads") + self.gridLayout.addWidget(self.threads_spinBox, 5, 1, 1, 1) + self.tabWidget.addTab(self.tab_record, "") + + self.save_button = QtWidgets.QPushButton(self) + self.save_button.setGeometry(QtCore.QRect(180, 240, 75, 23)) + self.save_button.setObjectName("save_button") + self.cancel_button = QtWidgets.QPushButton(self) + self.cancel_button.setGeometry(QtCore.QRect(270, 240, 75, 23)) + self.cancel_button.setObjectName("cancel_button") self.retranslateUi() self.tabWidget.setCurrentIndex(0) @@ -188,13 +217,13 @@ class SettingWindow(QDialog): self.label_13.setText(_translate("Form", "文件保存目录:")) self.label_12.setText(_translate("Form", "分辨率:")) self.btn_file_dir.setText(_translate("Form", "选择文件目录")) + self.threads_label.setText(_translate("Form", "CPU线程:")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_record), _translate("Form", "录制参数")) + self.save_button.setText(_translate("Form", "保存")) + self.cancel_button.setText(_translate("Form", "取消")) - - - # def set_combobox_select_index_by_name_or_data(self, combobox, name_or_data): - # for i in range(len() def load_combobox_data(self, combox, data): + #下拉列表数据加载 for obj in data: name = obj[0] value = name @@ -205,13 +234,56 @@ class SettingWindow(QDialog): def get_key_group_name(self, key_tuple): return key_tuple.replace(r'(','').replace(r')','') + def load_config(self): + ''' + 加载设置 + ''' + #设备 + video_device_name = self.rc.config.get('devices','camera_device_name') + voice_device_name = self.rc.config.get('devices','voice_device_name') + screen_device_name = self.rc.config.get('devices','screen_device_name') + system_voice_device_name = self.rc.config.get('devices','system_voice_device_name') + # self.cb_camera_devices.setCurrentIndex(1) + video_cur_index = self.cb_camera_devices.findData(video_device_name) + # print('video name:\n%s\ndevice index:%d' % (video_device_name, video_cur_index)) + self.cb_camera_devices.setCurrentIndex(video_cur_index) + + self.cb_voice_devices.setCurrentIndex(self.cb_voice_devices.findData(voice_device_name)) + self.cb_screen_devices.setCurrentIndex(self.cb_screen_devices.findData(screen_device_name)) + self.cb_system_voice_devices.setCurrentIndex(self.cb_system_voice_devices.findData(system_voice_device_name)) + + #快捷键 + record_camera_key_group = self.rc.config.get('shortcut','camera') + record_screen_key_group = self.rc.config.get('shortcut','screen') + record_stop_key_group = self.rc.config.get('shortcut','stop') + + record_camera_key_group_name = self.get_key_group_name(record_camera_key_group) + record_screen_key_group_name = self.get_key_group_name(record_screen_key_group) + record_stop_key_group_name = self.get_key_group_name(record_stop_key_group) + + self.le_start_record_camera_shortcut.setText(record_camera_key_group_name) + self.le_start_record_screen_shortcut.setText(record_screen_key_group_name) + self.le_start_stop_exit_shortcut.setText(record_stop_key_group_name) + + #录制参数 + record_resolution = self.rc.config.get('record','resolution') + record_vcodec = self.rc.config.get('record','vcodec') + record_frame_rate = self.rc.config.getfloat('record','frame_rate') + record_file_dir = self.rc.config.get('record','file_dir') + record_file_dir = os.path.abspath(record_file_dir) + record_threads = int(self.rc.config.get('record','threads')) + + self.cb_resolution.setCurrentIndex(self.cb_resolution.findData(record_resolution)) + self.cb_vcodec.setCurrentIndex(self.cb_vcodec.findData(record_vcodec)) + self.dsb_frame_rate.setValue(record_frame_rate) + self.le_file_path.setText(record_file_dir) + + self.threads_spinBox.setValue(record_threads) + def load(self): - - rc = RecordConfig() - self.rc = rc - self.changed = False + self.rc = RecordConfig() ''' 数据初始化 ''' @@ -237,75 +309,38 @@ class SettingWindow(QDialog): self.load_combobox_data(self.cb_resolution, resolutions) self.load_combobox_data(self.cb_vcodec, vcodec) + self.dsb_frame_rate.setDecimals(1) + cpu_count = psutil.cpu_count(logical=True) + self.threads_spinBox.setMaximum(cpu_count) + # print(self.cb_camera_devices.currentData()) # print('视频设备列表:') # print(di.video_devices) # print('音频设备列表:') # print(di.voice_devices) - ''' - 加载设置 - ''' - #设备 - video_device_name = rc.config.get('devices','camera_device_name') - voice_device_name = rc.config.get('devices','voice_device_name') - screen_device_name = rc.config.get('devices','screen_device_name') - system_voice_device_name = rc.config.get('devices','system_voice_device_name') - - # self.cb_camera_devices.setCurrentIndex(1) - video_cur_index = self.cb_camera_devices.findData(video_device_name) - # print('video name:\n%s\ndevice index:%d' % (video_device_name, video_cur_index)) - self.cb_camera_devices.setCurrentIndex(video_cur_index) - - self.cb_voice_devices.setCurrentIndex(self.cb_voice_devices.findData(voice_device_name)) - self.cb_screen_devices.setCurrentIndex(self.cb_screen_devices.findData(screen_device_name)) - self.cb_system_voice_devices.setCurrentIndex(self.cb_system_voice_devices.findData(system_voice_device_name)) - - #快捷键 - record_camera_key_group = rc.config.get('shortcut','camera') - record_screen_key_group = rc.config.get('shortcut','screen') - record_stop_key_group = rc.config.get('shortcut','stop') - - record_camera_key_group_name = self.get_key_group_name(record_camera_key_group) - record_screen_key_group_name = self.get_key_group_name(record_screen_key_group) - record_stop_key_group_name = self.get_key_group_name(record_stop_key_group) - - self.le_start_record_camera_shortcut.setText(record_camera_key_group_name) - self.le_start_record_screen_shortcut.setText(record_screen_key_group_name) - self.le_start_stop_exit_shortcut.setText(record_stop_key_group_name) - - #录制参数 - record_resolution = self.rc.config.get('record','resolution') - record_vcodec = self.rc.config.get('record','vcodec') - record_frame_rate = self.rc.config.getfloat('record','frame_rate') - record_file_dir = self.rc.config.get('record','file_dir') - record_file_dir = os.path.abspath(record_file_dir) - - self.cb_resolution.setCurrentIndex(self.cb_resolution.findData(record_resolution)) - self.cb_vcodec.setCurrentIndex(self.cb_vcodec.findData(record_vcodec)) - self.dsb_frame_rate.setDecimals(1) - self.dsb_frame_rate.setValue(record_frame_rate) - self.le_file_path.setText(record_file_dir) + self.load_config() ''' 关联事件 ''' #设备 - self.cb_camera_devices.currentIndexChanged.connect(lambda: self.indexChangedEvent(self, self.cb_camera_devices)) - self.cb_voice_devices.currentIndexChanged.connect(lambda: self.indexChangedEvent(self, self.cb_voice_devices)) - self.cb_screen_devices.currentIndexChanged.connect(lambda: self.indexChangedEvent(self, self.cb_screen_devices)) - self.cb_system_voice_devices.currentIndexChanged.connect(lambda: self.indexChangedEvent(self, self.cb_system_voice_devices)) + self.cb_camera_devices.currentIndexChanged.connect(self.stateChangedEvent) + self.cb_voice_devices.currentIndexChanged.connect(self.stateChangedEvent) + self.cb_screen_devices.currentIndexChanged.connect(self.stateChangedEvent) + self.cb_system_voice_devices.currentIndexChanged.connect(self.stateChangedEvent) #快捷键 - self.le_start_record_camera_shortcut.textChanged.connect(lambda: self.textChangedEvent(self.le_start_record_camera_shortcut)) - self.le_start_record_screen_shortcut.textChanged.connect(lambda: self.textChangedEvent(self.le_start_record_screen_shortcut)) - self.le_start_stop_exit_shortcut.textChanged.connect(lambda: self.textChangedEvent(self.le_start_stop_exit_shortcut)) + self.le_start_record_camera_shortcut.textChanged.connect(self.stateChangedEvent) + self.le_start_record_screen_shortcut.textChanged.connect(self.stateChangedEvent) + self.le_start_stop_exit_shortcut.textChanged.connect(self.stateChangedEvent) #录制参数 - self.cb_resolution.currentIndexChanged.connect(lambda: self.indexChangedEvent(self, self.cb_resolution)) - self.cb_vcodec.currentIndexChanged.connect(lambda: self.indexChangedEvent(self, self.cb_vcodec)) - self.dsb_frame_rate.valueChanged.connect(self.valueChangedEvent) - self.le_file_path.textChanged.connect(lambda: self.textChangedEvent(self.le_file_path)) + self.cb_resolution.currentIndexChanged.connect(self.stateChangedEvent) + self.cb_vcodec.currentIndexChanged.connect(self.stateChangedEvent) + self.dsb_frame_rate.valueChanged.connect(self.stateChangedEvent) + self.le_file_path.textChanged.connect(self.stateChangedEvent) + self.threads_spinBox.valueChanged.connect(self.stateChangedEvent) # self.le_start_record_camera_shortcut.keyPressEvent = self.record_keypress # print(dir(self.le_start_record_camera_shortcut.keyPressEvent)) @@ -313,6 +348,10 @@ class SettingWindow(QDialog): # self.le_file_path.setText() self.btn_file_dir.clicked.connect(self.file_dir_select) + self.save_button.clicked.connect(self.save_setting) + self.cancel_button.clicked.connect(self.cancel) + + self.update_state() def record_keypress(self, event): @@ -323,8 +362,11 @@ class SettingWindow(QDialog): def file_dir_select(self, event): current_dir = self.le_file_path.text() - if os.path.exists(current_dir): - selected_dir = QFileDialog.getExistingDirectory(self, '选择录像保存目录', current_dir, QFileDialog.ShowDirsOnly) + # print('current dir:%s' % current_dir) + if not os.path.exists(current_dir): + current_dir = os.path.abspath('.') + selected_dir = QFileDialog.getExistingDirectory(self, '选择录像保存目录', current_dir, QFileDialog.ShowDirsOnly) + if selected_dir and os.path.exists(selected_dir): self.le_file_path.setText(selected_dir) def showSettingWindow(self): @@ -346,12 +388,70 @@ class SettingWindow(QDialog): print('parent is None?%s' % (self.parent is None)) self.changed = False - self.setVisible(False) - event.ignore() + # self.setVisible(False) + # event.ignore() def save_setting(self): + + + #获取改动值 + #设备 + camera_device_name = self.cb_camera_devices.currentData() + voice_device_name = self.cb_voice_devices.currentData() + screen_device_name = self.cb_screen_devices.currentData() + system_voice_device_name = self.cb_system_voice_devices.currentData() + # print(camera_device_name) + + #快捷键 + record_camera_key_group_name = '(' +self.le_start_record_camera_shortcut.text()+ ')' + record_screen_key_group_name = '(' +self.le_start_record_screen_shortcut.text()+ ')' + record_stop_key_group_name = '(' +self.le_start_stop_exit_shortcut.text()+ ')' + # print(record_camera_key_group_name) + + #录制 + resolution = self.cb_resolution.currentData() + video_codec = self.cb_vcodec.currentData() + frame_rate = self.dsb_frame_rate.value() + file_dir = self.le_file_path.text() + threads = self.threads_spinBox.value() + # print(threads) + + #保存 + conf = self.rc.config + + devices_section_name = 'devices' + conf.set(devices_section_name,'camera_device_name', camera_device_name) + conf.set(devices_section_name,'voice_device_name', voice_device_name) + conf.set(devices_section_name,'screen_device_name', screen_device_name) + conf.set(devices_section_name,'system_voice_device_name', system_voice_device_name) + + shortcut_section_name = 'shortcut' + conf.set(shortcut_section_name,'camera', record_camera_key_group_name) + conf.set(shortcut_section_name,'screen', record_screen_key_group_name) + conf.set(shortcut_section_name,'stop', record_stop_key_group_name) + + record_section_name = 'record' + conf.set(record_section_name,'resolution', resolution) + conf.set(record_section_name,'vcodec', video_codec) + conf.set(record_section_name,'frame_rate', str(frame_rate)) + conf.set(record_section_name,'file_dir', file_dir) + conf.set(record_section_name,'threads', str(threads)) + self.rc.write() + self.update_setting.emit(self.changed) + self.changed = False + self.update_state() + def update_state(self): + + self.save_button.setDisabled(not self.changed) + self.cancel_button.setDisabled(not self.changed) + + def cancel(self): + self.load_config() + self.changed=False + self.update_state() + def setting(self, obj_name, value): section = '' @@ -374,32 +474,47 @@ class SettingWindow(QDialog): pass print('not found this section or name.') - def indexChangedEvent(self, index, obj): + # def indexChangedEvent(self, index, obj): # print('in data changed event.') - print(index) - print('event obj:%s' % type(obj)) - print('obj name:%s' % obj.objectName()) + # print(index) + # print('event obj:%s' % type(obj)) + # print('obj name:%s' % obj.objectName()) - value = obj.currentData() - obj_name = obj.objectName() - self.setting(obj_name, value) + # value = obj.currentData() + # obj_name = obj.objectName() + # self.setting(obj_name, value) + def stateChangedEvent(self, new_value): + print('changed value is :%s' % new_value) + self.changed = True + self.update_state() - def textChangedEvent(self, obj): + # def textChangedEvent(self, obj): # print('type of self:%s' % type(self)) # print('type of text:%s' % type(text)) # print('type of obj:%s' % type(obj)) - value = obj.text() - obj_name = obj.objectName() - self.setting(obj_name, value) + # value = obj.text() + # obj_name = obj.objectName() + # self.setting(obj_name, value) - def valueChangedEvent(self): - print('in value changed event.') - obj = self.dsb_frame_rate - value = obj.value() - print('value:%1.f' % value) - obj_name = obj.objectName() - self.setting(obj_name, str(value)) + # def valueChangedEvent(self, new_value): + # print('changed value is :%s.' % new_value) + + # self.changed = True + # self.update_state() + # obj = self.dsb_frame_rate + # value = obj.value() + # print('value:%1.f' % value) + # obj_name = obj.objectName() + # self.setting(obj_name, str(value)) + + # def valueChangedEvent_spinBox(self): + # print('in value changed event.') + # obj = self.threads_spinBox + # value = obj.value() + # print('value:%1.f' % value) + # obj_name = obj.objectName() + # self.setting(obj_name, str(value)) diff --git a/configByLinxiao.ini b/configByLinxiao.ini index 211af45..8853499 100644 --- a/configByLinxiao.ini +++ b/configByLinxiao.ini @@ -1,22 +1,22 @@ [devices] -camera_device_name = -voice_device_name = -screen_device_name = -system_voice_device_name = +camera_device_name = @device_pnp_\\?\usb#vid_04f2&pid_b354&mi_00#7&30d7ad30&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global +voice_device_name = @device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{571529B3-7DB3-42A3-ADEF-BBD82925C15D} +screen_device_name = @device_sw_{860BB310-5D01-11D0-BD3B-00A0C911CE86}\{4EA69364-2C8A-4AE6-A561-56E4B5044439} +system_voice_device_name = @device_sw_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\{8E146464-DB61-4309-AFA1-3578E927E935} [shortcut] -camera = 160,162,164,65 -screen = 160,162,164,66 -stop = 160,162,164,67 +camera = (160,162,164,65) +screen = (160,162,164,66) +stop = (160,162,164,67) [record] -resolution = 1920x1080 +resolution = 1280x1024 vcodec = libx264 -frame_rate = 7.0 -file_dir = . +frame_rate = 30.0 +file_dir = C:/Users/lv/ctest/record-camera-and-screen threads = 4 [author] name = linxiao -mail = 940950943@qq.com +mail = 940950943@qqqqqqqqqqqqqqqqqqqqqqqqqqqq.com