From 725031ebb83f887e8bb7745310882d1d725f9904 Mon Sep 17 00:00:00 2001 From: Raivis Dejus Date: Tue, 5 Nov 2024 19:41:26 +0200 Subject: [PATCH] Adding Core ML support for WhisperCpp (#976) This also changes how models for Whisper.cpp are downloaded. After update of the app models will need to be re-downloaded if you have them already downloaded. --- .gitignore | 2 + Buzz.spec | 4 + Makefile | 18 ++ buzz/assets/info-circle.svg | 6 + buzz/locale/ca_ES/LC_MESSAGES/buzz.po | 72 ++++--- buzz/locale/es_ES/LC_MESSAGES/buzz.po | 72 ++++--- buzz/locale/it_IT/LC_MESSAGES/buzz.po | 64 +++--- buzz/locale/ja_JP/LC_MESSAGES/buzz.po | 72 ++++--- buzz/locale/lv_LV/LC_MESSAGES/buzz.po | 74 +++---- buzz/locale/pl_PL/LC_MESSAGES/buzz.po | 72 ++++--- buzz/locale/uk_UA/LC_MESSAGES/buzz.po | 72 ++++--- buzz/locale/zh_CN/LC_MESSAGES/buzz.po | 72 ++++--- buzz/locale/zh_TW/LC_MESSAGES/buzz.po | 72 ++++--- buzz/model_loader.py | 86 +++++--- buzz/transcriber/recording_transcriber.py | 28 +-- buzz/transcriber/whisper_cpp.py | 196 ++++++++++++++---- .../whisper_cpp_file_transcriber.py | 23 +- buzz/widgets/icon.py | 1 + .../general_preferences_widget.py | 1 + .../models_preferences_widget.py | 1 + .../hugging_face_search_line_edit.py | 2 +- .../transcription_options_group_box.py | 40 +++- pyproject.toml | 2 +- tests/transcriber/whisper_cpp_test.py | 4 +- 24 files changed, 655 insertions(+), 401 deletions(-) create mode 100644 buzz/assets/info-circle.svg diff --git a/.gitignore b/.gitignore index 0223b70ff..6224dd8f4 100644 --- a/.gitignore +++ b/.gitignore @@ -12,10 +12,12 @@ coverage.xml # whisper_cpp libwhisper.* +libwhisper-coreml.* whisper_cpp whisper_cpp.exe whisper.dll buzz/whisper_cpp.py +buzz/whisper_cpp_coreml.py # Internationalization - compiled binaries *.mo diff --git a/Buzz.spec b/Buzz.spec index 06471327b..fbbe2a69d 100644 --- a/Buzz.spec +++ b/Buzz.spec @@ -47,6 +47,10 @@ binaries = [ (shutil.which("ffprobe"), "."), ] +# Include libwhisper-coreml.dylib on Apple Silicon +if platform.system() == "Darwin" and platform.machine() == "arm64": + binaries.append(("buzz/libwhisper-coreml.dylib", ".")) + # Include dll_backup folder and its contents on Windows if platform.system() == "Windows": datas += [("dll_backup", "dll_backup")] diff --git a/Makefile b/Makefile index 7e9edda72..0b1f78029 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ bundle_mac: dist/Buzz.app codesign_all_mac zip_mac notarize_zip staple_app_mac d bundle_mac_unsigned: dist/Buzz.app zip_mac dmg_mac_unsigned UNAME_S := $(shell uname -s) +UNAME_M := $(shell uname -m) LIBWHISPER := ifeq ($(OS), Windows_NT) @@ -38,6 +39,8 @@ ifeq ($(OS), Windows_NT) else rm -f buzz/$(LIBWHISPER) rm -f buzz/whisper_cpp.py + rm -f buzz/libwhisper-coreml.dylib || true + rm -f buzz/whisper_cpp_coreml.py || true rm -rf whisper.cpp/build || true rm -rf dist/* || true endif @@ -88,9 +91,24 @@ else cp whisper.cpp/build/bin/Debug/$(LIBWHISPER) buzz || true cp whisper.cpp/build/$(LIBWHISPER) buzz || true endif +# Build CoreML support on ARM Macs +ifeq ($(shell uname -m), arm64) +ifeq ($(shell uname -s), Darwin) + rm -rf whisper.cpp/build || true + cmake -S whisper.cpp -B whisper.cpp/build/ $(CMAKE_FLAGS) -DWHISPER_COREML=1 + cmake --build whisper.cpp/build --verbose + cp whisper.cpp/build/bin/Debug/$(LIBWHISPER) buzz/libwhisper-coreml.dylib || true + cp whisper.cpp/build/$(LIBWHISPER) buzz/libwhisper-coreml.dylib || true +endif +endif buzz/whisper_cpp.py: buzz/$(LIBWHISPER) translation_mo cd buzz && ctypesgen ../whisper.cpp/whisper.h -lwhisper -o whisper_cpp.py +ifeq ($(shell uname -m), arm64) +ifeq ($(shell uname -s), Darwin) + cd buzz && ctypesgen ../whisper.cpp/whisper.h -lwhisper-coreml -o whisper_cpp_coreml.py +endif +endif # Prints all the Mac developer identities used for code signing print_identities_mac: diff --git a/buzz/assets/info-circle.svg b/buzz/assets/info-circle.svg new file mode 100644 index 000000000..b1b4d2f3a --- /dev/null +++ b/buzz/assets/info-circle.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/buzz/locale/ca_ES/LC_MESSAGES/buzz.po b/buzz/locale/ca_ES/LC_MESSAGES/buzz.po index 65b19e819..a4a79d71f 100644 --- a/buzz/locale/ca_ES/LC_MESSAGES/buzz.po +++ b/buzz/locale/ca_ES/LC_MESSAGES/buzz.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: buzz\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-18 08:41+0300\n" +"POT-Creation-Date: 2024-11-03 08:32+0200\n" "PO-Revision-Date: 2023-02-15 05:01+0000\n" "Last-Translator: Jordi Mas i Hernàndez \n" "Language-Team: Catalan \n" @@ -26,7 +26,7 @@ msgstr "" #: buzz/widgets/import_url_dialog.py:28 #: buzz/widgets/preferences_dialog/preferences_dialog.py:69 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:244 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 #: buzz/widgets/transcriber/advanced_settings_dialog.py:97 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:295 #: buzz/widgets/main_window.py:234 @@ -35,7 +35,7 @@ msgstr "" #: buzz/widgets/import_url_dialog.py:29 #: buzz/widgets/preferences_dialog/preferences_dialog.py:70 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:246 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:296 #: buzz/widgets/model_download_progress_dialog.py:29 #: buzz/widgets/main_window.py:235 @@ -63,67 +63,67 @@ msgstr "" msgid "Font Size" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:60 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:61 msgid "Test" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:66 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:67 msgid "OpenAI API key" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:79 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:80 msgid "OpenAI base url" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:88 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:89 msgid "Default export file name" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:94 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:95 msgid "Enable live recording transcription export" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:100 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:101 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 msgid "Browse" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:119 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:120 msgid "Export folder" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:130 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:131 #, fuzzy msgid "Live recording mode" msgstr "Enregistrament en viu" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:155 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:161 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:162 msgid "OpenAI API Key Test" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:157 msgid "" "Your API key is valid. Buzz will use this key to perform Whisper API " "transcriptions and AI translations." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:172 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 msgid "Invalid API key" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:174 msgid "" "API supports only base64 characters (A-Za-z0-9+/=). Other characters in API " "key may cause errors." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:191 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:192 msgid "Select Export Folder" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:243 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:244 msgid "" "OpenAI API returned invalid response. Please check the API url or your key. " "Transcription and translation may still work if the API does not support key " @@ -180,45 +180,45 @@ msgstr "" msgid "Huggingface ID of a Faster whisper model" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:93 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:94 msgid "Download" msgstr "Baixada" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:98 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:99 msgid "Show file location" msgstr "Mostra la ubicació del fitxer" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:106 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:107 msgid "Delete" msgstr "Suprimeix" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:137 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:138 msgid "Downloaded" msgstr "Baixat" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:142 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:143 msgid "Available for Download" msgstr "Disponible per baixar" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:163 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:164 msgid "Download link to Whisper.cpp ggml model file" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:238 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 msgid "Delete Model" msgstr "Suprimeix el model" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:240 msgid "Are you sure you want to delete the selected model?" msgstr "Esteu segur que voleu suprimir el model seleccionat?" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:267 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 #, fuzzy msgid "Download failed" msgstr "Baixat" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 -#: buzz/widgets/main_window.py:291 buzz/model_loader.py:473 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:269 +#: buzz/widgets/main_window.py:291 buzz/model_loader.py:503 msgid "Error" msgstr "Error" @@ -240,19 +240,23 @@ msgstr "Detecta l'idioma" msgid "Run" msgstr "Executa" -#: buzz/widgets/transcriber/transcription_options_group_box.py:88 +#: buzz/widgets/transcriber/transcription_options_group_box.py:92 msgid "Model:" msgstr "Model:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:91 +#: buzz/widgets/transcriber/transcription_options_group_box.py:104 +msgid "First time use of a model may take up to several minutest to load." +msgstr "" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:113 msgid "Api Key:" msgstr "" -#: buzz/widgets/transcriber/transcription_options_group_box.py:92 +#: buzz/widgets/transcriber/transcription_options_group_box.py:114 msgid "Task:" msgstr "Tasca:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:93 +#: buzz/widgets/transcriber/transcription_options_group_box.py:115 msgid "Language:" msgstr "Idioma:" @@ -560,7 +564,7 @@ msgstr "" msgid "Transcribe" msgstr "Obre una transcripció" -#: buzz/model_loader.py:502 +#: buzz/model_loader.py:532 msgid "A connection error occurred" msgstr "" diff --git a/buzz/locale/es_ES/LC_MESSAGES/buzz.po b/buzz/locale/es_ES/LC_MESSAGES/buzz.po index 95baebfa2..fa32fa7e0 100644 --- a/buzz/locale/es_ES/LC_MESSAGES/buzz.po +++ b/buzz/locale/es_ES/LC_MESSAGES/buzz.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-18 08:41+0300\n" +"POT-Creation-Date: 2024-11-03 08:32+0200\n" "PO-Revision-Date: 2023-11-09 04:35-0600\n" "Last-Translator: Adolfo Jayme Barrientos \n" "Language-Team: \n" @@ -27,7 +27,7 @@ msgstr "" #: buzz/widgets/import_url_dialog.py:28 #: buzz/widgets/preferences_dialog/preferences_dialog.py:69 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:244 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 #: buzz/widgets/transcriber/advanced_settings_dialog.py:97 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:295 #: buzz/widgets/main_window.py:234 @@ -36,7 +36,7 @@ msgstr "" #: buzz/widgets/import_url_dialog.py:29 #: buzz/widgets/preferences_dialog/preferences_dialog.py:70 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:246 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:296 #: buzz/widgets/model_download_progress_dialog.py:29 #: buzz/widgets/main_window.py:235 @@ -64,68 +64,68 @@ msgstr "" msgid "Font Size" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:60 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:61 msgid "Test" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:66 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:67 msgid "OpenAI API key" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:79 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:80 msgid "OpenAI base url" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:88 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:89 msgid "Default export file name" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:94 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:95 msgid "Enable live recording transcription export" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:100 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:101 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 msgid "Browse" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:119 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:120 msgid "Export folder" msgstr "" # automatic translation -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:130 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:131 #, fuzzy msgid "Live recording mode" msgstr "Grabación en vivo" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:155 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:161 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:162 msgid "OpenAI API Key Test" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:157 msgid "" "Your API key is valid. Buzz will use this key to perform Whisper API " "transcriptions and AI translations." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:172 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 msgid "Invalid API key" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:174 msgid "" "API supports only base64 characters (A-Za-z0-9+/=). Other characters in API " "key may cause errors." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:191 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:192 msgid "Select Export Folder" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:243 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:244 msgid "" "OpenAI API returned invalid response. Please check the API url or your key. " "Transcription and translation may still work if the API does not support key " @@ -185,46 +185,46 @@ msgstr "" msgid "Huggingface ID of a Faster whisper model" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:93 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:94 msgid "Download" msgstr "Descargar" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:98 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:99 msgid "Show file location" msgstr "Mostrar ubicación de archivo" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:106 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:107 msgid "Delete" msgstr "Eliminar" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:137 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:138 msgid "Downloaded" msgstr "Descargado" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:142 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:143 msgid "Available for Download" msgstr "Disponible para descarga" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:163 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:164 msgid "Download link to Whisper.cpp ggml model file" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:238 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 msgid "Delete Model" msgstr "Eliminar modelo" # automatic translation -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:240 msgid "Are you sure you want to delete the selected model?" msgstr "¿Confirma que quiere eliminar el modelo seleccionado?" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:267 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 #, fuzzy msgid "Download failed" msgstr "Descargado" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 -#: buzz/widgets/main_window.py:291 buzz/model_loader.py:473 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:269 +#: buzz/widgets/main_window.py:291 buzz/model_loader.py:503 msgid "Error" msgstr "Error" @@ -251,21 +251,25 @@ msgid "Run" msgstr "Ejecutar" # automatic translation -#: buzz/widgets/transcriber/transcription_options_group_box.py:88 +#: buzz/widgets/transcriber/transcription_options_group_box.py:92 msgid "Model:" msgstr "Modelo:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:91 +#: buzz/widgets/transcriber/transcription_options_group_box.py:104 +msgid "First time use of a model may take up to several minutest to load." +msgstr "" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:113 msgid "Api Key:" msgstr "" # automatic translation -#: buzz/widgets/transcriber/transcription_options_group_box.py:92 +#: buzz/widgets/transcriber/transcription_options_group_box.py:114 msgid "Task:" msgstr "Tarea:" # automatic translation -#: buzz/widgets/transcriber/transcription_options_group_box.py:93 +#: buzz/widgets/transcriber/transcription_options_group_box.py:115 msgid "Language:" msgstr "Idioma:" @@ -603,7 +607,7 @@ msgstr "" msgid "Transcribe" msgstr "Abrir transcripción" -#: buzz/model_loader.py:502 +#: buzz/model_loader.py:532 msgid "A connection error occurred" msgstr "" diff --git a/buzz/locale/it_IT/LC_MESSAGES/buzz.po b/buzz/locale/it_IT/LC_MESSAGES/buzz.po index 4e3856854..a4c8cc31f 100644 --- a/buzz/locale/it_IT/LC_MESSAGES/buzz.po +++ b/buzz/locale/it_IT/LC_MESSAGES/buzz.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: buzz\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-18 08:41+0300\n" +"POT-Creation-Date: 2024-11-03 08:32+0200\n" "PO-Revision-Date: 2024-11-03 11:22+0100\n" "Language-Team: (Italiano) Albano Battistella \n" "Language: it_IT\n" @@ -26,7 +26,7 @@ msgstr "https://esempio.com/audio.mp3" #: buzz/widgets/import_url_dialog.py:28 #: buzz/widgets/preferences_dialog/preferences_dialog.py:69 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:244 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 #: buzz/widgets/transcriber/advanced_settings_dialog.py:97 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:295 #: buzz/widgets/main_window.py:234 @@ -35,7 +35,7 @@ msgstr "Ok" #: buzz/widgets/import_url_dialog.py:29 #: buzz/widgets/preferences_dialog/preferences_dialog.py:70 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:246 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:296 #: buzz/widgets/model_download_progress_dialog.py:29 #: buzz/widgets/main_window.py:235 @@ -62,27 +62,27 @@ msgstr "Ripristina impostazioni predefinite" msgid "Font Size" msgstr "Dimensione del carattere" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:60 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:61 msgid "Test" msgstr "Test" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:66 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:67 msgid "OpenAI API key" msgstr "Chiave API OpenAI" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:79 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:80 msgid "OpenAI base url" msgstr "URL di base di OpenAI" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:88 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:89 msgid "Default export file name" msgstr "Nome file di esportazione predefinito" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:94 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:95 msgid "Enable live recording transcription export" msgstr "Abilita l'esportazione della trascrizione della registrazione live" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:100 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:101 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 msgid "Browse" @@ -96,12 +96,12 @@ msgstr "Esporta cartella" msgid "Live recording mode" msgstr "Modalità di registrazione in diretta" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:155 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:161 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:162 msgid "OpenAI API Key Test" msgstr "Test della chiave API OpenAI" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:157 msgid "" "Your API key is valid. Buzz will use this key to perform Whisper API " "transcriptions and AI translations." @@ -113,7 +113,7 @@ msgstr "" msgid "Invalid API key" msgstr "Chiave API non valida" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:174 msgid "" "API supports only base64 characters (A-Za-z0-9+/=). Other characters in API " "key may cause errors." @@ -121,11 +121,11 @@ msgstr "" "L'API supporta solo caratteri base64 (A-Za-z0-9+/=). Altri caratteri nella chiave API " "potrebbero causare errori." -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:191 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:192 msgid "Select Export Folder" msgstr "Seleziona la cartella di esportazione" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:243 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:244 msgid "" "OpenAI API returned invalid response. Please check the API url or your key. " "Transcription and translation may still work if the API does not support key " @@ -182,35 +182,35 @@ msgstr "Gruppo" msgid "Huggingface ID of a Faster whisper model" msgstr "ID Huggingface di un modello Whisper più veloce" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:93 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:94 msgid "Download" msgstr "Download" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:98 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:99 msgid "Show file location" msgstr "Mostra la posizione del file" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:106 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:107 msgid "Delete" msgstr "Elimina" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:137 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:138 msgid "Downloaded" msgstr "Scaricato" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:142 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:143 msgid "Available for Download" msgstr "Disponibile per il download" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:163 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:164 msgid "Download link to Whisper.cpp ggml model file" msgstr "Link per scaricare il file modello ggml Whisper.cpp" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:238 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 msgid "Delete Model" msgstr "Elimina modello" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:240 msgid "Are you sure you want to delete the selected model?" msgstr "Sei sicuro di voler eliminare il modello selezionato?" @@ -218,8 +218,8 @@ msgstr "Sei sicuro di voler eliminare il modello selezionato?" msgid "Download failed" msgstr "Download non riuscito" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 -#: buzz/widgets/main_window.py:291 buzz/model_loader.py:473 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:269 +#: buzz/widgets/main_window.py:291 buzz/model_loader.py:503 msgid "Error" msgstr "Errore" @@ -241,19 +241,23 @@ msgstr "Rileva la lingua" msgid "Run" msgstr "Avvia" -#: buzz/widgets/transcriber/transcription_options_group_box.py:88 +#: buzz/widgets/transcriber/transcription_options_group_box.py:92 msgid "Model:" msgstr "Modello:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:91 +#: buzz/widgets/transcriber/transcription_options_group_box.py:104 +msgid "First time use of a model may take up to several minutest to load." +msgstr "" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:113 msgid "Api Key:" msgstr "Chiave API:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:92 +#: buzz/widgets/transcriber/transcription_options_group_box.py:114 msgid "Task:" msgstr "Compito:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:93 +#: buzz/widgets/transcriber/transcription_options_group_box.py:115 msgid "Language:" msgstr "Lingua:" @@ -555,7 +559,7 @@ msgstr "Impossibile salvare la chiave API OpenAI nel portachiavi" msgid "Transcribe" msgstr "Trascrivere" -#: buzz/model_loader.py:502 +#: buzz/model_loader.py:532 msgid "A connection error occurred" msgstr "Si è verificato un errore di connessione" diff --git a/buzz/locale/ja_JP/LC_MESSAGES/buzz.po b/buzz/locale/ja_JP/LC_MESSAGES/buzz.po index e3fff3f66..999ae0c10 100644 --- a/buzz/locale/ja_JP/LC_MESSAGES/buzz.po +++ b/buzz/locale/ja_JP/LC_MESSAGES/buzz.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-18 08:41+0300\n" +"POT-Creation-Date: 2024-11-03 08:32+0200\n" "PO-Revision-Date: \n" "Last-Translator: nunawa <71294849+nunawa@users.noreply.github.com>\n" "Language-Team: \n" @@ -22,7 +22,7 @@ msgstr "https://example.com/audio.mp3" #: buzz/widgets/import_url_dialog.py:28 #: buzz/widgets/preferences_dialog/preferences_dialog.py:69 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:244 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 #: buzz/widgets/transcriber/advanced_settings_dialog.py:97 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:295 #: buzz/widgets/main_window.py:234 @@ -31,7 +31,7 @@ msgstr "Ok" #: buzz/widgets/import_url_dialog.py:29 #: buzz/widgets/preferences_dialog/preferences_dialog.py:70 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:246 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:296 #: buzz/widgets/model_download_progress_dialog.py:29 #: buzz/widgets/main_window.py:235 @@ -58,47 +58,47 @@ msgstr "デフォルトに戻す" msgid "Font Size" msgstr "フォントサイズ" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:60 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:61 msgid "Test" msgstr "テスト" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:66 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:67 msgid "OpenAI API key" msgstr "OpenAI APIキー" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:79 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:80 msgid "OpenAI base url" msgstr "OpenAI ベースURL" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:88 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:89 msgid "Default export file name" msgstr "デフォルトの出力ファイル名" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:94 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:95 msgid "Enable live recording transcription export" msgstr "ライブ録音書き起こしの出力を有効にする" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:100 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:101 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 msgid "Browse" msgstr "参照" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:119 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:120 msgid "Export folder" msgstr "出力フォルダ" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:130 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:131 #, fuzzy msgid "Live recording mode" msgstr "ライブ録音" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:155 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:161 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:162 msgid "OpenAI API Key Test" msgstr "OpenAI APIキー テスト" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:157 msgid "" "Your API key is valid. Buzz will use this key to perform Whisper API " "transcriptions and AI translations." @@ -106,22 +106,22 @@ msgstr "" "あなたのAPIキーは有効です。Buzzはこのキーを使ってWhisper APIの書き起こしとAI" "翻訳を行います。" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:172 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 #, fuzzy msgid "Invalid API key" msgstr "OpenAI APIキー" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:174 msgid "" "API supports only base64 characters (A-Za-z0-9+/=). Other characters in API " "key may cause errors." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:191 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:192 msgid "Select Export Folder" msgstr "出力フォルダを選択" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:243 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:244 msgid "" "OpenAI API returned invalid response. Please check the API url or your key. " "Transcription and translation may still work if the API does not support key " @@ -179,44 +179,44 @@ msgstr "グループ" msgid "Huggingface ID of a Faster whisper model" msgstr "Faster whisperモデルのHuggingface ID" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:93 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:94 msgid "Download" msgstr "ダウンロード" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:98 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:99 msgid "Show file location" msgstr "ファイルの場所を表示" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:106 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:107 msgid "Delete" msgstr "削除" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:137 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:138 msgid "Downloaded" msgstr "ダウンロード済み" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:142 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:143 msgid "Available for Download" msgstr "ダウンロード可能" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:163 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:164 msgid "Download link to Whisper.cpp ggml model file" msgstr "Whisper.cpp ggmlモデルファイルのダウンロードリンク" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:238 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 msgid "Delete Model" msgstr "モデルを削除" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:240 msgid "Are you sure you want to delete the selected model?" msgstr "選択したモデルを本当に削除しますか?" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:267 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 msgid "Download failed" msgstr "ダウンロード失敗" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 -#: buzz/widgets/main_window.py:291 buzz/model_loader.py:473 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:269 +#: buzz/widgets/main_window.py:291 buzz/model_loader.py:503 msgid "Error" msgstr "エラー" @@ -238,19 +238,23 @@ msgstr "自動検出" msgid "Run" msgstr "実行" -#: buzz/widgets/transcriber/transcription_options_group_box.py:88 +#: buzz/widgets/transcriber/transcription_options_group_box.py:92 msgid "Model:" msgstr "モデル:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:91 +#: buzz/widgets/transcriber/transcription_options_group_box.py:104 +msgid "First time use of a model may take up to several minutest to load." +msgstr "" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:113 msgid "Api Key:" msgstr "APIキー:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:92 +#: buzz/widgets/transcriber/transcription_options_group_box.py:114 msgid "Task:" msgstr "タスク:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:93 +#: buzz/widgets/transcriber/transcription_options_group_box.py:115 msgid "Language:" msgstr "言語:" @@ -550,7 +554,7 @@ msgstr "OpenAI API キーをkeyringに保存できません" msgid "Transcribe" msgstr "文字起こし" -#: buzz/model_loader.py:502 +#: buzz/model_loader.py:532 msgid "A connection error occurred" msgstr "接続エラーが発生しました" diff --git a/buzz/locale/lv_LV/LC_MESSAGES/buzz.po b/buzz/locale/lv_LV/LC_MESSAGES/buzz.po index bc8a7824f..7c9581e74 100644 --- a/buzz/locale/lv_LV/LC_MESSAGES/buzz.po +++ b/buzz/locale/lv_LV/LC_MESSAGES/buzz.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-18 08:41+0300\n" -"PO-Revision-Date: 2024-10-18 08:43+0300\n" +"POT-Creation-Date: 2024-11-03 08:32+0200\n" +"PO-Revision-Date: 2024-11-03 08:33+0200\n" "Last-Translator: \n" "Language-Team: \n" "Language: lv_LV\n" @@ -28,7 +28,7 @@ msgstr "https://example.com/audio.mp3" #: buzz/widgets/import_url_dialog.py:28 #: buzz/widgets/preferences_dialog/preferences_dialog.py:69 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:244 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 #: buzz/widgets/transcriber/advanced_settings_dialog.py:97 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:295 #: buzz/widgets/main_window.py:234 @@ -37,7 +37,7 @@ msgstr "Labi" #: buzz/widgets/import_url_dialog.py:29 #: buzz/widgets/preferences_dialog/preferences_dialog.py:70 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:246 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:296 #: buzz/widgets/model_download_progress_dialog.py:29 #: buzz/widgets/main_window.py:235 @@ -64,48 +64,48 @@ msgstr "Atjaunot noklusētos" msgid "Font Size" msgstr "Fonta izmērs" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:60 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:61 msgid "Test" msgstr "Pārbaudīt" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:66 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:67 msgid "OpenAI API key" msgstr "OpenAI API atslēga" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:79 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:80 msgid "OpenAI base url" msgstr "OpenAI adrese" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:88 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:89 msgid "Default export file name" msgstr "Eksporta fails" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:94 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:95 msgid "Enable live recording transcription export" msgstr "Eksportēt dzīvā ieraksta transkriptus" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:100 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:101 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 msgid "Browse" msgstr "Izvēlēties" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:119 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:120 msgid "Export folder" msgstr "Eksportēt mapē" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:130 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:131 msgid "Live recording mode" msgstr "" "Dzīvā ieraksta\n" "režīms" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:155 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:161 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:162 msgid "OpenAI API Key Test" msgstr "OpenAI API atslēgas pārbaude" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:157 msgid "" "Your API key is valid. Buzz will use this key to perform Whisper API " "transcriptions and AI translations." @@ -113,11 +113,11 @@ msgstr "" "Jūsu API atslēga ir derīga. Buzz izmantos to runas atpazīšanai ar Whisper " "API un tulkošanai." -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:172 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 msgid "Invalid API key" msgstr "Nederīga API atslēga" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:174 msgid "" "API supports only base64 characters (A-Za-z0-9+/=). Other characters in API " "key may cause errors." @@ -125,11 +125,11 @@ msgstr "" "API atbalsta tikai base64 simbolus (A-Za-z0-9+/=). Citi simboli API atslēgā " "var radīt kļūdas." -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:191 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:192 msgid "Select Export Folder" msgstr "Izvēlieties mapi kurā eksportēt" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:243 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:244 msgid "" "OpenAI API returned invalid response. Please check the API url or your key. " "Transcription and translation may still work if the API does not support key " @@ -187,44 +187,44 @@ msgstr "Veids" msgid "Huggingface ID of a Faster whisper model" msgstr "Faster Whisper modeļa Huggingface ID" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:93 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:94 msgid "Download" msgstr "Lejupielādēt" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:98 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:99 msgid "Show file location" msgstr "Rādīt faila atrašanās vietu" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:106 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:107 msgid "Delete" msgstr "Dzēst" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:137 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:138 msgid "Downloaded" msgstr "Lejupielādēts" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:142 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:143 msgid "Available for Download" msgstr "Pieejams lejupielādei" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:163 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:164 msgid "Download link to Whisper.cpp ggml model file" msgstr "Whisper.cpp ggml modeļa datnes lejupielādes saite" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:238 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 msgid "Delete Model" msgstr "Dzēst modeli" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:240 msgid "Are you sure you want to delete the selected model?" msgstr "Vai tiešām dzēst izvēlēto modeli?" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:267 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 msgid "Download failed" msgstr "Lejupielāde neizdevās" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 -#: buzz/widgets/main_window.py:291 buzz/model_loader.py:473 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:269 +#: buzz/widgets/main_window.py:291 buzz/model_loader.py:503 msgid "Error" msgstr "Kļūda" @@ -246,19 +246,23 @@ msgstr "Noteikt valodu" msgid "Run" msgstr "Apstrādāt" -#: buzz/widgets/transcriber/transcription_options_group_box.py:88 +#: buzz/widgets/transcriber/transcription_options_group_box.py:92 msgid "Model:" msgstr "Modelis:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:91 +#: buzz/widgets/transcriber/transcription_options_group_box.py:104 +msgid "First time use of a model may take up to several minutest to load." +msgstr "Pirmā modeļa ielādes reize var aizņemt pat vairākas minūtes." + +#: buzz/widgets/transcriber/transcription_options_group_box.py:113 msgid "Api Key:" msgstr "API atslēga:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:92 +#: buzz/widgets/transcriber/transcription_options_group_box.py:114 msgid "Task:" msgstr "Uzdevums:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:93 +#: buzz/widgets/transcriber/transcription_options_group_box.py:115 msgid "Language:" msgstr "Valoda:" @@ -560,7 +564,7 @@ msgstr "Neizdevās saglabāt OpenAI API atslēgu atslēgu saišķī" msgid "Transcribe" msgstr "Atpazīt" -#: buzz/model_loader.py:502 +#: buzz/model_loader.py:532 msgid "A connection error occurred" msgstr "Notika savienojuma kļūda" diff --git a/buzz/locale/pl_PL/LC_MESSAGES/buzz.po b/buzz/locale/pl_PL/LC_MESSAGES/buzz.po index 301979f75..227b1dafa 100644 --- a/buzz/locale/pl_PL/LC_MESSAGES/buzz.po +++ b/buzz/locale/pl_PL/LC_MESSAGES/buzz.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-18 08:41+0300\n" +"POT-Creation-Date: 2024-11-03 08:32+0200\n" "PO-Revision-Date: 2024-03-17 20:50+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -27,7 +27,7 @@ msgstr "https://przyklad.pl/audio.mp3" #: buzz/widgets/import_url_dialog.py:28 #: buzz/widgets/preferences_dialog/preferences_dialog.py:69 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:244 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 #: buzz/widgets/transcriber/advanced_settings_dialog.py:97 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:295 #: buzz/widgets/main_window.py:234 @@ -36,7 +36,7 @@ msgstr "" #: buzz/widgets/import_url_dialog.py:29 #: buzz/widgets/preferences_dialog/preferences_dialog.py:70 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:246 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:296 #: buzz/widgets/model_download_progress_dialog.py:29 #: buzz/widgets/main_window.py:235 @@ -63,68 +63,68 @@ msgstr "" msgid "Font Size" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:60 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:61 msgid "Test" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:66 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:67 msgid "OpenAI API key" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:79 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:80 msgid "OpenAI base url" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:88 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:89 msgid "Default export file name" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:94 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:95 msgid "Enable live recording transcription export" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:100 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:101 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 msgid "Browse" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:119 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:120 msgid "Export folder" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:130 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:131 #, fuzzy msgid "Live recording mode" msgstr "Nagrywanie na żywo" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:155 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:161 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:162 msgid "OpenAI API Key Test" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:157 msgid "" "Your API key is valid. Buzz will use this key to perform Whisper API " "transcriptions and AI translations." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:172 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 #, fuzzy msgid "Invalid API key" msgstr "Nieprawidłowy URL" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:174 msgid "" "API supports only base64 characters (A-Za-z0-9+/=). Other characters in API " "key may cause errors." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:191 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:192 msgid "Select Export Folder" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:243 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:244 msgid "" "OpenAI API returned invalid response. Please check the API url or your key. " "Transcription and translation may still work if the API does not support key " @@ -183,48 +183,48 @@ msgstr "" msgid "Huggingface ID of a Faster whisper model" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:93 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:94 #, fuzzy msgid "Download" msgstr "Pobierz" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:98 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:99 msgid "Show file location" msgstr "Pokaż lokalizacje pliku" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:106 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:107 msgid "Delete" msgstr "Usuń" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:137 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:138 #, fuzzy msgid "Downloaded" msgstr "Pobrany" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:142 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:143 msgid "Available for Download" msgstr "Dostępne do pobrania" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:163 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:164 msgid "Download link to Whisper.cpp ggml model file" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:238 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 msgid "Delete Model" msgstr "Usuń model" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:240 #, fuzzy msgid "Are you sure you want to delete the selected model?" msgstr "Czy na pewno chcesz usunąć zaznaczoną transkrypcję?" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:267 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 #, fuzzy msgid "Download failed" msgstr "Pobrany" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 -#: buzz/widgets/main_window.py:291 buzz/model_loader.py:473 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:269 +#: buzz/widgets/main_window.py:291 buzz/model_loader.py:503 msgid "Error" msgstr "Błąd" @@ -246,19 +246,23 @@ msgstr "Wykryj język" msgid "Run" msgstr "Rozpocznij" -#: buzz/widgets/transcriber/transcription_options_group_box.py:88 +#: buzz/widgets/transcriber/transcription_options_group_box.py:92 msgid "Model:" msgstr "Model:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:91 +#: buzz/widgets/transcriber/transcription_options_group_box.py:104 +msgid "First time use of a model may take up to several minutest to load." +msgstr "" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:113 msgid "Api Key:" msgstr "" -#: buzz/widgets/transcriber/transcription_options_group_box.py:92 +#: buzz/widgets/transcriber/transcription_options_group_box.py:114 msgid "Task:" msgstr "Zadanie:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:93 +#: buzz/widgets/transcriber/transcription_options_group_box.py:115 msgid "Language:" msgstr "Język:" @@ -567,7 +571,7 @@ msgstr "" msgid "Transcribe" msgstr "Otwórz transkrypt" -#: buzz/model_loader.py:502 +#: buzz/model_loader.py:532 msgid "A connection error occurred" msgstr "" diff --git a/buzz/locale/uk_UA/LC_MESSAGES/buzz.po b/buzz/locale/uk_UA/LC_MESSAGES/buzz.po index 1425ea240..4b29644ce 100644 --- a/buzz/locale/uk_UA/LC_MESSAGES/buzz.po +++ b/buzz/locale/uk_UA/LC_MESSAGES/buzz.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-18 08:41+0300\n" +"POT-Creation-Date: 2024-11-03 08:32+0200\n" "PO-Revision-Date: \n" "Last-Translator: Yevhen Popok \n" "Language-Team: \n" @@ -24,7 +24,7 @@ msgstr "https://example.com/audio.mp3" #: buzz/widgets/import_url_dialog.py:28 #: buzz/widgets/preferences_dialog/preferences_dialog.py:69 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:244 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 #: buzz/widgets/transcriber/advanced_settings_dialog.py:97 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:295 #: buzz/widgets/main_window.py:234 @@ -33,7 +33,7 @@ msgstr "Гаразд" #: buzz/widgets/import_url_dialog.py:29 #: buzz/widgets/preferences_dialog/preferences_dialog.py:70 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:246 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:296 #: buzz/widgets/model_download_progress_dialog.py:29 #: buzz/widgets/main_window.py:235 @@ -60,47 +60,47 @@ msgstr "Типові значення" msgid "Font Size" msgstr "Розмір шрифту" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:60 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:61 msgid "Test" msgstr "Тест" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:66 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:67 msgid "OpenAI API key" msgstr "API-ключ OpenAI" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:79 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:80 msgid "OpenAI base url" msgstr "Базова адреса OpenAI" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:88 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:89 msgid "Default export file name" msgstr "Типова назва файлу експорту" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:94 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:95 msgid "Enable live recording transcription export" msgstr "Увімкнути експорт транскрипції з живого запису" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:100 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:101 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 msgid "Browse" msgstr "Огляд" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:119 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:120 msgid "Export folder" msgstr "Тека для експорту" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:130 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:131 #, fuzzy msgid "Live recording mode" msgstr "Живий запис" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:155 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:161 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:162 msgid "OpenAI API Key Test" msgstr "Тест API-ключа OpenAI" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:157 msgid "" "Your API key is valid. Buzz will use this key to perform Whisper API " "transcriptions and AI translations." @@ -108,22 +108,22 @@ msgstr "" "Ваш API-ключ дійсний. Buzz використає цей ключ для транскрипції з Whisper " "API та перекладу ШІ." -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:172 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 #, fuzzy msgid "Invalid API key" msgstr "API-ключ OpenAI" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:174 msgid "" "API supports only base64 characters (A-Za-z0-9+/=). Other characters in API " "key may cause errors." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:191 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:192 msgid "Select Export Folder" msgstr "Виберіть теку для експорту" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:243 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:244 msgid "" "OpenAI API returned invalid response. Please check the API url or your key. " "Transcription and translation may still work if the API does not support key " @@ -181,44 +181,44 @@ msgstr "Група" msgid "Huggingface ID of a Faster whisper model" msgstr "Huggingface ID для моделі Faster Whisper" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:93 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:94 msgid "Download" msgstr "Завантажити" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:98 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:99 msgid "Show file location" msgstr "Показати розташування файлу" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:106 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:107 msgid "Delete" msgstr "Видалити" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:137 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:138 msgid "Downloaded" msgstr "Завантажене" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:142 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:143 msgid "Available for Download" msgstr "Доступно для завантаження" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:163 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:164 msgid "Download link to Whisper.cpp ggml model file" msgstr "Посилання на завантаження файлу ggml моделі Whisper.cpp" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:238 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 msgid "Delete Model" msgstr "Видалити модель" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:240 msgid "Are you sure you want to delete the selected model?" msgstr "Ви впевнені, що хочете видалити вибрану модель?" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:267 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 msgid "Download failed" msgstr "Невдале завантаження" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 -#: buzz/widgets/main_window.py:291 buzz/model_loader.py:473 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:269 +#: buzz/widgets/main_window.py:291 buzz/model_loader.py:503 msgid "Error" msgstr "Помилка" @@ -240,19 +240,23 @@ msgstr "Визначити мову" msgid "Run" msgstr "Запуск" -#: buzz/widgets/transcriber/transcription_options_group_box.py:88 +#: buzz/widgets/transcriber/transcription_options_group_box.py:92 msgid "Model:" msgstr "Модель:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:91 +#: buzz/widgets/transcriber/transcription_options_group_box.py:104 +msgid "First time use of a model may take up to several minutest to load." +msgstr "" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:113 msgid "Api Key:" msgstr "API-ключ:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:92 +#: buzz/widgets/transcriber/transcription_options_group_box.py:114 msgid "Task:" msgstr "Завдання:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:93 +#: buzz/widgets/transcriber/transcription_options_group_box.py:115 msgid "Language:" msgstr "Мова:" @@ -552,7 +556,7 @@ msgstr "Не вдається додати до звʼязки ключів API- msgid "Transcribe" msgstr "Розпізнати" -#: buzz/model_loader.py:502 +#: buzz/model_loader.py:532 msgid "A connection error occurred" msgstr "Виникла помилка зʼєднання" diff --git a/buzz/locale/zh_CN/LC_MESSAGES/buzz.po b/buzz/locale/zh_CN/LC_MESSAGES/buzz.po index ccb080e85..99079a334 100644 --- a/buzz/locale/zh_CN/LC_MESSAGES/buzz.po +++ b/buzz/locale/zh_CN/LC_MESSAGES/buzz.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-18 08:41+0300\n" +"POT-Creation-Date: 2024-11-03 08:32+0200\n" "PO-Revision-Date: 2023-05-01 15:45+0800\n" "Last-Translator: \n" "Language-Team: lamb \n" @@ -28,7 +28,7 @@ msgstr "" #: buzz/widgets/import_url_dialog.py:28 #: buzz/widgets/preferences_dialog/preferences_dialog.py:69 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:244 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 #: buzz/widgets/transcriber/advanced_settings_dialog.py:97 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:295 #: buzz/widgets/main_window.py:234 @@ -37,7 +37,7 @@ msgstr "" #: buzz/widgets/import_url_dialog.py:29 #: buzz/widgets/preferences_dialog/preferences_dialog.py:70 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:246 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:296 #: buzz/widgets/model_download_progress_dialog.py:29 #: buzz/widgets/main_window.py:235 @@ -64,47 +64,47 @@ msgstr "恢复默认" msgid "Font Size" msgstr "字体大小" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:60 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:61 msgid "Test" msgstr "测试" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:66 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:67 msgid "OpenAI API key" msgstr "OpenAI API key" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:79 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:80 msgid "OpenAI base url" msgstr "OpenAI base url" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:88 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:89 msgid "Default export file name" msgstr "默认输出文件名" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:94 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:95 msgid "Enable live recording transcription export" msgstr "启用实时录制转录导出" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:100 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:101 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 msgid "Browse" msgstr "浏览" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:119 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:120 msgid "Export folder" msgstr "导出文件夹" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:130 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:131 #, fuzzy msgid "Live recording mode" msgstr "现场录制模式" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:155 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:161 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:162 msgid "OpenAI API Key Test" msgstr "测试OpenAI API Key" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:157 msgid "" "Your API key is valid. Buzz will use this key to perform Whisper API " "transcriptions and AI translations." @@ -113,21 +113,21 @@ msgstr "" “转录和人工智能翻译。” -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:172 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 msgid "Invalid API key" msgstr "无效的API key" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:174 msgid "" "API supports only base64 characters (A-Za-z0-9+/=). Other characters in API " "key may cause errors." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:191 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:192 msgid "Select Export Folder" msgstr "选择输出文件夹" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:243 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:244 msgid "" "OpenAI API returned invalid response. Please check the API url or your key. " "Transcription and translation may still work if the API does not support key " @@ -187,48 +187,48 @@ msgstr "组" msgid "Huggingface ID of a Faster whisper model" msgstr "更快的Whisper模型的Huggingface ID" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:93 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:94 #, fuzzy msgid "Download" msgstr "下载" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:98 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:99 msgid "Show file location" msgstr "查看文件位置" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:106 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:107 msgid "Delete" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:137 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:138 #, fuzzy msgid "Downloaded" msgstr "下载模型" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:142 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:143 msgid "Available for Download" msgstr "删除" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:163 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:164 msgid "Download link to Whisper.cpp ggml model file" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:238 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 msgid "Delete Model" msgstr "删除模型" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:240 #, fuzzy msgid "Are you sure you want to delete the selected model?" msgstr "您确定要删除所选录制吗?此操作无法撤消。" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:267 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 #, fuzzy msgid "Download failed" msgstr "下载模型" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 -#: buzz/widgets/main_window.py:291 buzz/model_loader.py:473 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:269 +#: buzz/widgets/main_window.py:291 buzz/model_loader.py:503 msgid "Error" msgstr "错误" @@ -250,19 +250,23 @@ msgstr "检测语言" msgid "Run" msgstr "开始执行" -#: buzz/widgets/transcriber/transcription_options_group_box.py:88 +#: buzz/widgets/transcriber/transcription_options_group_box.py:92 msgid "Model:" msgstr "模型:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:91 +#: buzz/widgets/transcriber/transcription_options_group_box.py:104 +msgid "First time use of a model may take up to several minutest to load." +msgstr "" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:113 msgid "Api Key:" msgstr "Api Key:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:92 +#: buzz/widgets/transcriber/transcription_options_group_box.py:114 msgid "Task:" msgstr "任务:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:93 +#: buzz/widgets/transcriber/transcription_options_group_box.py:115 msgid "Language:" msgstr "语言:" @@ -567,7 +571,7 @@ msgstr "无法将OpenAI API密钥保存到密钥串" msgid "Transcribe" msgstr "转换" -#: buzz/model_loader.py:502 +#: buzz/model_loader.py:532 msgid "A connection error occurred" msgstr "连接发生错误" diff --git a/buzz/locale/zh_TW/LC_MESSAGES/buzz.po b/buzz/locale/zh_TW/LC_MESSAGES/buzz.po index a15092cb3..28a8dad03 100644 --- a/buzz/locale/zh_TW/LC_MESSAGES/buzz.po +++ b/buzz/locale/zh_TW/LC_MESSAGES/buzz.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-18 08:41+0300\n" +"POT-Creation-Date: 2024-11-03 08:32+0200\n" "PO-Revision-Date: 2023-05-01 15:45+0800\n" "Last-Translator: \n" "Language-Team: Lamb\n" @@ -27,7 +27,7 @@ msgstr "" #: buzz/widgets/import_url_dialog.py:28 #: buzz/widgets/preferences_dialog/preferences_dialog.py:69 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:244 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 #: buzz/widgets/transcriber/advanced_settings_dialog.py:97 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:295 #: buzz/widgets/main_window.py:234 @@ -36,7 +36,7 @@ msgstr "" #: buzz/widgets/import_url_dialog.py:29 #: buzz/widgets/preferences_dialog/preferences_dialog.py:70 -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:245 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:246 #: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:296 #: buzz/widgets/model_download_progress_dialog.py:29 #: buzz/widgets/main_window.py:235 @@ -63,67 +63,67 @@ msgstr "" msgid "Font Size" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:60 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:61 msgid "Test" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:66 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:67 msgid "OpenAI API key" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:79 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:80 msgid "OpenAI base url" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:88 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:89 msgid "Default export file name" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:94 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:95 msgid "Enable live recording transcription export" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:100 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:101 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 #: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 msgid "Browse" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:119 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:120 msgid "Export folder" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:130 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:131 #, fuzzy msgid "Live recording mode" msgstr "現場錄製" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:155 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:161 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:162 msgid "OpenAI API Key Test" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:157 msgid "" "Your API key is valid. Buzz will use this key to perform Whisper API " "transcriptions and AI translations." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:172 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 msgid "Invalid API key" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:173 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:174 msgid "" "API supports only base64 characters (A-Za-z0-9+/=). Other characters in API " "key may cause errors." msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:191 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:192 msgid "Select Export Folder" msgstr "" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:243 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:244 msgid "" "OpenAI API returned invalid response. Please check the API url or your key. " "Transcription and translation may still work if the API does not support key " @@ -181,48 +181,48 @@ msgstr "" msgid "Huggingface ID of a Faster whisper model" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:93 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:94 #, fuzzy msgid "Download" msgstr "下載模型" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:98 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:99 msgid "Show file location" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:106 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:107 msgid "Delete" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:137 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:138 #, fuzzy msgid "Downloaded" msgstr "下載模型" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:142 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:143 msgid "Available for Download" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:163 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:164 msgid "Download link to Whisper.cpp ggml model file" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:238 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 msgid "Delete Model" msgstr "" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:239 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:240 #, fuzzy msgid "Are you sure you want to delete the selected model?" msgstr "您確定要刪除所選錄製嗎?此操作無法撤消。" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:267 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 #, fuzzy msgid "Download failed" msgstr "下載模型" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:268 -#: buzz/widgets/main_window.py:291 buzz/model_loader.py:473 +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:269 +#: buzz/widgets/main_window.py:291 buzz/model_loader.py:503 msgid "Error" msgstr "" @@ -244,19 +244,23 @@ msgstr "檢測語言" msgid "Run" msgstr "開始執行" -#: buzz/widgets/transcriber/transcription_options_group_box.py:88 +#: buzz/widgets/transcriber/transcription_options_group_box.py:92 msgid "Model:" msgstr "模型:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:91 +#: buzz/widgets/transcriber/transcription_options_group_box.py:104 +msgid "First time use of a model may take up to several minutest to load." +msgstr "" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:113 msgid "Api Key:" msgstr "" -#: buzz/widgets/transcriber/transcription_options_group_box.py:92 +#: buzz/widgets/transcriber/transcription_options_group_box.py:114 msgid "Task:" msgstr "任務:" -#: buzz/widgets/transcriber/transcription_options_group_box.py:93 +#: buzz/widgets/transcriber/transcription_options_group_box.py:115 msgid "Language:" msgstr "語言:" @@ -561,7 +565,7 @@ msgstr "" msgid "Transcribe" msgstr "打開轉換結果" -#: buzz/model_loader.py:502 +#: buzz/model_loader.py:532 msgid "A connection error occurred" msgstr "" diff --git a/buzz/model_loader.py b/buzz/model_loader.py index 70aba7874..7a0931818 100644 --- a/buzz/model_loader.py +++ b/buzz/model_loader.py @@ -10,16 +10,16 @@ import tempfile import warnings import platform +import requests +import whisper +import huggingface_hub +import zipfile from dataclasses import dataclass from typing import Optional, List -import requests from PyQt6.QtCore import QObject, pyqtSignal, QRunnable from platformdirs import user_cache_dir - -import faster_whisper -import whisper -import huggingface_hub +from huggingface_hub.errors import LocalEntryNotFoundError from buzz.locale import _ @@ -205,7 +205,7 @@ def delete_local_file(self): def get_local_model_path(self) -> Optional[str]: if self.model_type == ModelType.WHISPER_CPP: file_path = get_whisper_cpp_file_path(size=self.whisper_model_size) - if not os.path.exists(file_path) or not os.path.isfile(file_path): + if not file_path or not os.path.exists(file_path) or not os.path.isfile(file_path): return None return file_path @@ -241,21 +241,27 @@ def get_local_model_path(self) -> Optional[str]: raise Exception("Unknown model type") -WHISPER_CPP_MODELS_SHA256 = { - "tiny": "be07e048e1e599ad46341c8d2a135645097a538221678b7acdd1b1919c6e1b21", - "base": "60ed5bc3dd14eea856493d334349b405782ddcaf0028d4b5df4088345fba2efe", - "small": "1be3a9b2063867b937e64e2ec7483364a79917e157fa98c5d94b5c1fffea987b", - "medium": "6c14d5adee5f86394037b4e4e8b59f1673b6cee10e3cf0b11bbdbee79c156208", - "large-v1": "7d99f41a10525d0206bddadd86760181fa920438b6b33237e3118ff6c83bb53d", - "large-v2": "9a423fe4d40c82774b6af34115b8b935f34152246eb19e80e376071d3f999487", - "large-v3": "64d182b440b98d5203c4f9bd541544d84c605196c4f7b845dfa11fb23594d1e2", - "large-v3-turbo": "1fc70f774d38eb169993ac391eea357ef47c88757ef72ee5943879b7e8e2bc69", - "custom": None, -} +WHISPER_CPP_REPO_ID = "ggerganov/whisper.cpp" def get_whisper_cpp_file_path(size: WhisperModelSize) -> str: - return os.path.join(model_root_dir, f"ggml-model-whisper-{size.value}.bin") + if size == WhisperModelSize.CUSTOM: + return os.path.join(model_root_dir, f"ggml-model-whisper-custom.bin") + + model_filename = f"ggml-{size.to_whisper_cpp_model_size()}.bin" + + try: + model_path = huggingface_hub.snapshot_download( + repo_id=WHISPER_CPP_REPO_ID, + allow_patterns=[model_filename], + local_files_only=True, + cache_dir=model_root_dir, + etag_timeout=60 + ) + + return os.path.join(model_path, model_filename) + except LocalEntryNotFoundError: + return '' def get_whisper_file_path(size: WhisperModelSize) -> str: @@ -434,6 +440,7 @@ class Signals(QObject): def __init__(self, model: TranscriptionModel, custom_model_url: Optional[str] = None): super().__init__() + self.is_coreml_supported = platform.system() == "Darwin" and platform.machine() == "arm64" self.signals = self.Signals() self.model = model self.stopped = False @@ -443,22 +450,41 @@ def run(self) -> None: logging.debug("Downloading model: %s, %s", self.model, self.model.hugging_face_model_id) if self.model.model_type == ModelType.WHISPER_CPP: - model_name = self.model.whisper_model_size.to_whisper_cpp_model_size() - if self.custom_model_url: url = self.custom_model_url - else: - url = huggingface_hub.hf_hub_url( - repo_id="ggerganov/whisper.cpp", - filename=f"ggml-{model_name}.bin", - ) + file_path = get_whisper_cpp_file_path(size=self.model.whisper_model_size) + return self.download_model_to_path(url=url, file_path=file_path) - file_path = get_whisper_cpp_file_path(size=self.model.whisper_model_size) - expected_sha256 = WHISPER_CPP_MODELS_SHA256[model_name] - return self.download_model_to_path( - url=url, file_path=file_path, expected_sha256=expected_sha256 + model_name = self.model.whisper_model_size.to_whisper_cpp_model_size() + + whisper_cpp_model_files = [ + f"ggml-{model_name}.bin", + "README.md" + ] + num_large_files = 1 + if self.is_coreml_supported: + whisper_cpp_model_files = [ + f"ggml-{model_name}.bin", + f"ggml-{model_name}-encoder.mlmodelc.zip", + "README.md" + ] + num_large_files = 2 + + model_path = download_from_huggingface( + repo_id=WHISPER_CPP_REPO_ID, + allow_patterns=whisper_cpp_model_files, + progress=self.signals.progress, + num_large_files=num_large_files ) + if self.is_coreml_supported: + with zipfile.ZipFile( + os.path.join(model_path, f"ggml-{model_name}-encoder.mlmodelc.zip"), 'r') as zip_ref: + zip_ref.extractall(model_path) + + self.signals.finished.emit(os.path.join(model_path, f"ggml-{model_name}.bin")) + return + if self.model.model_type == ModelType.WHISPER: url = whisper._MODELS[self.model.whisper_model_size.value] file_path = get_whisper_file_path(size=self.model.whisper_model_size) @@ -496,7 +522,7 @@ def run(self) -> None: raise Exception("Invalid model type: " + self.model.model_type.value) def download_model_to_path( - self, url: str, file_path: str, expected_sha256: Optional[str] + self, url: str, file_path: str, expected_sha256: Optional[str] = None ): try: downloaded = self.download_model(url, file_path, expected_sha256) diff --git a/buzz/transcriber/recording_transcriber.py b/buzz/transcriber/recording_transcriber.py index 25481fd91..1654bf188 100644 --- a/buzz/transcriber/recording_transcriber.py +++ b/buzz/transcriber/recording_transcriber.py @@ -3,6 +3,7 @@ import platform import os import wave +import time import tempfile import threading from typing import Optional @@ -15,11 +16,11 @@ from openai import OpenAI from PyQt6.QtCore import QObject, pyqtSignal -from buzz import transformers_whisper, whisper_audio +from buzz import whisper_audio from buzz.model_loader import WhisperModelSize, ModelType, get_custom_api_whisper_model from buzz.settings.settings import Settings from buzz.transcriber.transcriber import TranscriptionOptions, Task -from buzz.transcriber.whisper_cpp import WhisperCpp, whisper_cpp_params +from buzz.transcriber.whisper_cpp import WhisperCpp from buzz.transformers_whisper import TransformersWhisper from buzz.settings.recording_transcriber_mode import RecordingTranscriberMode @@ -52,13 +53,13 @@ def __init__( self.input_device_index = input_device_index self.sample_rate = sample_rate if sample_rate is not None else whisper_audio.SAMPLE_RATE self.model_path = model_path - self.n_batch_samples = 5 * self.sample_rate # every 5 seconds + self.n_batch_samples = 5 * self.sample_rate # 5 seconds self.keep_sample_seconds = 0.15 if self.transcriber_mode == RecordingTranscriberMode.APPEND_AND_CORRECT: - self.n_batch_samples = 3 * self.sample_rate # every 3 seconds + self.n_batch_samples = 3 * self.sample_rate # 3 seconds self.keep_sample_seconds = 1.5 - # pause queueing if more than 5 batches behind - self.max_queue_size = 5 * self.n_batch_samples + # pause queueing if more than 3 batches behind + self.max_queue_size = 3 * self.n_batch_samples self.queue = np.ndarray([], dtype=np.float32) self.mutex = threading.Lock() self.sounddevice = sounddevice @@ -136,8 +137,8 @@ def start(self): callback=self.stream_callback, ): while self.is_running: - self.mutex.acquire() if self.queue.size >= self.n_batch_samples: + self.mutex.acquire() samples = self.queue[: self.n_batch_samples] self.queue = self.queue[self.n_batch_samples - keep_samples:] self.mutex.release() @@ -153,8 +154,8 @@ def start(self): # TODO Filter out silent audio if ( - self.transcription_options.model.model_type - == ModelType.WHISPER + self.transcription_options.model.model_type + == ModelType.WHISPER ): assert isinstance(model, whisper.Whisper) result = model.transcribe( @@ -165,13 +166,13 @@ def start(self): temperature=self.transcription_options.temperature, ) elif ( - self.transcription_options.model.model_type - == ModelType.WHISPER_CPP + self.transcription_options.model.model_type + == ModelType.WHISPER_CPP ): assert isinstance(model, WhisperCpp) result = model.transcribe( audio=samples, - params=whisper_cpp_params( + params=model.get_params( transcription_options=self.transcription_options ), ) @@ -254,7 +255,8 @@ def start(self): ) self.transcription.emit(next_text) else: - self.mutex.release() + time.sleep(0.5) + except PortAudioError as exc: self.error.emit(str(exc)) logging.exception("") diff --git a/buzz/transcriber/whisper_cpp.py b/buzz/transcriber/whisper_cpp.py index 1d6a2af08..c8252542b 100644 --- a/buzz/transcriber/whisper_cpp.py +++ b/buzz/transcriber/whisper_cpp.py @@ -1,3 +1,4 @@ +import platform import os import ctypes import logging @@ -13,9 +14,30 @@ from buzz import whisper_cpp +IS_COREML_SUPPORTED = False +if platform.system() == "Darwin" and platform.machine() == "arm64": + try: + from buzz import whisper_cpp_coreml # noqa: F401 + + IS_COREML_SUPPORTED = True + except ImportError: + logging.exception("") + + class WhisperCpp: def __init__(self, model: str) -> None: - self.ctx = whisper_cpp.whisper_init_from_file(model.encode()) + + self.is_coreml_supported = IS_COREML_SUPPORTED + + if self.is_coreml_supported: + coreml_model = model.replace(".bin", "-encoder.mlmodelc") + if not os.path.exists(coreml_model): + self.is_coreml_supported = False + + logging.debug(f"WhisperCpp model {model}, (Core ML: {self.is_coreml_supported})") + + self.instance = self.get_instance() + self.ctx = self.instance.init_from_file(model) self.segments: List[Segment] = [] def append_segment(self, txt: bytes, start: int, end: int): @@ -46,13 +68,13 @@ def transcribe(self, audio: Union[np.ndarray, str], params: Any): logging.debug("Loaded audio with length = %s", len(audio)) whisper_cpp_audio = audio.ctypes.data_as(ctypes.POINTER(ctypes.c_float)) - result = whisper_cpp.whisper_full( + result = self.instance.full( self.ctx, params, whisper_cpp_audio, len(audio) ) if result != 0: raise Exception(f"Error from whisper.cpp: {result}") - n_segments = whisper_cpp.whisper_full_n_segments(self.ctx) + n_segments = self.instance.full_n_segments(self.ctx) if params.token_timestamps: # Will process word timestamps @@ -61,9 +83,9 @@ def transcribe(self, audio: Union[np.ndarray, str], params: Any): txt_end = 0 for i in range(n_segments): - txt = whisper_cpp.whisper_full_get_segment_text(self.ctx, i) - start = whisper_cpp.whisper_full_get_segment_t0(self.ctx, i) - end = whisper_cpp.whisper_full_get_segment_t1(self.ctx, i) + txt = self.instance.full_get_segment_text(self.ctx, i) + start = self.instance.full_get_segment_t0(self.ctx, i) + end = self.instance.full_get_segment_t1(self.ctx, i) if txt.startswith(b' ') and self.append_segment(txt_buffer, txt_start, txt_end): txt_buffer = txt @@ -87,9 +109,9 @@ def transcribe(self, audio: Union[np.ndarray, str], params: Any): else: for i in range(n_segments): - txt = whisper_cpp.whisper_full_get_segment_text(self.ctx, i) - start = whisper_cpp.whisper_full_get_segment_t0(self.ctx, i) - end = whisper_cpp.whisper_full_get_segment_t1(self.ctx, i) + txt = self.instance.full_get_segment_text(self.ctx, i) + start = self.instance.full_get_segment_t0(self.ctx, i) + end = self.instance.full_get_segment_t1(self.ctx, i) self.append_segment(txt, start, end) @@ -98,30 +120,134 @@ def transcribe(self, audio: Union[np.ndarray, str], params: Any): "text": "".join([segment.text for segment in self.segments]), } + def get_instance(self): + if self.is_coreml_supported: + return WhisperCppCoreML() + return WhisperCppCpu() + + def get_params( + self, + transcription_options: TranscriptionOptions, + print_realtime=False, + print_progress=False, + ): + params = self.instance.full_default_params(whisper_cpp.WHISPER_SAMPLING_GREEDY) + params.n_threads = int(os.getenv("BUZZ_WHISPERCPP_N_THREADS", 4)) + params.print_realtime = print_realtime + params.print_progress = print_progress + params.language = self.instance.get_string((transcription_options.language or "en")) + params.translate = transcription_options.task == Task.TRANSLATE + params.max_len = ctypes.c_int(1) + params.max_len = 1 if transcription_options.word_level_timings else 0 + params.token_timestamps = transcription_options.word_level_timings + params.initial_prompt = self.instance.get_string(transcription_options.initial_prompt) + return params + def __del__(self): - whisper_cpp.whisper_free(self.ctx) - - -def whisper_cpp_params( - transcription_options: TranscriptionOptions, - print_realtime=False, - print_progress=False, -): - params = whisper_cpp.whisper_full_default_params( - whisper_cpp.WHISPER_SAMPLING_GREEDY - ) - params.n_threads = int(os.getenv("BUZZ_WHISPERCPP_N_THREADS", 4)) - params.print_realtime = print_realtime - params.print_progress = print_progress - - params.language = whisper_cpp.String( - (transcription_options.language or "en").encode() - ) - params.translate = transcription_options.task == Task.TRANSLATE - params.max_len = ctypes.c_int(1) - params.max_len = 1 if transcription_options.word_level_timings else 0 - params.token_timestamps = transcription_options.word_level_timings - params.initial_prompt = whisper_cpp.String( - transcription_options.initial_prompt.encode() - ) - return params + if self.instance: + self.instance.free(self.ctx) + + +class WhisperCppInterface: + def full_default_params(self, sampling: int): + raise NotImplementedError + + def get_string(self, string: str): + raise NotImplementedError + + def get_encoder_begin_callback(self, callback): + raise NotImplementedError + + def get_new_segment_callback(self, callback): + raise NotImplementedError + + def init_from_file(self, model: str): + raise NotImplementedError + + def full(self, ctx, params, audio, length): + raise NotImplementedError + + def full_n_segments(self, ctx): + raise NotImplementedError + + def full_get_segment_text(self, ctx, i): + raise NotImplementedError + + def full_get_segment_t0(self, ctx, i): + raise NotImplementedError + + def full_get_segment_t1(self, ctx, i): + raise NotImplementedError + + def free(self, ctx): + raise NotImplementedError + + +class WhisperCppCpu(WhisperCppInterface): + def full_default_params(self, sampling: int): + return whisper_cpp.whisper_full_default_params(sampling) + + def get_string(self, string: str): + return whisper_cpp.String(string.encode()) + + def get_encoder_begin_callback(self, callback): + return whisper_cpp.whisper_encoder_begin_callback(callback) + + def get_new_segment_callback(self, callback): + return whisper_cpp.whisper_new_segment_callback(callback) + + def init_from_file(self, model: str): + return whisper_cpp.whisper_init_from_file(model.encode()) + + def full(self, ctx, params, audio, length): + return whisper_cpp.whisper_full(ctx, params, audio, length) + + def full_n_segments(self, ctx): + return whisper_cpp.whisper_full_n_segments(ctx) + + def full_get_segment_text(self, ctx, i): + return whisper_cpp.whisper_full_get_segment_text(ctx, i) + + def full_get_segment_t0(self, ctx, i): + return whisper_cpp.whisper_full_get_segment_t0(ctx, i) + + def full_get_segment_t1(self, ctx, i): + return whisper_cpp.whisper_full_get_segment_t1(ctx, i) + + def free(self, ctx): + return whisper_cpp.whisper_free(ctx) + + +class WhisperCppCoreML(WhisperCppInterface): + def full_default_params(self, sampling: int): + return whisper_cpp_coreml.whisper_full_default_params(sampling) + + def get_string(self, string: str): + return whisper_cpp_coreml.String(string.encode()) + + def get_encoder_begin_callback(self, callback): + return whisper_cpp_coreml.whisper_encoder_begin_callback(callback) + + def get_new_segment_callback(self, callback): + return whisper_cpp_coreml.whisper_new_segment_callback(callback) + + def init_from_file(self, model: str): + return whisper_cpp_coreml.whisper_init_from_file(model.encode()) + + def full(self, ctx, params, audio, length): + return whisper_cpp_coreml.whisper_full(ctx, params, audio, length) + + def full_n_segments(self, ctx): + return whisper_cpp_coreml.whisper_full_n_segments(ctx) + + def full_get_segment_text(self, ctx, i): + return whisper_cpp_coreml.whisper_full_get_segment_text(ctx, i) + + def full_get_segment_t0(self, ctx, i): + return whisper_cpp_coreml.whisper_full_get_segment_t0(ctx, i) + + def full_get_segment_t1(self, ctx, i): + return whisper_cpp_coreml.whisper_full_get_segment_t1(ctx, i) + + def free(self, ctx): + return whisper_cpp_coreml.whisper_free(ctx) diff --git a/buzz/transcriber/whisper_cpp_file_transcriber.py b/buzz/transcriber/whisper_cpp_file_transcriber.py index 57dba762b..953a4ca61 100644 --- a/buzz/transcriber/whisper_cpp_file_transcriber.py +++ b/buzz/transcriber/whisper_cpp_file_transcriber.py @@ -6,13 +6,9 @@ from PyQt6.QtCore import QObject from buzz import whisper_audio -from buzz.model_loader import LOADED_WHISPER_CPP_BINARY from buzz.transcriber.file_transcriber import FileTranscriber from buzz.transcriber.transcriber import FileTranscriptionTask, Segment, Stopped -from buzz.transcriber.whisper_cpp import WhisperCpp, whisper_cpp_params - -if LOADED_WHISPER_CPP_BINARY: - from buzz import whisper_cpp +from buzz.transcriber.whisper_cpp import WhisperCpp class WhisperCppFileTranscriber(FileTranscriber): @@ -29,11 +25,11 @@ def __init__( self.transcription_options = task.transcription_options self.model_path = task.model_path + self.model = WhisperCpp(model=self.model_path) self.state = self.State() def transcribe(self) -> List[Segment]: self.state.running = True - model_path = self.model_path logging.debug( "Starting whisper_cpp file transcription, file path = %s, language = %s, " @@ -41,29 +37,28 @@ def transcribe(self) -> List[Segment]: self.transcription_task.file_path, self.transcription_options.language, self.transcription_options.task, - model_path, + self.model_path, self.transcription_options.word_level_timings, ) audio = whisper_audio.load_audio(self.transcription_task.file_path) self.duration_audio_ms = len(audio) * 1000 / whisper_audio.SAMPLE_RATE - whisper_params = whisper_cpp_params( + whisper_params = self.model.get_params( transcription_options=self.transcription_options ) whisper_params.encoder_begin_callback_user_data = ctypes.c_void_p( id(self.state) ) whisper_params.encoder_begin_callback = ( - whisper_cpp.whisper_encoder_begin_callback(self.encoder_begin_callback) + self.model.get_instance().get_encoder_begin_callback(self.encoder_begin_callback) ) whisper_params.new_segment_callback_user_data = ctypes.c_void_p(id(self.state)) - whisper_params.new_segment_callback = whisper_cpp.whisper_new_segment_callback( + whisper_params.new_segment_callback = self.model.get_instance().get_new_segment_callback( self.new_segment_callback ) - model = WhisperCpp(model=model_path) - result = model.transcribe( + result = self.model.transcribe( audio=self.transcription_task.file_path, params=whisper_params ) @@ -74,8 +69,8 @@ def transcribe(self) -> List[Segment]: return result["segments"] def new_segment_callback(self, ctx, _state, _n_new, user_data): - n_segments = whisper_cpp.whisper_full_n_segments(ctx) - t1 = whisper_cpp.whisper_full_get_segment_t1(ctx, n_segments - 1) + n_segments = self.model.get_instance().full_n_segments(ctx) + t1 = self.model.get_instance().full_get_segment_t1(ctx, n_segments - 1) # t1 seems to sometimes be larger than the duration when the # audio ends in silence. Trim to fix the displayed progress. progress = min(t1 * 10, self.duration_audio_ms) diff --git a/buzz/widgets/icon.py b/buzz/widgets/icon.py index 36616da5f..4dca94c4f 100644 --- a/buzz/widgets/icon.py +++ b/buzz/widgets/icon.py @@ -92,6 +92,7 @@ def __init__(self, parent: QWidget): BUZZ_ICON_PATH = get_path("assets/buzz.ico") BUZZ_LARGE_ICON_PATH = get_path("assets/buzz-icon-1024.png") +INFO_ICON_PATH = get_path("assets/info-circle.svg") RECORD_ICON_PATH = get_path("assets/mic_FILL0_wght700_GRAD0_opsz48.svg") EXPAND_ICON_PATH = get_path("assets/open_in_full_FILL0_wght700_GRAD0_opsz48.svg") ADD_ICON_PATH = get_path("assets/add_FILL0_wght700_GRAD0_opsz48.svg") diff --git a/buzz/widgets/preferences_dialog/general_preferences_widget.py b/buzz/widgets/preferences_dialog/general_preferences_widget.py index c46b58f42..b68853dec 100644 --- a/buzz/widgets/preferences_dialog/general_preferences_widget.py +++ b/buzz/widgets/preferences_dialog/general_preferences_widget.py @@ -56,6 +56,7 @@ def __init__( self.on_openai_api_key_changed ) self.openai_api_key_line_edit.focus_out.connect(self.on_openai_api_key_focus_out) + self.openai_api_key_line_edit.setMinimumWidth(200) self.test_openai_api_key_button = QPushButton(_("Test")) self.test_openai_api_key_button.clicked.connect( diff --git a/buzz/widgets/preferences_dialog/models_preferences_widget.py b/buzz/widgets/preferences_dialog/models_preferences_widget.py index 5f569f541..479f58e65 100644 --- a/buzz/widgets/preferences_dialog/models_preferences_widget.py +++ b/buzz/widgets/preferences_dialog/models_preferences_widget.py @@ -85,6 +85,7 @@ def __init__( self.custom_model_id_input.hide() self.custom_model_link_input = LineEdit() + self.custom_model_link_input.setMinimumWidth(255) self.custom_model_link_input.setObjectName("ModelLinkInput") self.custom_model_link_input.textChanged.connect(self.on_custom_model_link_input_changed) layout.addRow("", self.custom_model_link_input) diff --git a/buzz/widgets/transcriber/hugging_face_search_line_edit.py b/buzz/widgets/transcriber/hugging_face_search_line_edit.py index e6d7239da..f686cf4c6 100644 --- a/buzz/widgets/transcriber/hugging_face_search_line_edit.py +++ b/buzz/widgets/transcriber/hugging_face_search_line_edit.py @@ -36,7 +36,7 @@ def __init__( self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) self.setPlaceholderText(_("Huggingface ID of a model")) - self.setMinimumWidth(150) + self.setMinimumWidth(255) self.timer = QTimer(self) self.timer.setSingleShot(True) diff --git a/buzz/widgets/transcriber/transcription_options_group_box.py b/buzz/widgets/transcriber/transcription_options_group_box.py index a02f45c53..5611ae2f6 100644 --- a/buzz/widgets/transcriber/transcription_options_group_box.py +++ b/buzz/widgets/transcriber/transcription_options_group_box.py @@ -1,12 +1,15 @@ import os import logging +import platform from typing import Optional, List from PyQt6.QtCore import pyqtSignal -from PyQt6.QtWidgets import QGroupBox, QWidget, QFormLayout, QComboBox +from PyQt6.QtGui import QIcon +from PyQt6.QtWidgets import QGroupBox, QWidget, QFormLayout, QComboBox, QLabel, QHBoxLayout from buzz.locale import _ from buzz.settings.settings import Settings +from buzz.widgets.icon import INFO_ICON_PATH from buzz.model_loader import ModelType, WhisperModelSize, get_whisper_cpp_file_path from buzz.transcriber.transcriber import TranscriptionOptions, Task from buzz.widgets.model_type_combo_box import ModelTypeComboBox @@ -87,7 +90,26 @@ def __init__( self.advanced_settings_button.clicked.connect(self.open_advanced_settings) self.form_layout.addRow(_("Model:"), self.model_type_combo_box) - self.form_layout.addRow("", self.whisper_model_size_combo_box) + + if platform.system() == "Darwin" and platform.machine() == "arm64": + self.whisper_model_size_layout = QHBoxLayout() + self.whisper_model_size_layout.setContentsMargins(0, 0, 0, 0) + self.whisper_model_size_layout.setSpacing(0) + + self.whisper_model_size_layout.addWidget(self.whisper_model_size_combo_box) + + self.load_note_tooltip_icon = QLabel() + self.load_note_tooltip_icon.setPixmap(QIcon(INFO_ICON_PATH).pixmap(23, 23)) + self.load_note_tooltip_icon.setToolTip( + _("First time use of a model may take up to several minutest to load.")) + self.whisper_model_size_layout.addWidget(self.load_note_tooltip_icon) + + self.form_layout.addRow("", self.whisper_model_size_layout) + else: + self.load_note_tooltip_icon = None + self.whisper_model_size_layout = None + self.form_layout.addRow("", self.whisper_model_size_combo_box) + self.form_layout.addRow("", self.hugging_face_search_line_edit) self.form_layout.addRow(_("Api Key:"), self.openai_access_token_edit) self.form_layout.addRow(_("Task:"), self.tasks_combo_box) @@ -176,10 +198,24 @@ def reset_visible_rows(self): or (model_type == ModelType.WHISPER_CPP) or (model_type == ModelType.FASTER_WHISPER), ) + if self.whisper_model_size_layout is not None: + self.form_layout.setRowVisible( + self.whisper_model_size_layout, + (model_type == ModelType.WHISPER) + or (model_type == ModelType.WHISPER_CPP) + or (model_type == ModelType.FASTER_WHISPER), + ) + self.form_layout.setRowVisible( self.openai_access_token_edit, model_type == ModelType.OPEN_AI_WHISPER_API ) + # Note on Apple Silicon Macs + if self.load_note_tooltip_icon is not None: + self.load_note_tooltip_icon.setVisible( + self.transcription_options.model.model_type == ModelType.WHISPER_CPP + ) + def on_model_type_changed(self, model_type: ModelType): self.transcription_options.model.model_type = model_type if not model_type.supports_initial_prompt: diff --git a/pyproject.toml b/pyproject.toml index cad0580e1..791d2c412 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Chidi Williams "] license = "MIT" readme = "README.md" include = [ - "buzz/libwhisper.*", "buzz/*.dll", "buzz/whisper_cpp.py", "buzz/locale/*/LC_MESSAGES/buzz.mo", + "buzz/libwhisper.*", "buzz/libwhisper-coreml.*", "buzz/*.dll", "buzz/whisper_cpp.py", "buzz/locale/*/LC_MESSAGES/buzz.mo", "buzz/dll_backup/*", ] repository = "https://github.com/chidiwilliams/buzz" diff --git a/tests/transcriber/whisper_cpp_test.py b/tests/transcriber/whisper_cpp_test.py index 1125484ea..8076c26e1 100644 --- a/tests/transcriber/whisper_cpp_test.py +++ b/tests/transcriber/whisper_cpp_test.py @@ -1,6 +1,6 @@ from buzz.model_loader import TranscriptionModel, ModelType, WhisperModelSize from buzz.transcriber.transcriber import TranscriptionOptions, Task -from buzz.transcriber.whisper_cpp import WhisperCpp, whisper_cpp_params +from buzz.transcriber.whisper_cpp import WhisperCpp from tests.audio import test_audio_path from tests.model_loader import get_model_path @@ -19,7 +19,7 @@ def test_transcribe(self): model_path = get_model_path(transcription_options.model) whisper_cpp = WhisperCpp(model=model_path) - params = whisper_cpp_params(transcription_options=transcription_options) + params = whisper_cpp.get_params(transcription_options=transcription_options) result = whisper_cpp.transcribe(audio=test_audio_path, params=params) assert "Bienvenue dans Passe" in result["text"]