add components

gutin
linxiao 2018-06-16 22:06:56 +08:00
parent 3a38df12a9
commit 30205c86c9
9 changed files with 181 additions and 68 deletions

View File

@ -2,10 +2,22 @@ import re
import RunCMD
from RunCMD import run_cmd
import cchardet
import logging
class DevicesInfo():
def __init__(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)
self.logger.addHandler(handler)
list_devices_cmd = 'ffmpeg -list_devices true -f dshow -i dummy'
# status, output = subprocess.getstatusoutput(list_devices_cmd)
output_err, output_str = run_cmd(list_devices_cmd, universal_newlines = False)
@ -33,11 +45,15 @@ class DevicesInfo():
device_line = []
devices_output_copy = devices_output[0:]
devices_txt = ''
self.logger.info('devices_text:')
for txt in devices_output_copy:
# charset = cchardet.detect(txt)
# if charset
devices_txt += txt.decode('utf-8','ignore').replace(r'\r\n','')
self.logger.info(txt)
devices_txt += txt.decode('utf-8').replace(r'\r\n','')
# print(dir(re))
self.logger.info('decode result:')
self.logger.info(devices_txt)
print(devices_txt)
results = re.findall(r'\[[^\]]+\]([^\[]+)',devices_txt)
# results.pop(0)

View File

@ -3,7 +3,7 @@
# from DevicesInfo import *
class RecordConfig():
def __init__(self, config_file_name = 'config.ini'):
def __init__(self, config_file_name = 'configByLinxiao.ini'):
self.file_name = config_file_name
self.encoding = 'gb2312'
self.load()
@ -41,6 +41,11 @@ class RecordConfig():
conf.set(record_section_name,'vcodec','libx264')
conf.set(record_section_name,'frame_rate','7.0')
conf.set(record_section_name,'file_dir','.')
conf.set(record_section_name,'threads', '4')
conf.add_section('author')
conf.set('author', 'name', 'linxiao')
conf.set('author', 'mail', '940950943@qq.com')
self.config = conf
self.write()

View File

@ -19,22 +19,20 @@ class RecordHelp(QWidget):
self.setObjectName("Form")
self.resize(386, 238)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("resource/gutin.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon.addPixmap(QtGui.QPixmap("../record-camera-and-screen/resource/gutin.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.setWindowIcon(icon)
self.frame = QtWidgets.QFrame(self)
self.frame.setGeometry(QtCore.QRect(60, 330, 229, 10))
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.gridLayoutWidget = QtWidgets.QWidget(self)
self.gridLayoutWidget.setGeometry(QtCore.QRect(19, 19, 341, 201))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayoutWidget = QtWidgets.QWidget(self)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 391, 241))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(self.gridLayoutWidget)
self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(14)
font.setBold(True)
@ -43,31 +41,50 @@ class RecordHelp(QWidget):
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.label_2 = QtWidgets.QLabel(self.gridLayoutWidget)
self.label_2 = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label_2.setFont(font)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
self.label_3 = QtWidgets.QLabel(self.gridLayoutWidget)
self.label_3 = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setFamily("Agency FB")
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label_3.setFont(font)
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName("label_3")
self.verticalLayout.addWidget(self.label_3)
self.label_4 = QtWidgets.QLabel(self.gridLayoutWidget)
self.label_4 = QtWidgets.QLabel(self.verticalLayoutWidget)
self.label_4.setBaseSize(QtCore.QSize(0, 0))
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label_4.setFont(font)
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
self.label_4.setObjectName("label_4")
self.verticalLayout.addWidget(self.label_4)
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
self.label_5 = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_5.setFont(font)
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
self.label_5.setObjectName("label_5")
self.verticalLayout.addWidget(self.label_5)
self.label_6 = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_6.setFont(font)
self.label_6.setAlignment(QtCore.Qt.AlignCenter)
self.label_6.setObjectName("label_6")
self.verticalLayout.addWidget(self.label_6)
self.retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self)
@ -77,8 +94,10 @@ class RecordHelp(QWidget):
self.setWindowTitle(_translate("Form", "帮助"))
self.label.setText(_translate("Form", "Gutin谷田会议视频录播管理系统"))
self.label_2.setText(_translate("Form", "主要功能:录制屏幕和摄像头"))
self.label_3.setText(_translate("Form", "开发者:林潇 "))
self.label_4.setText(_translate("Form", "联系方式940950943@qq.com"))
self.label_3.setText(_translate("Form", "默认快捷键:"))
self.label_4.setText(_translate("Form", "录制摄像头Ctrl + Shfit + Alt + A"))
self.label_5.setText(_translate("Form", "录制屏幕Ctrl + Shift + Alt + B"))
self.label_6.setText(_translate("Form", "停止录制Ctrl + Shift + Alt + C"))
def showWindow(self):
if not self.isVisible():

