# -*- coding: utf-8 -*-
import io
import sys
import threading
import time
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import numpy as np
import cv2
from ui import Ui_Dialog
import sounddevice as sd
import soundfile as sf
import queue
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(100, 100)
self.label_5 = QtWidgets.QLabel(Dialog)
self.label_5.setGeometry(QtCore.QRect(0, 0, 100, 100))
self.label_5.setText("")
self.label_5.setPixmap(QtGui.QPixmap("pic/record.gif"))
self.label_5.setScaledContents(True)
self.label_5.setObjectName("label_5")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "发音检测"))
# qt线程 录音
class Worker(QThread):
# 定义信号
_signal = pyqtSignal(str)
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
self.isStart = False
# 播放
def play(self):
event = threading.Event()
data, fs = sf.read("test.wav", always_2d=True)
current_frame = 0
def callback(outdata, frames, time, status):
global current_frame
if status:
print(status)
chunksize = min(len(data) - current_frame, frames)
outdata[:chunksize] = data[current_frame:current_frame + chunksize]
if chunksize < frames:
outdata[chunksize:] = 0
raise sd.CallbackStop()
current_frame += chunksize
stream = sd.OutputStream(
samplerate=fs, device=None, channels=data.shape[1],
callback=callback, finished_callback=event.set)
with stream:
event.wait() # Wait until playback is finished
def stop(self):
print("停止录音")
self.isStart = False
def run(self):
# 开始录音
self.isStart = True
q = queue.Queue()
def callback(indata, frames, time, status):
"""This is called (from a separate thread) for each audio block."""
if status:
print(status, file=sys.stderr)
q.put(indata.copy())
# soundfile expects an int, sounddevice provides a float:
samplerate = 16000
channels = 1
# Make sure the file is opened before recording anything:
with sf.SoundFile("test.wav", mode='w', samplerate=samplerate,channels=channels) as file:
with sd.InputStream(samplerate=samplerate, device=None,channels=channels, callback=callback):
self._signal.emit("开始录音")
while self.isStart:
file.write(q.get())
# 停止录音
self._signal.emit("录音线程结束")
class mwindow(QWidget, Ui_Dialog):
def __init__(self):
super(mwindow, self).__init__()
self.setupUi(self)
self.flag = 0
# 创建线程对象
self.thread_obj = Worker()
# 将信号与槽连接
self.thread_obj._signal.connect(self.set_btn)
# 信号带参回传
def set_btn(self,a):
print(a)
# 设置可点击
self.label_5.setEnabled(True)
# 鼠标松开事件
def mouseReleaseEvent(self, event):
# 获取鼠标松开的坐标
x = event.x()
y = event.y()
# 鼠标松开的对象
label = self.childAt(x, y)
# 判断鼠标松开的对象是否为label
if isinstance(label, QLabel):
# 获取label的名字
name = label.objectName()
if name=="label_5":
# 设置不可点击
self.label_5.setEnabled(False)
# 判断是否为第一次按下
if self.flag==0:
# 更换图片
label.setPixmap(QPixmap("pic/stop.gif"))
# 开启线程
self.thread_obj.start()
# 设置标志位为1
self.flag = 1
else:
# 更换图片
label.setPixmap(QPixmap("pic/record.gif"))
self.thread_obj.stop()
self.flag=0
if __name__ == '__main__':
app=QApplication(sys.argv)
#初始化窗口
m=mwindow()
m.show()
sys.exit(app.exec_())
pyqt5多线程实现录音
最新推荐文章于 2022-07-08 18:31:56 发布
该博客介绍了一个使用PyQt5和相关库实现的录音和播放功能的应用。应用中包含一个UI对话框,当点击特定按钮时,会启动录音线程,并在完成时切换到播放状态。录音线程利用sounddevice和soundfile库进行音频输入和输出,通过Qt线程保证了界面的响应性。
摘要由CSDN通过智能技术生成