4
4
import logging
5
5
import os
6
6
import platform
7
- import random
8
7
import sys
9
8
from datetime import datetime
10
9
from enum import auto
11
- from typing import Dict , List , Optional , Tuple , Union
10
+ from typing import Dict , List , Optional , Tuple
12
11
13
12
import humanize
14
13
import sounddevice
33
32
from .recording import RecordingAmplitudeListener
34
33
from .transcriber import (SUPPORTED_OUTPUT_FORMATS , FileTranscriptionOptions , OutputFormat ,
35
34
Task ,
36
- WhisperCppFileTranscriber , WhisperFileTranscriber ,
37
35
get_default_output_file_path , segments_to_text , write_output , TranscriptionOptions ,
38
36
FileTranscriberQueueWorker , FileTranscriptionTask , RecordingTranscriber , LOADED_WHISPER_DLL )
39
37
@@ -217,24 +215,23 @@ def show_model_download_error_dialog(parent: QWidget, error: str):
217
215
218
216
class FileTranscriberWidget (QWidget ):
219
217
model_download_progress_dialog : Optional [DownloadModelProgressDialog ] = None
220
- file_transcriber : Optional [Union [WhisperFileTranscriber ,
221
- WhisperCppFileTranscriber ]] = None
222
218
model_loader : Optional [ModelLoader ] = None
223
219
transcriber_thread : Optional [QThread ] = None
224
220
file_transcription_options : FileTranscriptionOptions
225
221
transcription_options : TranscriptionOptions
226
222
is_transcribing = False
227
223
# (TranscriptionOptions, FileTranscriptionOptions, str)
228
224
triggered = pyqtSignal (tuple )
225
+ openai_access_token_changed = pyqtSignal (str )
229
226
230
- def __init__ (self , file_paths : List [str ], parent : Optional [QWidget ] = None ,
231
- flags : Qt .WindowType = Qt .WindowType .Widget ) -> None :
227
+ def __init__ (self , file_paths : List [str ], openai_access_token : Optional [str ] = None ,
228
+ parent : Optional [ QWidget ] = None , flags : Qt .WindowType = Qt .WindowType .Widget ) -> None :
232
229
super ().__init__ (parent , flags )
233
230
234
231
self .setWindowTitle (file_paths_as_title (file_paths ))
235
232
236
233
self .file_paths = file_paths
237
- self .transcription_options = TranscriptionOptions ()
234
+ self .transcription_options = TranscriptionOptions (openai_access_token = openai_access_token )
238
235
self .file_transcription_options = FileTranscriptionOptions (
239
236
file_paths = self .file_paths )
240
237
@@ -266,7 +263,9 @@ def __init__(self, file_paths: List[str], parent: Optional[QWidget] = None,
266
263
def on_transcription_options_changed (self , transcription_options : TranscriptionOptions ):
267
264
self .transcription_options = transcription_options
268
265
self .word_level_timings_checkbox .setDisabled (
269
- self .transcription_options .model .model_type == ModelType .HUGGING_FACE )
266
+ self .transcription_options .model .model_type == ModelType .HUGGING_FACE or self .transcription_options .model .model_type == ModelType .OPEN_AI_WHISPER_API )
267
+ if self .transcription_options .openai_access_token is not None :
268
+ self .openai_access_token_changed .emit (self .transcription_options .openai_access_token )
270
269
271
270
def on_click_run (self ):
272
271
self .run_button .setDisabled (True )
@@ -503,7 +502,10 @@ def __init__(self, parent: Optional[QWidget] = None, flags: Optional[Qt.WindowTy
503
502
self .text_box .setPlaceholderText (_ ('Click Record to begin...' ))
504
503
505
504
transcription_options_group_box = TranscriptionOptionsGroupBox (
506
- default_transcription_options = self .transcription_options , parent = self )
505
+ default_transcription_options = self .transcription_options ,
506
+ # Live transcription with OpenAI Whisper API not implemented
507
+ model_types = [model_type for model_type in ModelType if model_type is not ModelType .OPEN_AI_WHISPER_API ],
508
+ parent = self )
507
509
transcription_options_group_box .transcription_options_changed .connect (
508
510
self .on_transcription_options_changed )
509
511
@@ -820,7 +822,7 @@ def upsert_task(self, task: FileTranscriptionTask):
820
822
elif task .status == FileTranscriptionTask .Status .COMPLETED :
821
823
status_widget .setText (_ ('Completed' ))
822
824
elif task .status == FileTranscriptionTask .Status .FAILED :
823
- status_widget .setText (_ ( ' Failed' ) )
825
+ status_widget .setText (f' { _ ( " Failed" ) } ( { task . error } )' )
824
826
elif task .status == FileTranscriptionTask .Status .CANCELED :
825
827
status_widget .setText (_ ('Canceled' ))
826
828
@@ -925,6 +927,7 @@ class MainWindow(QMainWindow):
925
927
table_widget : TranscriptionTasksTableWidget
926
928
tasks : Dict [int , 'FileTranscriptionTask' ]
927
929
tasks_changed = pyqtSignal ()
930
+ openai_access_token : Optional [str ] = None
928
931
929
932
def __init__ (self , tasks_cache = TasksCache ()):
930
933
super ().__init__ (flags = Qt .WindowType .Window )
@@ -1026,11 +1029,17 @@ def on_new_transcription_action_triggered(self):
1026
1029
return
1027
1030
1028
1031
file_transcriber_window = FileTranscriberWidget (
1029
- file_paths , self , flags = Qt .WindowType .Window )
1032
+ file_paths , self . openai_access_token , self , flags = Qt .WindowType .Window )
1030
1033
file_transcriber_window .triggered .connect (
1031
1034
self .on_file_transcriber_triggered )
1035
+ file_transcriber_window .openai_access_token_changed .connect (self .on_openai_access_token_changed )
1032
1036
file_transcriber_window .show ()
1033
1037
1038
+ # Save the access token on the main window so the user doesn't need to re-enter (at least, not while the app is
1039
+ # still open)
1040
+ def on_openai_access_token_changed (self , access_token : str ):
1041
+ self .openai_access_token = access_token
1042
+
1034
1043
def on_open_transcript_action_triggered (self ):
1035
1044
selected_rows = self .table_widget .selectionModel ().selectedRows ()
1036
1045
for selected_row in selected_rows :
@@ -1092,6 +1101,7 @@ def on_tasks_changed(self):
1092
1101
self .toolbar .set_open_transcript_action_enabled (self .should_enable_open_transcript_action ())
1093
1102
self .toolbar .set_stop_transcription_action_enabled (self .should_enable_stop_transcription_action ())
1094
1103
self .toolbar .set_clear_history_action_enabled (self .should_enable_clear_history_action ())
1104
+ self .save_tasks_to_cache ()
1095
1105
1096
1106
def closeEvent (self , event : QtGui .QCloseEvent ) -> None :
1097
1107
self .transcriber_worker .stop ()
@@ -1236,6 +1246,7 @@ class TranscriptionOptionsGroupBox(QGroupBox):
1236
1246
transcription_options_changed = pyqtSignal (TranscriptionOptions )
1237
1247
1238
1248
def __init__ (self , default_transcription_options : TranscriptionOptions = TranscriptionOptions (),
1249
+ model_types : Optional [List [ModelType ]] = None ,
1239
1250
parent : Optional [QWidget ] = None ):
1240
1251
super ().__init__ (title = '' , parent = parent )
1241
1252
self .transcription_options = default_transcription_options
@@ -1261,7 +1272,9 @@ def __init__(self, default_transcription_options: TranscriptionOptions = Transcr
1261
1272
self .hugging_face_search_line_edit .model_selected .connect (self .on_hugging_face_model_changed )
1262
1273
1263
1274
self .model_type_combo_box = QComboBox (self )
1264
- for model_type in ModelType :
1275
+ if model_types is None :
1276
+ model_types = [model_type for model_type in ModelType ]
1277
+ for model_type in model_types :
1265
1278
# Hide Whisper.cpp option is whisper.dll did not load correctly.
1266
1279
# See: https://github.com/chidiwilliams/buzz/issues/274, https://github.com/chidiwilliams/buzz/issues/197
1267
1280
if model_type == ModelType .WHISPER_CPP and LOADED_WHISPER_DLL is False :
@@ -1277,18 +1290,28 @@ def __init__(self, default_transcription_options: TranscriptionOptions = Transcr
1277
1290
default_transcription_options .model .whisper_model_size .value .title ())
1278
1291
self .whisper_model_size_combo_box .currentTextChanged .connect (self .on_whisper_model_size_changed )
1279
1292
1280
- self .form_layout .addRow (_ ('Task:' ), self .tasks_combo_box )
1281
- self .form_layout .addRow (_ ('Language:' ), self .languages_combo_box )
1293
+ self .openai_access_token_edit = QLineEdit (self )
1294
+ self .openai_access_token_edit .setText (default_transcription_options .openai_access_token )
1295
+ self .openai_access_token_edit .setEchoMode (QLineEdit .EchoMode .Password )
1296
+ self .openai_access_token_edit .textChanged .connect (self .on_openai_access_token_edit_changed )
1297
+
1282
1298
self .form_layout .addRow (_ ('Model:' ), self .model_type_combo_box )
1283
1299
self .form_layout .addRow ('' , self .whisper_model_size_combo_box )
1284
1300
self .form_layout .addRow ('' , self .hugging_face_search_line_edit )
1301
+ self .form_layout .addRow ('Access Token:' , self .openai_access_token_edit )
1302
+ self .form_layout .addRow (_ ('Task:' ), self .tasks_combo_box )
1303
+ self .form_layout .addRow (_ ('Language:' ), self .languages_combo_box )
1285
1304
1286
- self .form_layout . setRowVisible ( self . hugging_face_search_line_edit , False )
1305
+ self .reset_visible_rows ( )
1287
1306
1288
1307
self .form_layout .addRow ('' , self .advanced_settings_button )
1289
1308
1290
1309
self .setLayout (self .form_layout )
1291
1310
1311
+ def on_openai_access_token_edit_changed (self , access_token : str ):
1312
+ self .transcription_options .openai_access_token = access_token
1313
+ self .transcription_options_changed .emit (self .transcription_options )
1314
+
1292
1315
def on_language_changed (self , language : str ):
1293
1316
self .transcription_options .language = language
1294
1317
self .transcription_options_changed .emit (self .transcription_options )
@@ -1316,12 +1339,17 @@ def on_transcription_options_changed(self, transcription_options: TranscriptionO
1316
1339
self .transcription_options = transcription_options
1317
1340
self .transcription_options_changed .emit (transcription_options )
1318
1341
1319
- def on_model_type_changed (self , text : str ):
1320
- model_type = ModelType ( text )
1342
+ def reset_visible_rows (self ):
1343
+ model_type = self . transcription_options . model . model_type
1321
1344
self .form_layout .setRowVisible (self .hugging_face_search_line_edit , model_type == ModelType .HUGGING_FACE )
1322
1345
self .form_layout .setRowVisible (self .whisper_model_size_combo_box ,
1323
1346
(model_type == ModelType .WHISPER ) or (model_type == ModelType .WHISPER_CPP ))
1347
+ self .form_layout .setRowVisible (self .openai_access_token_edit , model_type == ModelType .OPEN_AI_WHISPER_API )
1348
+
1349
+ def on_model_type_changed (self , text : str ):
1350
+ model_type = ModelType (text )
1324
1351
self .transcription_options .model .model_type = model_type
1352
+ self .reset_visible_rows ()
1325
1353
self .transcription_options_changed .emit (self .transcription_options )
1326
1354
1327
1355
def on_whisper_model_size_changed (self , text : str ):
0 commit comments