View File

@ -11,7 +11,7 @@ import RecordConfig
from RecordConfig import *
import logging
import RunCMD
from RunCMD import run_cmd
from RunCMD import get_ffmpeg_path
class RecordVideo():
@ -72,6 +72,8 @@ class RecordVideo():
self.brate=rc.config.getfloat('record','frame_rate')
#文件目录
self.file_dir= os.path.abspath(rc.config.get('record','file_dir'))
#线程数
self.threads = rc.config.getint('record','threads')
self.logger.info('camera device name: %s' % self.camera_name)
self.logger.info('voice device name: %s' % self.voice_device_name)
@ -83,27 +85,6 @@ class RecordVideo():
self.logger.info('save dir: %s' % self.file_dir)
def get_ffmpeg_path(self):
datadir = ''
subdir = os.path.join('ffmpeg-shared','bin')
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
datadir = os.path.join(datadir, subdir)
datadir = os.path.abspath(datadir)
print(datadir)
#如果存在ffmpeg.exe
if os.path.isfile(os.path.join(datadir, 'ffmpeg.exe')):
return datadir
#兼容环境变量设置
return ''
def start_ffmpeg(self,cmd, shell = True):
try:
@ -159,17 +140,17 @@ class RecordVideo():
# self.logger.info(self.process.communicate())
# print('done.')
def record(self,cmd='ffmpeg -h', target = None):
def record(self, cmd='ffmpeg -h', target = None):
if target:
cmd = os.path.join(self.get_ffmpeg_path(), cmd)
cmd = os.path.join(get_ffmpeg_path(), cmd)
print('cmd: \n%s' % cmd)
self.logger.info('record cmd:\n %s' % cmd)
th=Thread(name=self.record_thread_name, target= target, args = (cmd,), daemon=True)
self.record_thread = Thread(name=self.record_thread_name, target= target, args = (cmd,), daemon=True)
th.start()
self.recording=True
self.exception_exit = False
self.record_thread=th
print('record thread,ident:%d' % self.record_thread.ident)
# th.join()
@ -199,12 +180,13 @@ class RecordVideo():
if self.camera_name and self.voice_device_name:
self.record_type=RecordType.Camera
record_cmd='ffmpeg -f dshow -i video=\"%s\":audio=\"%s\" -acodec libmp3lame -vcodec %s -preset:v ultrafast -tune:v zerolatency -s %s -r %d -y %s' %(
record_cmd='ffmpeg -f dshow -i video=\"%s\":audio=\"%s\" -acodec libmp3lame -vcodec %s -preset:v ultrafast -tune:v zerolatency -s %s -r %d -threads %d -y %s' %(
self.deal_with_device_name(self.camera_name),
self.deal_with_device_name(self.voice_device_name),
self.video_codec,
self.resolution,
self.brate,
self.threads,
self.get_file_name()
)
# print(record_cmd)
@ -213,16 +195,43 @@ class RecordVideo():
def record_screen(self):
if self.screen_name and self.system_voice_device_name:
self.record_type=RecordType.Screen
record_cmd='ffmpeg -f dshow -i video="{}":audio="{}" -acodec libmp3lame -vcodec {} -preset:v ultrafast -tune:v zerolatency -s {} -r {} -y {}'.format(
record_cmd='ffmpeg -f dshow -i video="{}":audio="{}" -acodec libmp3lame -vcodec {} -preset:v ultrafast -tune:v zerolatency -s {} -r {} -threads {} -y {}'.format(
self.deal_with_device_name(self.screen_name),
self.deal_with_device_name(self.system_voice_device_name),
self.video_codec,
self.resolution,
'1024x768', #屏幕录制分辨率固定
self.brate,
self.threads,
self.get_file_name()
)
self.record(record_cmd, self.start_ffmpeg)
def check_device(self):
#简单验证摄像头设置是否为空
ready = True
l_msg = ''
if not self.camera_name:
ready = False
l_msg += '摄像头设备为空\n'
if not self.voice_device_name:
ready = False
l_msg += '麦克风设备为空\n'
if not self.screen_name:
ready = False
l_msg += '屏幕录制驱动为空\n'
if not self.system_voice_device_name:
ready = False
l_msg += '系统声音录制驱动为空\n'
if ready:
l_msg = '设备检测正常'
print(l_msg)
self.logger.info(l_msg)
return ready
def debug_camera(self):
try:
@ -252,14 +261,18 @@ class RecordVideo():
return device_name
def get_file_name(self):
time_str=datetime.now().strftime('%Y%m%d_%H%M%S')
video_type = ''
date_dir = datetime.now().strftime('%Y-%m-%d')
time_str = datetime.now().strftime('%H_%M')
video_type_name = ''
if self.record_type == RecordType.Camera:
video_type = '摄像头'
video_type_name = '摄像头'
if self.record_type == RecordType.Screen:
video_type = '屏幕'
video_type_name = '屏幕'
file_name = os.path.join(self.file_dir, '{}_{}{}'.format(video_type, time_str, self.file_suffix))
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))
print('recording file name: %s' % file_name)
return file_name

