pygpt-net 2.4.53__py3-none-any.whl → 2.4.55__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. CHANGELOG.md +10 -0
  2. README.md +18 -1
  3. pygpt_net/CHANGELOG.txt +10 -0
  4. pygpt_net/__init__.py +3 -3
  5. pygpt_net/controller/lang/mapping.py +2 -1
  6. pygpt_net/core/audio/capture.py +2 -1
  7. pygpt_net/data/config/config.json +5 -3
  8. pygpt_net/data/config/models.json +3 -3
  9. pygpt_net/data/config/modes.json +3 -3
  10. pygpt_net/data/config/settings.json +24 -0
  11. pygpt_net/data/locale/locale.de.ini +3 -0
  12. pygpt_net/data/locale/locale.en.ini +3 -0
  13. pygpt_net/data/locale/locale.es.ini +3 -0
  14. pygpt_net/data/locale/locale.fr.ini +3 -0
  15. pygpt_net/data/locale/locale.it.ini +3 -0
  16. pygpt_net/data/locale/locale.pl.ini +4 -1
  17. pygpt_net/data/locale/locale.uk.ini +3 -0
  18. pygpt_net/data/locale/locale.zh.ini +3 -0
  19. pygpt_net/data/win32/USER-LICENSE.rtf +0 -0
  20. pygpt_net/plugin/audio_input/simple.py +23 -7
  21. pygpt_net/plugin/audio_input/worker.py +8 -5
  22. pygpt_net/plugin/audio_output/__init__.py +47 -12
  23. pygpt_net/plugin/audio_output/worker.py +114 -20
  24. pygpt_net/provider/core/config/patch.py +9 -1
  25. pygpt_net/ui/__init__.py +2 -1
  26. pygpt_net/ui/dialog/snap.py +3 -2
  27. pygpt_net/ui/layout/chat/input.py +4 -1
  28. pygpt_net/ui/widget/audio/bar.py +103 -0
  29. pygpt_net/ui/widget/audio/input_button.py +5 -46
  30. pygpt_net/ui/widget/dialog/snap.py +37 -6
  31. {pygpt_net-2.4.53.dist-info → pygpt_net-2.4.55.dist-info}/METADATA +19 -2
  32. {pygpt_net-2.4.53.dist-info → pygpt_net-2.4.55.dist-info}/RECORD +35 -34
  33. {pygpt_net-2.4.53.dist-info → pygpt_net-2.4.55.dist-info}/LICENSE +0 -0
  34. {pygpt_net-2.4.53.dist-info → pygpt_net-2.4.55.dist-info}/WHEEL +0 -0
  35. {pygpt_net-2.4.53.dist-info → pygpt_net-2.4.55.dist-info}/entry_points.txt +0 -0
CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 2.4.55 (2025-01-18)
4
+
5
+ - Added a new option in settings: Audio -> Recording timeout.
6
+ - Added a new option in settings: Audio -> Enable timeout in continuous mode.
7
+
8
+ ## 2.4.54 (2025-01-18)
9
+
10
+ - Audio output switched from PyGame to PyAudio. It may be necessary to manually connect Alsa in Snap version with: "sudo snap connect pygpt:alsa".
11
+ - Added audio output volume progress bar.
12
+
3
13
  ## 2.4.53 (2025-01-17)
4
14
 
5
15
  - Fix: issue #89
