mirror of
https://github.com/HaujetZhao/CapsWriter.git
synced 2025-07-13 21:12:08 +08:00
经过测试,如果在windows上按下按键的时候才开始启动录音,录音启动会有一定的延迟,这个延迟大概在0.5到1秒钟。为了能做到按下按键的时候,就立刻开始录音,现在在启动引擎之后,现在程序会持续性调用麦克风(但不会将录音数据写入内存),对耗电量影响也不大,当按下按键的时候,就会立刻将录音数据开始写入内存,这样就可以做到按下按键的时候立马开始说话,也能捕捉到。
另外,录音进程是在一个新的线程中进行的,但是发现了pyside 的一个 bug,当新线程中存在一个 pyaudio stream 时,就会阻塞其他的图形界面。所以在启动引擎之后,就不要点击其他按钮了,可能会导致页面卡死。如果换成 PyQt5 就不会有这个问题。目前已反馈至 PySide 的 bug 反馈平台:https://bugreports.qt.io/browse/PYSIDE-1465,希望官方可以修复,如果不行的话,以后就换成 PyQt5。 对导入模块进行了精简。
This commit is contained in:
parent
3d727d0364
commit
6bd5f55dcf
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,6 +14,7 @@ __pycache__
|
|||||||
*/dist/*
|
*/dist/*
|
||||||
*/build/*
|
*/build/*
|
||||||
*.db
|
*.db
|
||||||
|
*test/*
|
||||||
*.afphoto
|
*.afphoto
|
||||||
icon*.png
|
icon*.png
|
||||||
视频封面.png
|
视频封面.png
|
||||||
|
@ -6,9 +6,9 @@ os.chdir(os.path.dirname(os.path.abspath(__file__))) # 更改工作目录,指
|
|||||||
sys.path.append(os.path.dirname(os.path.abspath(__file__))) # 将当前目录导入 python 寻找 package 和 moduel 的变量
|
sys.path.append(os.path.dirname(os.path.abspath(__file__))) # 将当前目录导入 python 寻找 package 和 moduel 的变量
|
||||||
# os.environ['PATH'] += os.pathsep + os.path.abspath('./bin') # 将可执行文件的目录加入环境变量
|
# os.environ['PATH'] += os.pathsep + os.path.abspath('./bin') # 将可执行文件的目录加入环境变量
|
||||||
|
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtWidgets import QApplication
|
||||||
from PySide2.QtCore import *
|
from PySide2.QtCore import QCoreApplication
|
||||||
from PySide2.QtGui import *
|
from PySide2.QtGui import Qt
|
||||||
|
|
||||||
from moduels.function.createDB import createDB # 引入检查和创建创建数据库的函数
|
from moduels.function.createDB import createDB # 引入检查和创建创建数据库的函数
|
||||||
|
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import pyaudio
|
|
||||||
import threading
|
|
||||||
import keyboard
|
import keyboard
|
||||||
import time
|
|
||||||
|
|
||||||
from ali_speech.callbacks import SpeechRecognizerCallback
|
from ali_speech.callbacks import SpeechRecognizerCallback
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
import sys
|
||||||
|
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtWidgets import QTextEdit
|
||||||
from PySide2.QtGui import *
|
from PySide2.QtGui import QTextCursor
|
||||||
|
|
||||||
|
from moduels.component.Stream import Stream
|
||||||
|
|
||||||
# 命令输出窗口中的多行文本框
|
# 命令输出窗口中的多行文本框
|
||||||
class QEditBox_StdoutBox(QTextEdit):
|
class QEditBox_StdoutBox(QTextEdit):
|
||||||
@ -9,6 +12,9 @@ class QEditBox_StdoutBox(QTextEdit):
|
|||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(QEditBox_StdoutBox, self).__init__(parent)
|
super(QEditBox_StdoutBox, self).__init__(parent)
|
||||||
self.setReadOnly(True)
|
self.setReadOnly(True)
|
||||||
|
self.标准输出流 = Stream()
|
||||||
|
self.标准输出流.newText.connect(self.print)
|
||||||
|
sys.stdout = self.标准输出流
|
||||||
|
|
||||||
def print(self, text):
|
def print(self, text):
|
||||||
try:
|
try:
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtWidgets import QDialog
|
||||||
from PySide2.QtGui import *
|
from PySide2.QtGui import Qt, QIcon, QPainter, QPixmap
|
||||||
from PySide2.QtCore import *
|
|
||||||
|
|
||||||
from moduels.component.NormalValue import 常量
|
from moduels.component.NormalValue import 常量
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from PySide2.QtWidgets import *
|
|
||||||
from PySide2.QtGui import *
|
from PySide2.QtCore import Signal, QObject
|
||||||
from PySide2.QtCore import *
|
|
||||||
|
|
||||||
|
|
||||||
class Stream(QObject):
|
class Stream(QObject):
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
import os, sqlite3
|
import os, sqlite3
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtWidgets import QComboBox
|
||||||
from PySide2.QtGui import *
|
|
||||||
from PySide2.QtCore import *
|
|
||||||
from moduels.component.NormalValue import 常量
|
from moduels.component.NormalValue import 常量
|
||||||
|
|
||||||
# 添加预设对话框
|
# 添加预设对话框
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtWidgets import QGroupBox, QLineEdit, QPushButton, QGridLayout
|
||||||
from moduels.gui.List_List import List_List
|
from moduels.gui.List_List import List_List
|
||||||
|
|
||||||
# 添加预设对话框
|
# 添加预设对话框
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtWidgets import QListWidget
|
||||||
from PySide2.QtGui import *
|
from PySide2.QtCore import Signal
|
||||||
from PySide2.QtCore import *
|
|
||||||
from moduels.component.NormalValue import 常量
|
from moduels.component.NormalValue import 常量
|
||||||
|
|
||||||
# 添加预设对话框
|
# 添加预设对话框
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtWidgets import QMainWindow, QTabWidget
|
||||||
from PySide2.QtGui import *
|
from PySide2.QtGui import QIcon, Qt
|
||||||
|
|
||||||
from moduels.component.NormalValue import 常量
|
from moduels.component.NormalValue import 常量
|
||||||
|
|
||||||
from moduels.gui.Tab_CapsWriter import Tab_CapsWriter
|
from moduels.gui.Tab_CapsWriter import Tab_CapsWriter
|
||||||
# from moduels.gui.Tab_Stdout import Tab_Stdout
|
|
||||||
from moduels.gui.Tab_Config import Tab_Config
|
from moduels.gui.Tab_Config import Tab_Config
|
||||||
from moduels.gui.Tab_Help import Tab_Help
|
from moduels.gui.Tab_Help import Tab_Help
|
||||||
|
|
||||||
@ -24,7 +23,6 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
|
|
||||||
# self.setWindowState(Qt.WindowMaximized)
|
# self.setWindowState(Qt.WindowMaximized)
|
||||||
# sys.stdout = Stream(newText=self.onUpdateText)
|
|
||||||
|
|
||||||
def initElements(self):
|
def initElements(self):
|
||||||
self.状态栏 = self.statusBar()
|
self.状态栏 = self.statusBar()
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtWidgets import QSystemTrayIcon, QMenu, QApplication, QAction
|
||||||
from PySide2.QtCore import *
|
# from PySide2.QtCore import *
|
||||||
from PySide2.QtGui import *
|
from PySide2.QtGui import QIcon
|
||||||
|
from PySide2.QtCore import Qt
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -1,29 +1,16 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QPushButton
|
||||||
from PySide2.QtGui import *
|
# from PySide2.QtGui import *
|
||||||
from PySide2.QtCore import *
|
from PySide2.QtCore import Signal
|
||||||
import sys, os, re, subprocess, time
|
import os, re, subprocess, time
|
||||||
|
|
||||||
import pyaudio
|
import pyaudio
|
||||||
|
|
||||||
# from moduels.component.QLEdit_FilePathQLineEdit import QLEdit_FilePathQLineEdit
|
|
||||||
from moduels.component.Stream import Stream
|
|
||||||
from moduels.component.NormalValue import 常量
|
from moduels.component.NormalValue import 常量
|
||||||
from moduels.component.QEditBox_StdoutBox import QEditBox_StdoutBox
|
from moduels.component.QEditBox_StdoutBox import QEditBox_StdoutBox
|
||||||
# from moduels.component.SpaceLine import QHLine, QVLine
|
|
||||||
from moduels.thread.Thread_AliEngine import Thread_AliEngine
|
from moduels.thread.Thread_AliEngine import Thread_AliEngine
|
||||||
# from moduels.thread.Thread_GenerateSkins import Thread_GenerateSkins
|
|
||||||
# from moduels.thread.Thread_ExtractAllSkin import Thread_ExtractAllSkin
|
|
||||||
|
|
||||||
# from moduels.function.applyTemplate import applyTemplate
|
|
||||||
# from moduels.function.openSkinSourcePath import openSkinSourcePath
|
|
||||||
#
|
|
||||||
# from moduels.gui.Dialog_AddSkin import Dialog_AddSkin
|
|
||||||
# from moduels.gui.Dialog_DecompressSkin import Dialog_DecompressSkin
|
|
||||||
# from moduels.gui.Dialog_RestoreSkin import Dialog_RestoreSkin
|
|
||||||
# from moduels.gui.Group_EditableList import Group_EditableList
|
|
||||||
# from moduels.gui.VBox_RBtnContainer import VBox_RBtnContainer
|
|
||||||
from moduels.gui.Combo_EngineList import Combo_EngineList
|
from moduels.gui.Combo_EngineList import Combo_EngineList
|
||||||
|
|
||||||
|
|
||||||
@ -54,10 +41,10 @@ class Tab_CapsWriter(QWidget):
|
|||||||
self.停止按钮 = QPushButton('停止 CapsWriter')
|
self.停止按钮 = QPushButton('停止 CapsWriter')
|
||||||
self.启停按钮Box布局 = QHBoxLayout()
|
self.启停按钮Box布局 = QHBoxLayout()
|
||||||
|
|
||||||
self.标准输出流 = Stream()
|
|
||||||
|
|
||||||
def initLayouts(self):
|
def initLayouts(self):
|
||||||
self.标准输出流.newText.connect(self.更新控制台输出)
|
|
||||||
|
|
||||||
self.引擎选择Box布局.addWidget(self.引擎选择下拉框)
|
self.引擎选择Box布局.addWidget(self.引擎选择下拉框)
|
||||||
|
|
||||||
@ -85,10 +72,8 @@ class Tab_CapsWriter(QWidget):
|
|||||||
|
|
||||||
def initValues(self):
|
def initValues(self):
|
||||||
self.引擎线程 = None
|
self.引擎线程 = None
|
||||||
# self.aliClient = ali_speech.NlsClient()
|
|
||||||
# self.aliClient.set_log_level('WARNING') # 设置 client 输出日志信息的级别:DEBUG、INFO、WARNING、ERROR
|
|
||||||
self.停止按钮.setDisabled(True)
|
self.停止按钮.setDisabled(True)
|
||||||
sys.stdout = self.标准输出流
|
|
||||||
print("""\n软件介绍:
|
print("""\n软件介绍:
|
||||||
|
|
||||||
CapsWriter,顾名思义,就是按下大写锁定键来打字的工具。它的具体作用是:当你按下键盘上的大写锁定键后,软件开始语音识别,当你松开大写锁定键时,识别的结果就可以立马上屏。
|
CapsWriter,顾名思义,就是按下大写锁定键来打字的工具。它的具体作用是:当你按下键盘上的大写锁定键后,软件开始语音识别,当你松开大写锁定键时,识别的结果就可以立马上屏。
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import webbrowser
|
import webbrowser
|
||||||
from PySide2.QtCore import *
|
from PySide2.QtCore import Signal
|
||||||
from PySide2.QtGui import *
|
from PySide2.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QGridLayout, QGroupBox, QPushButton, QCheckBox
|
||||||
from PySide2.QtSql import *
|
|
||||||
from PySide2.QtWidgets import *
|
|
||||||
from moduels.component.NormalValue import 常量
|
from moduels.component.NormalValue import 常量
|
||||||
from moduels.gui.Group_EditableList import Group_EditableList
|
from moduels.gui.Group_EditableList import Group_EditableList
|
||||||
from moduels.gui.Dialog_AddEngine import Dialog_AddEngine
|
from moduels.gui.Dialog_AddEngine import Dialog_AddEngine
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtWidgets import QWidget, QPushButton, QVBoxLayout
|
||||||
from PySide2.QtCore import Signal
|
from PySide2.QtCore import Signal
|
||||||
from moduels.component.NormalValue import 常量
|
from moduels.component.NormalValue import 常量
|
||||||
from moduels.component.SponsorDialog import SponsorDialog
|
from moduels.component.SponsorDialog import SponsorDialog
|
||||||
|
@ -10,9 +10,8 @@ import time
|
|||||||
|
|
||||||
import ali_speech
|
import ali_speech
|
||||||
|
|
||||||
from PySide2.QtWidgets import *
|
from PySide2.QtCore import QThread, Signal
|
||||||
from PySide2.QtGui import *
|
from PySide2.QtWidgets import QApplication
|
||||||
from PySide2.QtCore import *
|
|
||||||
|
|
||||||
from moduels.component.NormalValue import 常量
|
from moduels.component.NormalValue import 常量
|
||||||
from moduels.function.getAlibabaRecognizer import getAlibabaRecognizer
|
from moduels.function.getAlibabaRecognizer import getAlibabaRecognizer
|
||||||
@ -40,6 +39,7 @@ class Thread_AliEngine(QThread):
|
|||||||
|
|
||||||
def __init__(self, 引擎名称, parent=None):
|
def __init__(self, 引擎名称, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
self.持续录音 = True
|
||||||
self.正在运行 = 0
|
self.正在运行 = 0
|
||||||
self.引擎名称 = 引擎名称
|
self.引擎名称 = 引擎名称
|
||||||
self.得到引擎信息()
|
self.得到引擎信息()
|
||||||
@ -98,7 +98,8 @@ class Thread_AliEngine(QThread):
|
|||||||
self.识别中 = True
|
self.识别中 = True
|
||||||
try:
|
try:
|
||||||
self.data = []
|
self.data = []
|
||||||
threading.Thread(target=self.录音线程, args=[self.p]).start() # 开始录音
|
if not self.持续录音: # 如果录音进程不是被持续开启着,那么就需要在这里主动开启
|
||||||
|
threading.Thread(target=self.录音线程, args=[self.p]).start() # 开始录音
|
||||||
threading.Thread(target=self.识别线程).start() # 开始识别
|
threading.Thread(target=self.识别线程).start() # 开始识别
|
||||||
|
|
||||||
except:
|
except:
|
||||||
@ -110,6 +111,7 @@ class Thread_AliEngine(QThread):
|
|||||||
else:
|
else:
|
||||||
# print(event.event_type)
|
# print(event.event_type)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def 为下一次输入准备识别器(self):
|
def 为下一次输入准备识别器(self):
|
||||||
self.识别器 = getAlibabaRecognizer(self.client,
|
self.识别器 = getAlibabaRecognizer(self.client,
|
||||||
self.appKey,
|
self.appKey,
|
||||||
@ -140,11 +142,20 @@ class Thread_AliEngine(QThread):
|
|||||||
rate=self.RATE,
|
rate=self.RATE,
|
||||||
input=True,
|
input=True,
|
||||||
frames_per_buffer=self.CHUNK)
|
frames_per_buffer=self.CHUNK)
|
||||||
|
if self.持续录音:
|
||||||
|
while self.isRunning():
|
||||||
|
if self.识别中:
|
||||||
|
self.录音数据存入内存(stream)
|
||||||
|
else:
|
||||||
|
stream.read(self.CHUNK)
|
||||||
|
else:
|
||||||
|
self.录音数据存入内存(stream)
|
||||||
|
|
||||||
# print('录制器准备完毕')
|
stream.stop_stream()# print('停止录制流')
|
||||||
# 录音写入序号 = 1
|
stream.close()
|
||||||
|
|
||||||
|
def 录音数据存入内存(self, stream):
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
# self.访问录音数据的线程锁.acquire()
|
|
||||||
if not self.识别中:
|
if not self.识别中:
|
||||||
self.data = []
|
self.data = []
|
||||||
# self.访问录音数据的线程锁.release()
|
# self.访问录音数据的线程锁.release()
|
||||||
@ -153,7 +164,6 @@ class Thread_AliEngine(QThread):
|
|||||||
self.data.append(stream.read(self.CHUNK))
|
self.data.append(stream.read(self.CHUNK))
|
||||||
# print(f'录音{录音写入序号},写入结束,时间 {time.time()}')
|
# print(f'录音{录音写入序号},写入结束,时间 {time.time()}')
|
||||||
# 录音写入序号 += 1
|
# 录音写入序号 += 1
|
||||||
# self.访问录音数据的线程锁.release()
|
|
||||||
# 在这里录下5个小片段,大约录制了0.32秒,如果这个时候松开了大写锁定键,就不打开连接。如果还继续按着,那就开始识别。
|
# 在这里录下5个小片段,大约录制了0.32秒,如果这个时候松开了大写锁定键,就不打开连接。如果还继续按着,那就开始识别。
|
||||||
|
|
||||||
while self.识别中:
|
while self.识别中:
|
||||||
@ -168,9 +178,6 @@ class Thread_AliEngine(QThread):
|
|||||||
self.总共写入音频片段数 = len(self.data)
|
self.总共写入音频片段数 = len(self.data)
|
||||||
# self.访问录音数据的线程锁.release()
|
# self.访问录音数据的线程锁.release()
|
||||||
self.发送大写锁定键() # 再按下大写锁定键,还原大写锁定
|
self.发送大写锁定键() # 再按下大写锁定键,还原大写锁定
|
||||||
stream.stop_stream()# print('停止录制流')
|
|
||||||
stream.close()
|
|
||||||
|
|
||||||
|
|
||||||
# 这边开始上传识别
|
# 这边开始上传识别
|
||||||
def 识别(self):
|
def 识别(self):
|
||||||
@ -250,6 +257,8 @@ class Thread_AliEngine(QThread):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
self.p = pyaudio.PyAudio() # 在 QThread 中引入 PyAudio 会使得 PySide2 图形界面阻塞
|
self.p = pyaudio.PyAudio() # 在 QThread 中引入 PyAudio 会使得 PySide2 图形界面阻塞
|
||||||
|
if self.持续录音:
|
||||||
|
threading.Thread(target=self.录音线程, args=[self.p]).start()
|
||||||
|
|
||||||
self.开始监听大写锁定键()
|
self.开始监听大写锁定键()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user