View File

@ -303,16 +303,30 @@ class RecordWindow(QtWidgets.QWidget):
print('检测到正在录制,录制类型将切换...')
self.stop_record()
#开始录制
if rtype == RecordType.Camera:
print('开始录制摄像头...')
self.rv.record_camera()
elif rtype == RecordType.Screen:
print('开始录制屏幕...')
self.rv.record_screen()
if self.rv.check_device():
#开始录制
if rtype == RecordType.Camera:
print('开始录制摄像头...')
self.rv.record_camera()
elif rtype == RecordType.Screen:
print('开始录制屏幕...')
self.rv.record_screen()
self.start_timer()
self.update_state()
self.start_timer()
self.update_state()
else:
question = QMessageBox.information(self, '提示', '检测到录制设备缺失,无法进行录制,请先完善设备设置。', QMessageBox.Yes)
# question = QMessageBox()
# question.setText('检测到录制设备缺失,无法进行录制,请先完善设备设置。')
# question.setWindowTitle('提示')
# question.setIcon(QMessageBox.Question)
# question.addButton(QMessageBox.Yes)
# question.addButton(QMessageBox.No)
# question.setDefaultButton(QMessageBox.No)
# ret = question.exec()
# if ret == QMessageBox.Yes:
# print('软件将退出.')
''''
鼠标拖动窗体

View File

@ -1,8 +1,10 @@
import subprocess
import subprocess,os,sys
def run_cmd(cmd, shell = True, universal_newlines = False):
output_info=[]
output_err=[]
cmd = os.path.join(get_ffmpeg_path(), cmd)
print('执行cmd\n%s' % cmd)
with subprocess.Popen(cmd,
shell = shell,
universal_newlines = universal_newlines,
@ -27,3 +29,25 @@ def run_cmd(cmd, shell = True, universal_newlines = False):
return output_err, output_info
def get_ffmpeg_path():
datadir = ''
subdir = os.path.join('ffmpeg-shared','bin')
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
datadir = os.path.join(datadir, subdir)
datadir = os.path.abspath(datadir)
print(datadir)
#如果存在ffmpeg.exe
if os.path.isfile(os.path.join(datadir, 'ffmpeg.exe')):
return datadir
#兼容环境变量设置
return ''

View File

@ -173,7 +173,7 @@ class SettingWindow(QDialog):
def retranslateUi(self):
_translate = QtCore.QCoreApplication.translate
self.setWindowTitle(_translate("Form", "设置-Development By Linxiao"))
self.setWindowTitle(_translate("Form", "设置"))
self.label_3.setText(_translate("Form", "屏幕录制设备:"))
self.label_2.setText(_translate("Form", "声音输入设备:"))
self.label.setText(_translate("Form", "摄像头名称:"))

22
configByLinxiao.ini Normal file
View File

@ -0,0 +1,22 @@
[devices]
camera_device_name =
voice_device_name =
screen_device_name =
system_voice_device_name =
[shortcut]
camera = 160,162,164,65
screen = 160,162,164,66
stop = 160,162,164,67
[record]
resolution = 1920x1080
vcodec = libx264
frame_rate = 7.0
file_dir = .
threads = 4
[author]
name = linxiao
mail = 940950943@qq.com

View File

@ -2,8 +2,8 @@ import sys
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = { 'include_files':['resource','ffmpeg-shared']}
install_exe_options = { 'install_dir' : 'd:\\record-camera-and-screen', 'build_dir':'build', 'install_exe':'d:\\record-camera-and-screen'}
build_exe_options = { 'include_files':['resource','ffmpeg-shared'], 'build_exe' : 'd:/dev/record/record-win'}
install_exe_options = { 'install_dir' : 'd:/dev/record/record-win', 'build_dir':'build', 'install_exe':'d:\\record-camera-and-screen'}
# GUI applications require a different base on Windows (the default is for a
# console application).
@ -12,7 +12,7 @@ if sys.platform == "win32":
base = "Win32GUI"
executables = [
Executable('RecordWindow.py', base=base, icon = 'resource/gutin.ico', targetName = 'RecordWindow.exe')
Executable('RecordWindow.py', base=base, icon = 'resource/gutin.ico')
]
setup( name = "Gutin谷田会议视频录播管理系统",
version = "0.2",