README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![pygpt](https://snapcraft.io/pygpt/badge.svg)](https://snapcraft.io/pygpt)
4
4
 
5
- Release: **2.4.53** | build: **2025.01.17** | Python: **>=3.10, <3.13**
5
+ Release: **2.4.55** | build: **2025.01.18** | Python: **>=3.10, <3.13**
6
6
 
7
7
  > Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
8
8
  >
@@ -121,6 +121,13 @@ sudo snap connect pygpt:audio-record :audio-record
121
121
  sudo snap connect pygpt:alsa
122
122
  ```
123
123
 
124
+ **Using audio output:** to use audio output in Snap version you must connect the audio with:
125
+
126
+ ```commandline
127
+ sudo snap connect pygpt:audio-playback
128
+ sudo snap connect pygpt:alsa
129
+ ```
130
+
124
131
  **Connecting IPython in Docker in Snap version**:
125
132
 
126
133
  To use IPython in the Snap version, you must connect PyGPT to the Docker daemon:
@@ -3953,6 +3960,16 @@ may consume additional tokens that are not displayed in the main window.
3953
3960
 
3954
3961
  ## Recent changes:
3955
3962
 
3963
+ **2.4.55 (2025-01-18)**
3964
+
3965
+ - Added a new option in settings: Audio -> Recording timeout.
3966
+ - Added a new option in settings: Audio -> Enable timeout in continuous mode.
3967
+
3968
+ **2.4.54 (2025-01-18)**
3969
+
3970
+ - Audio output switched from PyGame to PyAudio. It may be necessary to manually connect Alsa in Snap version with: "sudo snap connect pygpt:alsa".
3971
+ - Added audio output volume progress bar.
3972
+
3956
3973
  **2.4.53 (2025-01-17)**
3957
3974
 
3958
3975
  - Fix: issue #89
pygpt_net/CHANGELOG.txt CHANGED
@@ -1,3 +1,13 @@
1
+ 2.4.55 (2025-01-18)
2
+
3
+ - Added a new option in settings: Audio -> Recording timeout.
4
+ - Added a new option in settings: Audio -> Enable timeout in continuous mode.
5
+
6
+ 2.4.54 (2025-01-18)
7
+
8
+ - Audio output switched from PyGame to PyAudio. It may be necessary to manually connect Alsa in Snap version with: "sudo snap connect pygpt:alsa".
9
+ - Added audio output volume progress bar.
10
+
1
11
  2.4.53 (2025-01-17)
2
12
 
3
13
  - Fix: issue #89
pygpt_net/__init__.py CHANGED
@@ -6,15 +6,15 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.01.17 13:00:00 #
9
+ # Updated Date: 2025.01.18 16:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  __author__ = "Marcin Szczygliński"
13
13
  __copyright__ = "Copyright 2025, Marcin Szczygliński"
14
14
  __credits__ = ["Marcin Szczygliński"]
15
15
  __license__ = "MIT"
16
- __version__ = "2.4.53"
17
- __build__ = "2025.01.17"
16
+ __version__ = "2.4.55"
17
+ __build__ = "2025.01.18"
18
18
  __maintainer__ = "Marcin Szczygliński"
19
19
  __github__ = "https://github.com/szczyglis-dev/py-gpt"
20
20
  __report__ = "https://github.com/szczyglis-dev/py-gpt/issues"
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.01.16 01:00:00 #
9
+ # Updated Date: 2025.01.18 16:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Dict
@@ -145,6 +145,7 @@ class Mapping:
145
145
  nodes["agent.iterations.label"] = "toolbox.agent.iterations.label"
146
146
  nodes["agent.auto_stop"] = "toolbox.agent.auto_stop.label"
147
147
  nodes["agent.continue"] = "toolbox.agent.continue.label"
148
+ nodes['layout.split'] = "layout.split"
148
149
  # nodes["indexes.new"] = "idx.new"
149
150
 
150
151
  # input
@@ -333,10 +333,10 @@ class Capture:
333
333
  :return: True if working
334
334
  """
335
335
  import pyaudio
336
+ p = pyaudio.PyAudio()
336
337
  try:
337
338
  rate = 44100
338
339
  channels = 1
339
- p = pyaudio.PyAudio()
340
340
  stream = p.open(format=pyaudio.paInt16,
341
341
  channels=channels,
342
342
  rate=rate,
@@ -346,4 +346,5 @@ class Capture:
346
346
  p.terminate()
347
347
  return True
348
348
  except Exception as e:
349
+ p.terminate()
349
350
  return False
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.4.53",
4
- "app.version": "2.4.53",
5
- "updated_at": "2025-01-17T00:00:00"
3
+ "version": "2.4.55",
4
+ "app.version": "2.4.55",
5
+ "updated_at": "2025-01-18T00:00:00"
6
6
  },
7
7
  "access.audio.event.speech": false,
8
8
  "access.audio.event.speech.disabled": [],
@@ -78,6 +78,8 @@
78
78
  "audio.input.device": "0",
79
79
  "audio.input.rate": 44100,
80
80
  "audio.input.stop_interval": 10,
81
+ "audio.input.timeout": 120,
82
+ "audio.input.timeout.continuous": false,
81
83
  "audio.transcribe.convert_video": true,
82
84
  "context_threshold": 200,
83
85
  "cmd": false,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.4.53",
4
- "app.version": "2.4.53",
5
- "updated_at": "2025-01-17T00:00:00"
3
+ "version": "2.4.55",
4
+ "app.version": "2.4.55",
5
+ "updated_at": "2025-01-18T00:00:00"
6
6
  },
7
7
  "items": {
8
8
  "claude-3-5-sonnet-20240620": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.4.53",
4
- "app.version": "2.4.53",
5
- "updated_at": "2025-01-17T00:00:00"
3
+ "version": "2.4.55",
4
+ "app.version": "2.4.55",
5
+ "updated_at": "2025-01-18T00:00:00"
6
6
  },
7
7
  "items": {
8
8
  "chat": {
@@ -1136,6 +1136,30 @@
1136
1136
  "step": 1,
1137
1137
  "advanced": false
1138
1138
  },
1139
+ "audio.input.timeout": {
1140
+ "section": "audio",
1141
+ "type": "int",
1142
+ "slider": false,
1143
+ "label": "settings.audio.input.timeout",
1144
+ "description": "settings.audio.input.timeout.desc",
1145
+ "value": 120,
1146
+ "min": 0,
1147
+ "multiplier": 1,
1148
+ "step": 1,
1149
+ "advanced": false
1150
+ },
1151
+ "audio.input.timeout.continuous": {
1152
+ "section": "audio",
1153
+ "type": "bool",
1154
+ "slider": false,
1155
+ "label": "settings.audio.input.timeout.continuous",
1156
+ "value": false,
1157
+ "min": null,
1158
+ "max": null,
1159
+ "multiplier": null,
1160
+ "step": null,
1161
+ "advanced": false
1162
+ },
1139
1163
  "llama.idx.list": {
1140
1164
  "section": "llama-index",
1141
1165
  "type": "dict",
@@ -777,6 +777,9 @@ settings.audio.input.rate = Abtastrate
777
777
  settings.audio.input.rate.desc = Abtastrate, Standard: 44100
778
778
  settings.audio.input.stop_interval = Intervall für kontinuierliche automatische Transkription
779
779
  settings.audio.input.stop_interval.desc = Intervall in Sekunden für automatisches Transkribieren eines Audioabschnitts, Standard: 10
780
+ settings.audio.input.timeout = Aufnahme-Zeitüberschreitung
781
+ settings.audio.input.timeout.desc = Zeitüberschreitung (Sekunden) für automatische Stop-Aufzeichnung, 0 zum Deaktivieren, Standard: 120
782
+ settings.audio.input.timeout.continuous = Zeitüberschreitung im Dauerbetrieb aktivieren
780
783
  settings.check_updates = Beim Start nach Updates suchen
781
784
  settings.check_updates.bg = Im Hintergrund nach Updates suchen
782
785
  settings.cmd.field.desc = Aktivieren Sie das `{cmd}`-Werkzeug.
@@ -948,6 +948,9 @@ settings.audio.input.rate = Sampling Rate
948
948
  settings.audio.input.rate.desc = Sampling rate, default: 44100
949
949
  settings.audio.input.stop_interval = Continuous recording auto-transcribe interval
950
950
  settings.audio.input.stop_interval.desc = Interval in seconds for auto-transcribe audio chunk, default: 10
951
+ settings.audio.input.timeout = Recording timeout
952
+ settings.audio.input.timeout.desc = Timeout (seconds) for auto-stop recording, 0 to disable, default: 120
953
+ settings.audio.input.timeout.continuous = Enable timeout in continuous mode
951
954
  settings.check_updates = Check for Updates on start
952
955
  settings.check_updates.bg = Check for Updates in the background
953
956
  settings.cmd.config.collapse = JSON params
@@ -776,6 +776,9 @@ settings.audio.input.rate = Taux d'échantillonnage
776
776
  settings.audio.input.rate.desc = Taux d'échantillonnage, par défaut : 44100
777
777
  settings.audio.input.stop_interval = Intervalo de transcripción automática continua
778
778
  settings.audio.input.stop_interval.desc = Intervalo en segundos para transcribir automáticamente el fragmento de audio, predeterminado: 10
779
+ settings.audio.input.timeout = Tiempo de espera de grabación
780
+ settings.audio.input.timeout.desc = Tiempo de espera (segundos) para detener la grabación automáticamente, 0 para deshabilitar, por defecto: 120
781
+ settings.audio.input.timeout.continuous = Habilitar tiempo de espera en modo continuo
779
782
  settings.check_updates = Buscar actualizaciones al iniciar
780
783
  settings.check_updates.bg = Buscar actualizaciones en segundo plano
781
784
  settings.cmd.field.desc = Habilitar la herramienta `{cmd}`.
@@ -776,6 +776,9 @@ settings.audio.input.rate = Taux d'échantillonnage
776
776
  settings.audio.input.rate.desc = Taux d'échantillonnage, par défaut : 44100
777
777
  settings.audio.input.stop_interval = Intervalle d'auto-transcription enregistrement continu
778
778
  settings.audio.input.stop_interval.desc = Intervalle en secondes pour la transcription automatique d'un morceau audio, par défaut : 10
779
+ settings.audio.input.timeout = Délai d'enregistrement
780
+ settings.audio.input.timeout.desc = Délai (secondes) pour l'arrêt automatique de l'enregistrement, 0 pour désactiver, par défaut : 120
781
+ settings.audio.input.timeout.continuous = Activer le délai en mode continu
779
782
  settings.check_updates = Vérifier les mises à jour au démarrage
780
783
  settings.check_updates.bg = Vérifier les mises à jour en arrière-plan
781
784
  settings.cmd.field.desc = Activer l'outil `{cmd}`.
@@ -777,6 +777,9 @@ settings.audio.input.rate = Frequenza di campionamento
777
777
  settings.audio.input.rate.desc = Frequenza di campionamento, predefinito: 44100
778
778
  settings.audio.input.stop_interval = Intervallo di trascrizione automatica continua
779
779
  settings.audio.input.stop_interval.desc = Intervallo in secondi per la trascrizione automatica del segmento audio, predefinito: 10
780
+ settings.audio.input.timeout = Timeout di registrazione
781
+ settings.audio.input.timeout.desc = Timeout (secondi) per l'arresto automatico della registrazione, 0 per disabilitare, predefinito: 120
782
+ settings.audio.input.timeout.continuous = Abilita timeout in modalità continua
780
783
  settings.check_updates = Controlla aggiornamenti all'avvio
781
784
  settings.check_updates.bg = Controlla gli aggiornamenti in background
782
785
  settings.cmd.field.desc = Abilita lo strumento `{cmd}`.
@@ -776,7 +776,10 @@ settings.audio.input.device.desc = Wybierz urządzenie audio dla wejścia mikrof
776
776
  settings.audio.input.rate = Częstotliwość próbkowania
777
777
  settings.audio.input.rate.desc = Częstotliwość próbkowania, domyślnie: 44100
778
778
  settings.audio.input.stop_interval = Interwał automatycznego transkrybowania nagrania ciągłego
779
- settings.audio.input.stop_interval.desc = Interwał w sekundach dla automatycznego transkrybowania fragmentu audio, domyślnie: 10
779
+ settings.audio.input.stop_interval.desc = Interwał w sekundach dla automatycznego transkrybowania fragmentu audio, domyślnie: 10
780
+ settings.audio.input.timeout = Limit czasu nagrywania
781
+ settings.audio.input.timeout.desc = Limit czasu (w sekundach) dla automatycznego zatrzymania nagrywania, 0 aby wyłączyć, domyślnie: 120
782
+ settings.audio.input.timeout.continuous = Włącz limit czasu w trybie ciągłym
780
783
  settings.check_updates = Sprawdź aktualizacje przy starcie
781
784
  settings.check_updates.bg = Sprawdź aktualizacje w tle
782
785
  settings.cmd.field.desc = Włącz narzędzie `{cmd}`.
@@ -776,6 +776,9 @@ settings.audio.input.rate = Частота дискретизації
776
776
  settings.audio.input.rate.desc = Частота дискретизації, за замовчуванням: 44100
777
777
  settings.audio.input.stop_interval = Інтервал автоматичного транскрибування безперервного запису
778
778
  settings.audio.input.stop_interval.desc = Інтервал у секундах для автоматичного транскрибування фрагмента аудіо, за замовчуванням: 10
779
+ settings.audio.input.timeout = Тайм-аут запису
780
+ settings.audio.input.timeout.desc = Тайм-аут (в секундах) для автоматичної зупинки запису, 0 для відключення, за замовчуванням: 120
781
+ settings.audio.input.timeout.continuous = Увімкнути тайм-аут у безперервному режимі
779
782
  settings.check_updates = Перевіряти оновлення при запуску
780
783
  settings.check_updates.bg = Перевіряти оновлення у фоновому режимі
781
784
  settings.cmd.field.desc = Увімкнути інструмент `{cmd}`.
@@ -878,6 +878,9 @@ settings.audio.input.rate = 采样率
878
878
  settings.audio.input.rate.desc = 采样率,默认: 44100
879
879
  settings.audio.input.stop_interval = 连续录音自动转录间隔
880
880
  settings.audio.input.stop_interval.desc = 自动转录音频片段的间隔(以秒为单位),默认:10
881
+ settings.audio.input.timeout = 录音超时
882
+ settings.audio.input.timeout.desc = 自动停止录音的超时时间(秒),0为禁用,默认:120
883
+ settings.audio.input.timeout.continuous = 在连续模式下启用超时
881
884
  settings.check_updates = 啟動時檢查更新
882
885
  settings.check_updates.bg = 在後台檢查更新
883
886
  settings.cmd.field.desc = 启用 `{cmd}` 工具。
Binary file
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.01.17 02:00:00 #
9
+ # Updated Date: 2025.01.18 16:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -61,6 +61,19 @@ class Simple:
61
61
 
62
62
  :param force: True to force recording
63
63
  """
64
+ # display snap warning if not displayed yet
65
+ if (not self.plugin.window.core.config.get("audio.input.snap", False)
66
+ or not self.plugin.window.core.config.has("audio.input.snap")):
67
+ if self.plugin.window.core.platforms.is_snap():
68
+ self.plugin.window.ui.dialogs.open(
69
+ 'snap_audio_input',
70
+ width=400,
71
+ height=200
72
+ )
73
+ self.plugin.window.core.config.set("audio.input.snap", True)
74
+ self.plugin.window.core.config.save()
75
+ return
76
+
64
77
  # enable continuous mode if notepad tab is active
65
78
  self.plugin.window.core.audio.capture.stop_callback = self.on_stop
66
79
  continuous_enabled = self.plugin.window.core.config.get('audio.input.continuous', False)
@@ -71,8 +84,7 @@ class Simple:
71
84
 
72
85
  try:
73
86
  # stop audio output if playing
74
- if self.plugin.window.controller.audio.is_playing():
75
- self.plugin.window.controller.audio.stop_output()
87
+ self.plugin.window.controller.audio.stop_output()
76
88
 
77
89
  # set audio volume bar
78
90
  self.plugin.window.core.audio.capture.set_bar(
@@ -80,10 +92,14 @@ class Simple:
80
92
  )
81
93
 
82
94
  # start timeout timer to prevent infinite recording
83
- if self.timer is None:
84
- self.timer = QTimer()
85
- self.timer.timeout.connect(self.stop_timeout)
86
- self.timer.start(self.TIMEOUT_SECONDS * 1000)
95
+ # disable in continuous mode
96
+ timeout = int(self.plugin.window.core.config.get('audio.input.timeout', 120) or 0) # get timeout
97
+ timeout_continuous = self.plugin.window.core.config.get('audio.input.timeout.continuous', False) # enable continuous timeout
98
+ if timeout > 0:
99
+ if self.timer is None and (not continuous_enabled or timeout_continuous):
100
+ self.timer = QTimer()
101
+ self.timer.timeout.connect(self.stop_timeout)
102
+ self.timer.start(timeout * 1000)
87
103
 
88
104
  if not force:
89
105
  if not self.plugin.window.core.audio.capture.check_audio_input():
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.11.26 19:00:00 #
9
+ # Updated Date: 2025.01.18 03:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os.path
@@ -16,6 +16,7 @@ import audioop
16
16
 
17
17
  from PySide6.QtCore import Slot, Signal
18
18
 
19
+ from pygpt_net.core.tabs import Tab
19
20
  from pygpt_net.utils import trans
20
21
  from pygpt_net.plugin.base.worker import BaseWorker, BaseSignals
21
22
 
@@ -76,10 +77,12 @@ class Worker(BaseWorker):
76
77
  self.status(trans('audio.speak.wait'))
77
78
 
78
79
  # if multimodal audio, then only return path to audio file and do not transcribe
79
- if self.plugin.window.controller.chat.audio.enabled():
80
- self.signals.on_realtime.emit(self.path)
81
- self.status('')
82
- return
80
+ tab = self.window.controller.ui.tabs.get_current_tab()
81
+ if tab.type == Tab.TAB_CHAT:
82
+ if self.plugin.window.controller.chat.audio.enabled():
83
+ self.signals.on_realtime.emit(self.path)
84
+ self.status('')
85
+ return
83
86
 
84
87
  # transcribe audio
85
88
  transcript = self.plugin.get_provider().transcribe(self.path)
@@ -6,9 +6,11 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.12.14 18:00:00 #
9
+ # Updated Date: 2025.01.18 03:00:00 #
10
10
  # ================================================== #
11
11
 
12
+ from typing import Any
13
+
12
14
  from PySide6.QtCore import Slot
13
15
 
14
16
  from pygpt_net.core.types import MODE_AUDIO
@@ -35,6 +37,7 @@ class Plugin(BasePlugin):
35
37
  self.use_locale = True
36
38
  self.output_file = "output.mp3"
37
39
  self.config = Config(self)
40
+ self.worker = None
38
41
 
39
42
  def init_options(self):
40
43
  """Initialize options"""
@@ -171,10 +174,12 @@ class Plugin(BasePlugin):
171
174
  # check for audio read allowed. Prevents reading audio in commands, results, etc.
172
175
  if name == Event.CTX_AFTER:
173
176
  if not ctx.audio_read_allowed():
174
- return # abort if audio read is not allowed (commands, results, etc.)
175
-
177
+ return # abort if audio read is not allowed (commands, results, etc.)
178
+
176
179
  try:
177
180
  if text is not None and len(text) > 0:
181
+ self.stop_audio()
182
+
178
183
  worker = Worker()
179
184
  worker.from_defaults(self)
180
185
  worker.ctx = ctx
@@ -185,13 +190,16 @@ class Plugin(BasePlugin):
185
190
 
186
191
  # signals
187
192
  worker.signals.playback.connect(self.handle_playback)
193
+ worker.signals.error_playback.connect(self.handle_playback_error)
188
194
  worker.signals.stop.connect(self.handle_stop)
195
+ worker.signals.volume_changed.connect(self.handle_volume)
189
196
 
190
197
  worker.run_async()
198
+ self.worker = worker
191
199
 
192
200
  # only for manual reading
193
201
  if name == Event.AUDIO_READ_TEXT:
194
- self.window.controller.audio.on_begin(worker.text)
202
+ self.window.controller.audio.on_begin(self.worker.text)
195
203
 
196
204
  except Exception as e:
197
205
  self.error(e)
@@ -202,8 +210,10 @@ class Plugin(BasePlugin):
202
210
 
203
211
  :param ctx: CtxItem
204
212
  :param event: Event
205
- """
213
+ """
206
214
  try:
215
+ self.stop_audio()
216
+
207
217
  worker = Worker()
208
218
  worker.from_defaults(self)
209
219
  worker.audio_file = event.data["audio_file"]
@@ -211,9 +221,12 @@ class Plugin(BasePlugin):
211
221
 
212
222
  # signals
213
223
  worker.signals.playback.connect(self.handle_playback)
224
+ worker.signals.error_playback.connect(self.handle_playback_error)
214
225
  worker.signals.stop.connect(self.handle_stop)
226
+ worker.signals.volume_changed.connect(self.handle_volume)
215
227
 
216
228
  worker.run_async()
229
+ self.worker = worker
217
230
 
218
231
  except Exception as e:
219
232
  self.error(e)
@@ -250,22 +263,44 @@ class Plugin(BasePlugin):
250
263
 
251
264
  Stop playing the audio
252
265
  """
253
- if self.playback is not None:
254
- self.playback.stop()
255
- self.playback = None
266
+ if self.worker is not None:
267
+ self.worker.stop()
268
+ self.handle_volume(0.0)
256
269
 
257
- @Slot(object, str)
258
- def handle_playback(self, playback, event: str):
270
+ @Slot(object)
271
+ def handle_playback_error(self, err: Any):
272
+ """
273
+ Send error message to logger and alert dialog
274
+
275
+ :param err: error message
276
+ """
277
+ self.error(err)
278
+ if self.window.core.platforms.is_snap():
279
+ self.window.ui.dialogs.open(
280
+ 'snap_audio_output',
281
+ width=400,
282
+ height=200
283
+ )
284
+
285
+ @Slot(str)
286
+ def handle_playback(self, event: str):
259
287
  """
260
288
  Handle thread playback object
261
289
 
262
- :param playback: playback object
263
290
  :param event: event name
264
291
  """
265
- self.playback = playback
266
292
  self.window.controller.audio.on_play(event)
267
293
 
268
294
  @Slot()
269
295
  def handle_stop(self):
270
296
  """Handle thread playback stop"""
271
297
  self.stop_audio()
298
+
299
+ @Slot(float)
300
+ def handle_volume(self, volume: float):
301
+ """
302
+ Handle thread playback volume
303
+
304
+ :param volume: volume level
305
+ """
306
+ self.window.ui.plugin_addon['audio.output.bar'].setLevel(volume)