import sys from PyQt5.QtWidgets import ( QApplication, QWidget, QTabWidget, QVBoxLayout, QPushButton, QTextEdit, QHBoxLayout, QFileDialog, QTextBrowser, QGroupBox, QButtonGroup, QSlider, QComboBox, ) from PyQt5 import QtCore, QtWidgets from PyQt5.QtGui import QFont, QTextCursor from PyQt5.QtMultimedia import QMediaPlaylist from record import Record from component.player import Player from summary.infer import summary, summary_with_model from time import time, sleep import soundfile as sf class Tab1Widget(QWidget): def __init__(self, add_signal): super().__init__() self.text = '' self.add_signal = add_signal ## for player self.player = Player(self) self.playlist = ['/Users/user/Documents/HDC/RnD/Project/qt/resource/1. KsponSpeech_sample.wav'] self.selectedList = [0] self.playOption = QMediaPlaylist.Sequential wav, sr = sf.read(self.playlist[0]) self.playlist_data = [[wav, sr]] self.sound_prev = 0 self.initUI() self.record_thread = RecordWorker(self.add_signal) self.record_file_thread = FileRecordWorker(self.add_signal, self.playlist_data) self.btn_run.clicked.connect(self.clicked_run_btn) self.btn_stop.clicked.connect(self.clicked_stop_btn) self.btn_clear.clicked.connect(self.clicked_clear_btn) def initUI(self): self.btn_run = QPushButton('Run', self) self.btn_stop = QPushButton('Stop', self) self.btn_clear = QPushButton('Clear', self) self.tb = QTextEdit() self.tb.setReadOnly(True) self.tb.setAcceptRichText(True) font = QFont() font.setPointSize(80) self.tb.setFont(font) self.tb.setText(self.text) # Play Control self.gb = QGroupBox('Play Control') grp = QButtonGroup(self) play_button_layout = QHBoxLayout() play_button_text = ['Change', '▶','■'] # ['◀◀', '▶', '⏸', '▶▶', '■'] for i in range(len(play_button_text)): btn = QPushButton(play_button_text[i], self) grp.addButton(btn, i) play_button_layout.addWidget(btn) grp.buttonClicked[int].connect(self.clicked_play_btn) # Volume self.slider = QSlider(QtCore.Qt.Horizontal, self) self.slider.setRange(0,100) self.slider.setValue(50) self.slider.valueChanged[int].connect(self.volumeChanged) play_button_layout.addWidget(self.slider) self.gb.setLayout(play_button_layout) self.vbox = QVBoxLayout() self.vbox.addWidget(self.gb) self.vbox.addWidget(self.btn_run) self.vbox.addWidget(self.btn_stop) self.vbox.addWidget(self.btn_clear) self.vbox.addWidget(self.tb) self.setLayout(self.vbox) def clicked_run_btn(self): self.record_thread.start() # self.text += '\nrun!!\n' # self.tb.setText(self.text) # self.addText.emit(self.text) def clicked_play_btn(self, id): if id==0: #change self.changeList() elif id==1: #▶ self.player.play(self.playlist, self.selectedList[0], self.playOption) self.record_file_thread.start() elif id==2: #■ self.player.stop() self.record_file_thread.stop() def clicked_stop_btn(self): self.record_thread.stop() def clicked_clear_btn(self): # self.record_thread = RecordWorker(self.add_signal) self.record_thread.clear() self.add_signal.emit('') def volumeChanged(self): self.player.upateVolume(self.slider.value()) def clear_text_browser(self): self.text = '' # self.tb.setText(self.text) self.add_signal.emit('') def changeList(self): fname = QFileDialog.getOpenFileName(self, 'Select one file to open', './resource') if fname[0]: self.clear_text_browser() wav, sr = sf.read(fname[0]) self.playlist = [fname[0]] self.playlist_data = [[wav, sr]] self.record_file_thread = FileRecordWorker(self.add_signal, self.playlist_data) def updateMediaChanged(self, index): print('index:',index) pass # if index>=0: # self.table.selectRow(index) def updateDurationChanged(self, index, msec): print('index:',index, 'duration:', msec) # self.pbar = self.table.cellWidget(index, 1) # if self.pbar: # self.pbar.setRange(0, msec) def updatePositionChanged(self, index, msec): print('index:',index, 'position:', msec) # self.pbar = self.table.cellWidget(index, 1) # if self.pbar: # self.pbar.setValue(msec) class Tab2Widget(QWidget): def __init__(self): super().__init__() self.summary_model_idx = 0 self.initUI() self.btn_convert.clicked.connect(self.clicked_convert_btn) self.btn_open_file.clicked.connect(self.clicked_open_file_btn) self.btn_clear.clicked.connect(self.clicked_clear_btn) def initUI(self): self.grid = QHBoxLayout() self.btn_open_file = QPushButton('Open File') self.btn_clear = QPushButton('Clear') self.grid.addWidget(self.btn_open_file) self.grid.addWidget(self.btn_clear) self.combo = QComboBox(self) self.combo.addItems(["General", "Estate"]) self.combo.currentTextChanged.connect(self.on_combobox_func) self.grid.addWidget(self.combo) self.tb_source = QTextEdit() self.tb_source.setAcceptRichText(True) self.btn_convert = QPushButton('Convert', self) self.tb_convert = QTextBrowser() # self.tb_convert.setReadOnly(True) self.tb_convert.setAcceptRichText(True) font = QFont() font.setPointSize(80) self.tb_convert.setFont(font) # self.tb_convert.setSource(QtCore.QUrl.fromLocalFile("test2.html")) self.vbox = QVBoxLayout() self.vbox.addLayout(self.grid, 0) self.vbox.addWidget(self.tb_source, 1) self.vbox.addWidget(self.btn_convert, 2) self.vbox.addWidget(self.tb_convert, 3) self.setLayout(self.vbox) def on_combobox_func(self, text): if text == 'General': self.summary_model_idx = 0 else: self.summary_model_idx = 1 @QtCore.pyqtSlot(str) def update_source_text(self, content): self.tb_source.setText(content) def clicked_convert_btn(self): text = self.tb_source.toPlainText() # text = summary(text) text = summary_with_model(text, self.summary_model_idx) self.tb_convert.setText(text) def clicked_open_file_btn(self): fname = QFileDialog.getOpenFileName(self, 'Open file', './script') if fname[0]: f = open(fname[0], 'r') with f: data = f.read() self.tb_source.setText(data) def clicked_clear_btn(self): self.tb_source.setText("") class MyApp(QtWidgets.QMainWindow): addText = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(MyApp, self).__init__(parent) self.text = '' self.blank_cnt = 0 self.blank_max = 2 self.initUI() def initUI(self): self.tab1 = Tab1Widget(self.addText) self.tab2 = Tab2Widget() # tab1.addText.connect(tab2.update_source_text) # tab1.addText.connect(tab2.update_source_text) # self.addText.connect(tab2.update_source_text) self.addText.connect(self.update_text) tabs = QTabWidget() tabs.addTab(self.tab1, '음성 인식') tabs.addTab(self.tab2, '요약') self.setCentralWidget(tabs) # vbox = QVBoxLayout() # vbox.addWidget(tabs) # self.setLayout(vbox) self.setWindowTitle('BTS') self.setGeometry(300, 300, 900, 500) self.show() @QtCore.pyqtSlot(str) def update_text(self, content): if content == '': self.text = '' elif len(content) == 0 and len(self.text) and self.text[-1] != "\n": self.blank_cnt += 1 if self.blank_cnt >= self.blank_max: self.blank_cnt = 0 self.text += '\n' else: self.text += content self.tab1.tb.setText(self.text) self.tab1.tb.moveCursor(QTextCursor.End) self.tab2.tb_source.setText(self.text) self.tab2.tb_source.moveCursor(QTextCursor.End) def list_chunk(lst, n): return [lst[i:i+n] for i in range(0, len(lst), n)] class RecordWorker(QtCore.QThread): def __init__(self, add_signal): super().__init__() self.power = False self.record = Record() self.add_signal = add_signal def run(self): self.power = True while self.power == True: self.record.record_unit(self.add_signal.emit) # self.record.record_unit(self.add_signal.emit) def stop(self): self.power = False def clear(self): self.record.clear() class FileRecordWorker(QtCore.QThread): def __init__(self, add_signal, audio_data): super().__init__() self.power = False self.record = Record() self.add_signal = add_signal self.audio_data = audio_data def run(self): self.power = True sec = 1 audio, sr = self.audio_data[0] sample_list = list_chunk(audio, 16000 * sec) start_time = time() for idx, sample in enumerate(sample_list): if self.power: now = time() length = len(sample)/sr print('time = ', start_time + length + (idx+1), 'now = ', now, 'diff = ', (start_time + length + (idx+1)) - now) pivot = (start_time + length + (idx+1)) - now if pivot > 0: sleep(pivot) self.record.record_file(sample, self.add_signal.emit) def stop(self): self.power = False if __name__ == '__main__': app = QApplication(sys.argv) ex = MyApp() sys.exit(app.exec_())