demo.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. import sys
  2. from PyQt5.QtWidgets import (
  3. QApplication, QWidget, QTabWidget, QVBoxLayout,
  4. QPushButton, QTextEdit, QHBoxLayout, QFileDialog,
  5. QTextBrowser, QGroupBox, QButtonGroup, QSlider,
  6. QComboBox,
  7. )
  8. from PyQt5 import QtCore, QtWidgets
  9. from PyQt5.QtGui import QFont, QTextCursor
  10. from PyQt5.QtMultimedia import QMediaPlaylist
  11. from record import Record
  12. from component.player import Player
  13. from summary.infer import summary, summary_with_model
  14. from time import time, sleep
  15. import soundfile as sf
  16. class Tab1Widget(QWidget):
  17. def __init__(self, add_signal):
  18. super().__init__()
  19. self.text = ''
  20. self.add_signal = add_signal
  21. ## for player
  22. self.player = Player(self)
  23. self.playlist = ['/Users/user/Documents/HDC/RnD/Project/qt/resource/1. KsponSpeech_sample.wav']
  24. self.selectedList = [0]
  25. self.playOption = QMediaPlaylist.Sequential
  26. wav, sr = sf.read(self.playlist[0])
  27. self.playlist_data = [[wav, sr]]
  28. self.sound_prev = 0
  29. self.initUI()
  30. self.record_thread = RecordWorker(self.add_signal)
  31. self.record_file_thread = FileRecordWorker(self.add_signal, self.playlist_data)
  32. self.btn_run.clicked.connect(self.clicked_run_btn)
  33. self.btn_stop.clicked.connect(self.clicked_stop_btn)
  34. self.btn_clear.clicked.connect(self.clicked_clear_btn)
  35. def initUI(self):
  36. self.btn_run = QPushButton('Run', self)
  37. self.btn_stop = QPushButton('Stop', self)
  38. self.btn_clear = QPushButton('Clear', self)
  39. self.tb = QTextEdit()
  40. self.tb.setReadOnly(True)
  41. self.tb.setAcceptRichText(True)
  42. font = QFont()
  43. font.setPointSize(80)
  44. self.tb.setFont(font)
  45. self.tb.setText(self.text)
  46. # Play Control
  47. self.gb = QGroupBox('Play Control')
  48. grp = QButtonGroup(self)
  49. play_button_layout = QHBoxLayout()
  50. play_button_text = ['Change', '▶','■'] # ['◀◀', '▶', '⏸', '▶▶', '■']
  51. for i in range(len(play_button_text)):
  52. btn = QPushButton(play_button_text[i], self)
  53. grp.addButton(btn, i)
  54. play_button_layout.addWidget(btn)
  55. grp.buttonClicked[int].connect(self.clicked_play_btn)
  56. # Volume
  57. self.slider = QSlider(QtCore.Qt.Horizontal, self)
  58. self.slider.setRange(0,100)
  59. self.slider.setValue(50)
  60. self.slider.valueChanged[int].connect(self.volumeChanged)
  61. play_button_layout.addWidget(self.slider)
  62. self.gb.setLayout(play_button_layout)
  63. self.vbox = QVBoxLayout()
  64. self.vbox.addWidget(self.gb)
  65. self.vbox.addWidget(self.btn_run)
  66. self.vbox.addWidget(self.btn_stop)
  67. self.vbox.addWidget(self.btn_clear)
  68. self.vbox.addWidget(self.tb)
  69. self.setLayout(self.vbox)
  70. def clicked_run_btn(self):
  71. self.record_thread.start()
  72. # self.text += '\nrun!!\n'
  73. # self.tb.setText(self.text)
  74. # self.addText.emit(self.text)
  75. def clicked_play_btn(self, id):
  76. if id==0: #change
  77. self.changeList()
  78. elif id==1: #▶
  79. self.player.play(self.playlist, self.selectedList[0], self.playOption)
  80. self.record_file_thread.start()
  81. elif id==2: #■
  82. self.player.stop()
  83. self.record_file_thread.stop()
  84. def clicked_stop_btn(self):
  85. self.record_thread.stop()
  86. def clicked_clear_btn(self):
  87. # self.record_thread = RecordWorker(self.add_signal)
  88. self.record_thread.clear()
  89. self.add_signal.emit('<cls>')
  90. def volumeChanged(self):
  91. self.player.upateVolume(self.slider.value())
  92. def clear_text_browser(self):
  93. self.text = ''
  94. # self.tb.setText(self.text)
  95. self.add_signal.emit('<cls>')
  96. def changeList(self):
  97. fname = QFileDialog.getOpenFileName(self, 'Select one file to open', './resource')
  98. if fname[0]:
  99. self.clear_text_browser()
  100. wav, sr = sf.read(fname[0])
  101. self.playlist = [fname[0]]
  102. self.playlist_data = [[wav, sr]]
  103. self.record_file_thread = FileRecordWorker(self.add_signal, self.playlist_data)
  104. def updateMediaChanged(self, index):
  105. print('index:',index)
  106. pass
  107. # if index>=0:
  108. # self.table.selectRow(index)
  109. def updateDurationChanged(self, index, msec):
  110. print('index:',index, 'duration:', msec)
  111. # self.pbar = self.table.cellWidget(index, 1)
  112. # if self.pbar:
  113. # self.pbar.setRange(0, msec)
  114. def updatePositionChanged(self, index, msec):
  115. print('index:',index, 'position:', msec)
  116. # self.pbar = self.table.cellWidget(index, 1)
  117. # if self.pbar:
  118. # self.pbar.setValue(msec)
  119. class Tab2Widget(QWidget):
  120. def __init__(self):
  121. super().__init__()
  122. self.summary_model_idx = 0
  123. self.initUI()
  124. self.btn_convert.clicked.connect(self.clicked_convert_btn)
  125. self.btn_open_file.clicked.connect(self.clicked_open_file_btn)
  126. self.btn_clear.clicked.connect(self.clicked_clear_btn)
  127. def initUI(self):
  128. self.grid = QHBoxLayout()
  129. self.btn_open_file = QPushButton('Open File')
  130. self.btn_clear = QPushButton('Clear')
  131. self.grid.addWidget(self.btn_open_file)
  132. self.grid.addWidget(self.btn_clear)
  133. self.combo = QComboBox(self)
  134. self.combo.addItems(["General", "Estate"])
  135. self.combo.currentTextChanged.connect(self.on_combobox_func)
  136. self.grid.addWidget(self.combo)
  137. self.tb_source = QTextEdit()
  138. self.tb_source.setAcceptRichText(True)
  139. self.btn_convert = QPushButton('Convert', self)
  140. self.tb_convert = QTextBrowser()
  141. # self.tb_convert.setReadOnly(True)
  142. self.tb_convert.setAcceptRichText(True)
  143. font = QFont()
  144. font.setPointSize(80)
  145. self.tb_convert.setFont(font)
  146. # self.tb_convert.setSource(QtCore.QUrl.fromLocalFile("test2.html"))
  147. self.vbox = QVBoxLayout()
  148. self.vbox.addLayout(self.grid, 0)
  149. self.vbox.addWidget(self.tb_source, 1)
  150. self.vbox.addWidget(self.btn_convert, 2)
  151. self.vbox.addWidget(self.tb_convert, 3)
  152. self.setLayout(self.vbox)
  153. def on_combobox_func(self, text):
  154. if text == 'General':
  155. self.summary_model_idx = 0
  156. else:
  157. self.summary_model_idx = 1
  158. @QtCore.pyqtSlot(str)
  159. def update_source_text(self, content):
  160. self.tb_source.setText(content)
  161. def clicked_convert_btn(self):
  162. text = self.tb_source.toPlainText()
  163. # text = summary(text)
  164. text = summary_with_model(text, self.summary_model_idx)
  165. self.tb_convert.setText(text)
  166. def clicked_open_file_btn(self):
  167. fname = QFileDialog.getOpenFileName(self, 'Open file', './script')
  168. if fname[0]:
  169. f = open(fname[0], 'r')
  170. with f:
  171. data = f.read()
  172. self.tb_source.setText(data)
  173. def clicked_clear_btn(self):
  174. self.tb_source.setText("")
  175. class MyApp(QtWidgets.QMainWindow):
  176. addText = QtCore.pyqtSignal(str)
  177. def __init__(self, parent=None):
  178. super(MyApp, self).__init__(parent)
  179. self.text = ''
  180. self.blank_cnt = 0
  181. self.blank_max = 2
  182. self.initUI()
  183. def initUI(self):
  184. self.tab1 = Tab1Widget(self.addText)
  185. self.tab2 = Tab2Widget()
  186. # tab1.addText.connect(tab2.update_source_text)
  187. # tab1.addText.connect(tab2.update_source_text)
  188. # self.addText.connect(tab2.update_source_text)
  189. self.addText.connect(self.update_text)
  190. tabs = QTabWidget()
  191. tabs.addTab(self.tab1, '음성 인식')
  192. tabs.addTab(self.tab2, '요약')
  193. self.setCentralWidget(tabs)
  194. # vbox = QVBoxLayout()
  195. # vbox.addWidget(tabs)
  196. # self.setLayout(vbox)
  197. self.setWindowTitle('BTS')
  198. self.setGeometry(300, 300, 900, 500)
  199. self.show()
  200. @QtCore.pyqtSlot(str)
  201. def update_text(self, content):
  202. if content == '<cls>':
  203. self.text = ''
  204. elif len(content) == 0 and len(self.text) and self.text[-1] != "\n":
  205. self.blank_cnt += 1
  206. if self.blank_cnt >= self.blank_max:
  207. self.blank_cnt = 0
  208. self.text += '\n'
  209. else:
  210. self.text += content
  211. self.tab1.tb.setText(self.text)
  212. self.tab1.tb.moveCursor(QTextCursor.End)
  213. self.tab2.tb_source.setText(self.text)
  214. self.tab2.tb_source.moveCursor(QTextCursor.End)
  215. def list_chunk(lst, n):
  216. return [lst[i:i+n] for i in range(0, len(lst), n)]
  217. class RecordWorker(QtCore.QThread):
  218. def __init__(self, add_signal):
  219. super().__init__()
  220. self.power = False
  221. self.record = Record()
  222. self.add_signal = add_signal
  223. def run(self):
  224. self.power = True
  225. while self.power == True:
  226. self.record.record_unit(self.add_signal.emit)
  227. # self.record.record_unit(self.add_signal.emit)
  228. def stop(self):
  229. self.power = False
  230. def clear(self):
  231. self.record.clear()
  232. class FileRecordWorker(QtCore.QThread):
  233. def __init__(self, add_signal, audio_data):
  234. super().__init__()
  235. self.power = False
  236. self.record = Record()
  237. self.add_signal = add_signal
  238. self.audio_data = audio_data
  239. def run(self):
  240. self.power = True
  241. sec = 1
  242. audio, sr = self.audio_data[0]
  243. sample_list = list_chunk(audio, 16000 * sec)
  244. start_time = time()
  245. for idx, sample in enumerate(sample_list):
  246. if self.power:
  247. now = time()
  248. length = len(sample)/sr
  249. print('time = ', start_time + length + (idx+1), 'now = ', now, 'diff = ', (start_time + length + (idx+1)) - now)
  250. pivot = (start_time + length + (idx+1)) - now
  251. if pivot > 0:
  252. sleep(pivot)
  253. self.record.record_file(sample, self.add_signal.emit)
  254. def stop(self):
  255. self.power = False
  256. if __name__ == '__main__':
  257. app = QApplication(sys.argv)
  258. ex = MyApp()
  259. sys.exit(app.exec_())