opencode-voice-dictation 0.6.0 → 0.6.2
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.
- package/README.md +84 -10
- package/docs/whisperx.md +182 -0
- package/package.json +3 -2
- package/src/whisper/server.ts +17 -3
package/README.md
CHANGED
|
@@ -15,6 +15,8 @@ escritorio:
|
|
|
15
15
|
cursor, sin robar el foco ni simular `Ctrl+V`.
|
|
16
16
|
- **Lectura natural**: voces neuronales de Edge (45 en español), con respaldo
|
|
17
17
|
a las voces del sistema si no hay internet.
|
|
18
|
+
- **WhisperX local (avanzado)**: dictado con WhisperX en WSL y GPU NVIDIA. Ver
|
|
19
|
+
[la guía](https://github.com/evious/opencode-voice-dictation/blob/main/docs/whisperx.md).
|
|
18
20
|
- **Solo Windows**: la app declara `os: ["windows"]`; en otros sistemas aparece
|
|
19
21
|
como no disponible en vez de fallar.
|
|
20
22
|
|
|
@@ -151,17 +153,38 @@ dictado, para que el micrófono no capture la voz del altavoz.
|
|
|
151
153
|
El texto se inserta en la posición del cursor. Si ya hay texto y no termina en
|
|
152
154
|
espacio, se añade uno de separación (configurable).
|
|
153
155
|
|
|
156
|
+
## Motores de dictado
|
|
157
|
+
|
|
158
|
+
| Motor | Requisitos | Estado |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| Windows Voice Typing (Win+H) | Windows 11, internet | Por defecto |
|
|
161
|
+
| System.Speech | Windows, offline | Disponible |
|
|
162
|
+
| WhisperX local (WSL) | WSL2 + Python + CUDA + NVIDIA | Avanzado · [guía](https://github.com/evious/opencode-voice-dictation/blob/main/docs/whisperx.md) |
|
|
163
|
+
| `whisper.cpp` nativo | Binario + modelo | Roadmap |
|
|
164
|
+
| Google Cloud Speech-to-Text | API key, internet | Roadmap |
|
|
165
|
+
| OpenAI (`gpt-4o-transcribe`) | API key, internet | Roadmap |
|
|
166
|
+
| Deepgram / AssemblyAI | API key, internet | Roadmap |
|
|
167
|
+
|
|
168
|
+
El motor se elige en **Ajustes → Dictado por voz → Motor de dictado**.
|
|
169
|
+
|
|
170
|
+
WhisperX es el único que requiere instalación manual: WSL2, un venv de Python
|
|
171
|
+
con `whisperx`/`torch` CUDA y una GPU NVIDIA. El resto funciona sin setup local.
|
|
172
|
+
|
|
154
173
|
## Ajustes
|
|
155
174
|
|
|
156
175
|
| Ajuste | Por defecto | Qué hace |
|
|
157
176
|
|---|---|---|
|
|
158
|
-
| Motor de dictado | Windows Voice Typing (Win+H) |
|
|
177
|
+
| Motor de dictado | Windows Voice Typing (Win+H) | Win+H, `System.Speech` offline o `WhisperX local (WSL)`. |
|
|
159
178
|
| Probar Win+H | — | Envía el atajo y comprueba que Windows abre su barra de dictado. |
|
|
160
179
|
| Idioma | `es-ES` | Solo para `System.Speech`. Reconocedor instalado en Windows. Si no existe el exacto, usa el mismo idioma base. |
|
|
161
180
|
| Confianza mínima | 0,4 | Solo para `System.Speech`. Descarta resultados con menor confianza. |
|
|
162
181
|
| Espacio antes del texto | Sí | Solo para `System.Speech`. Separa el dictado de lo que ya hay escrito. |
|
|
163
182
|
| Enfocar el prompt al terminar | Sí | Solo para `System.Speech`. Mueve el cursor al prompt tras cada frase. |
|
|
164
183
|
| Probar micrófono | — | Solo para `System.Speech`. Lista los idiomas instalados y comprueba el micrófono. |
|
|
184
|
+
| Python del entorno | Ruta del venv de WhisperX | Solo WhisperX. Python del venv con `whisperx`. |
|
|
185
|
+
| Modelo (WhisperX) | `large-v3-turbo` | Solo WhisperX. `large-v3` o `medium` si necesitas otra cosa. |
|
|
186
|
+
| Idioma (WhisperX) | Automático | Solo WhisperX. Autodetección o `es`, `en`, `pt`. |
|
|
187
|
+
| Comprobar WhisperX | — | Arranca el worker y valida GPU/modelo. |
|
|
165
188
|
|
|
166
189
|
### Lectura en voz alta
|
|
167
190
|
|
|
@@ -187,7 +210,14 @@ PowerShell (SAPI) no hay pausa real: el menú muestra solo «Leer de nuevo» y
|
|
|
187
210
|
|
|
188
211
|
## Permisos
|
|
189
212
|
|
|
190
|
-
El plugin
|
|
213
|
+
El plugin funciona en local salvo lo que elijas y use red:
|
|
214
|
+
|
|
215
|
+
- **WhisperX**: escribe el audio en `%TEMP%\opencode-voice-dictation`, lo pasa a
|
|
216
|
+
WSL y ejecuta el worker con tu venv. El audio no sale del equipo.
|
|
217
|
+
- **Edge**: envía el texto a Microsoft para sintetizar la voz (online).
|
|
218
|
+
- **Futuros motores en la nube**: enviarán el audio al proveedor que configures.
|
|
219
|
+
|
|
220
|
+
Para el dictado/lectura con Windows:
|
|
191
221
|
|
|
192
222
|
- Escribe un script `dictation-<hash>.ps1` o `speak-<hash>.ps1` en
|
|
193
223
|
`%TEMP%\opencode-voice-dictation`.
|
|
@@ -214,6 +244,9 @@ bloqueas el micrófono, verás el aviso «No hay ningún micrófono disponible»
|
|
|
214
244
|
| «Windows no tiene voces instaladas para la lectura» | Instala una voz en Configuración → Hora e idioma → Voz, o revisa que `System.Speech` esté disponible. El plugin usa primero las voces de Chromium y cae a SAPI si no hay. |
|
|
215
245
|
| La lectura se corta o no suena | Prueba «Probar voz» en Ajustes; si suena ahí, el problema es el dispositivo de salida de la app. |
|
|
216
246
|
| «Abre una conversación para leer su último mensaje» | En Home o en un chat nuevo sin mensajes no hay respuesta que leer. |
|
|
247
|
+
| WhisperX se queda en «Transcribiendo…» | El worker no arrancó. Mira el toast: ruta del Python, CUDA o token de Hugging Face. Guía: <https://github.com/evious/opencode-voice-dictation/blob/main/docs/whisperx.md>. |
|
|
248
|
+
| El RPC devuelve 400 o no cargan las voces de Edge | El plugin server no cargó: Ajustes → Extensiones → Plugins → **Reload**, o reinicia el servicio. |
|
|
249
|
+
| WhisperX pide token de Hugging Face | `huggingface-cli login` y acepta los términos del modelo de VAD de `pyannote`. |
|
|
217
250
|
|
|
218
251
|
Los errores del plugin se registran en el log de OpenCode Desktop; los `toast`
|
|
219
252
|
de la app muestran los más importantes.
|
|
@@ -224,6 +257,10 @@ de la app muestran los más importantes.
|
|
|
224
257
|
cambiar entre versiones de OpenCode.
|
|
225
258
|
- `System.Speech` no añade puntuación ni mayúsculas automáticamente y su
|
|
226
259
|
precisión es inferior a Whisper o al dictado nativo de Windows 11.
|
|
260
|
+
- **WhisperX local** requiere WSL2, Python, CUDA y una GPU NVIDIA. No es
|
|
261
|
+
portable: es un motor avanzado para equipos ya preparados.
|
|
262
|
+
- El primer dictado con WhisperX tarda 10–30 s porque carga el modelo en la GPU;
|
|
263
|
+
los siguientes son rápidos.
|
|
227
264
|
- El modo Win+H envía la combinación con `keybd_event`. Kaspersky o la
|
|
228
265
|
protección UIPI de Windows pueden bloquearla; en ese caso usa `System.Speech`.
|
|
229
266
|
- Con Win+H el texto lo escribe Windows en el campo enfocado: el plugin no
|
|
@@ -239,22 +276,56 @@ de la app muestran los más importantes.
|
|
|
239
276
|
- Si cambias de sesión durante el dictado, el texto se descarta con un aviso
|
|
240
277
|
para no escribirlo en la sesión equivocada.
|
|
241
278
|
|
|
242
|
-
El
|
|
243
|
-
|
|
244
|
-
|
|
279
|
+
El dictado vive en `src/gui` (Win+H y System.Speech) y en el servidor
|
|
280
|
+
(`src/whisper` para WhisperX y `src/edge.ts` para la lectura). Para añadir un
|
|
281
|
+
motor nuevo, consulta la sección siguiente.
|
|
282
|
+
|
|
283
|
+
## Añadir un motor de dictado nuevo
|
|
284
|
+
|
|
285
|
+
La ventana ya graba el audio (`getUserMedia` + `MediaRecorder`) y lo envía por
|
|
286
|
+
RPC al servidor. Eso es reutilizable para cualquier motor: local o en la nube.
|
|
287
|
+
|
|
288
|
+
1. **Contrato RPC** (`src/rpc.ts`): añade un método
|
|
289
|
+
`transcribe({ audio, mime, language, ... })` o uno por motor.
|
|
290
|
+
2. **Servidor** (`src/index.ts`): implementa el método. Para la nube, llama al
|
|
291
|
+
proveedor desde el servidor, nunca desde la ventana.
|
|
292
|
+
3. **Ajustes** (`src/gui/settings.tsx`): añade el motor al selector y sus campos
|
|
293
|
+
(API key, idioma, modelo).
|
|
294
|
+
4. **Ventana** (`src/gui/window.tsx`): enruta el modo del motor a la grabación y
|
|
295
|
+
al RPC; inserta con `composer.insert()` o copia con `ctx.system.copy()` si
|
|
296
|
+
quieres dictar hacia otra app.
|
|
297
|
+
|
|
298
|
+
Proveedores previstos:
|
|
299
|
+
|
|
300
|
+
- **Google Cloud Speech-to-Text**: cuenta de servicio o API key,
|
|
301
|
+
`@google-cloud/speech`, audio `WEBM_OPUS` o `LINEAR16` 16 kHz.
|
|
302
|
+
- **OpenAI**: `gpt-4o-transcribe` o `whisper-1`,
|
|
303
|
+
`POST /v1/audio/transcriptions`, API key.
|
|
304
|
+
- **Deepgram / AssemblyAI**: `POST /v1/listen`, API key.
|
|
305
|
+
- **`whisper.cpp` nativo**: binario + modelo `ggml`, sin WSL ni Python; la
|
|
306
|
+
opción más portable para uso local.
|
|
307
|
+
|
|
308
|
+
Las claves de API no deben viajar al renderer. Guárdalas en el store del plugin
|
|
309
|
+
o, mejor, en variables de entorno del servidor.
|
|
245
310
|
|
|
246
311
|
## Desarrollo
|
|
247
312
|
|
|
248
313
|
```
|
|
249
314
|
src/
|
|
250
|
-
├── index.ts Parte servidor:
|
|
315
|
+
├── index.ts Parte servidor: registra los RPC de Edge y WhisperX
|
|
316
|
+
├── rpc.ts Contrato RPC compartido (voces, síntesis, dictado)
|
|
317
|
+
├── edge.ts Voces y síntesis de Edge (servidor)
|
|
318
|
+
├── whisper/
|
|
319
|
+
│ ├── server.ts Worker persistente, spawn WSL/Node, timeouts
|
|
320
|
+
│ └── worker.py WhisperX en la GPU; protocolo JSON por stdin/stdout
|
|
251
321
|
├── gui.tsx Entrada ./gui-experimental
|
|
252
322
|
└── gui/
|
|
253
323
|
├── definition.ts os, stores, i18n es/en
|
|
254
324
|
├── contract.ts Ipc: dictado y lectura
|
|
255
325
|
├── window.tsx Píldoras, comandos e inserción de texto
|
|
256
|
-
├──
|
|
257
|
-
├──
|
|
326
|
+
├── recorder.ts getUserMedia + MediaRecorder para WhisperX
|
|
327
|
+
├── main.ts Dictado Win+H / System.Speech y voz SAPI
|
|
328
|
+
├── speak.ts Limpieza de Markdown, troceado, Edge y speechSynthesis
|
|
258
329
|
├── settings.tsx Página de ajustes
|
|
259
330
|
└── engines/
|
|
260
331
|
├── script.ts Script de PowerShell para el dictado
|
|
@@ -263,10 +334,13 @@ src/
|
|
|
263
334
|
└── sapi-speech.ts Voz de respaldo y listado de voces SAPI
|
|
264
335
|
```
|
|
265
336
|
|
|
337
|
+
La guía de WhisperX está en [`docs/whisperx.md`](docs/whisperx.md).
|
|
338
|
+
|
|
266
339
|
`npm run typecheck` valida los tipos, `npm run build` genera el bundle CJS y
|
|
267
340
|
`npm test` ejecuta el smoke test (`test/smoke.cjs`): simula el host de la app,
|
|
268
|
-
un `powershell.exe` falso
|
|
269
|
-
lectura, limpieza de Markdown,
|
|
341
|
+
un `powershell.exe` falso, la API de voz del navegador, el RPC de Edge y la
|
|
342
|
+
grabadora de WhisperX para comprobar dictado, lectura, limpieza de Markdown,
|
|
343
|
+
pausa, cancelación, fallback y errores.
|
|
270
344
|
|
|
271
345
|
## Publicar
|
|
272
346
|
|
package/docs/whisperx.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Dictado con WhisperX local (Windows + WSL)
|
|
2
|
+
|
|
3
|
+
Guía para configurar el motor **WhisperX local** del plugin en un equipo con
|
|
4
|
+
Windows y WSL2. WhisperX transcribe **audio a texto** (dictado); no es un motor
|
|
5
|
+
de lectura.
|
|
6
|
+
|
|
7
|
+
> Este motor es **avanzado**. Para un usuario sin WSL, Python y GPU NVIDIA, usa
|
|
8
|
+
> `Windows Voice Typing (Win+H)` o un motor en la nube. La integración con
|
|
9
|
+
> `whisper.cpp` nativo (sin WSL) está en el roadmap.
|
|
10
|
+
|
|
11
|
+
## Requisitos
|
|
12
|
+
|
|
13
|
+
- Windows 10/11 con **WSL2** y una distro **Ubuntu-22.04**.
|
|
14
|
+
- **GPU NVIDIA** con un driver de Windows compatible con WSL CUDA.
|
|
15
|
+
- No instales un driver Linux dentro de WSL: usa el driver de Windows.
|
|
16
|
+
- Comprueba con `nvidia-smi` dentro de WSL.
|
|
17
|
+
- **Python 3.10** y `python3-venv`.
|
|
18
|
+
- **ffmpeg** (WhisperX lo usa para decodificar el audio).
|
|
19
|
+
- Un **venv** con `whisperx`, `torch` con CUDA y `pyannote`.
|
|
20
|
+
- Modelo `large-v3-turbo` (se descarga la primera vez, ~1,5 GB).
|
|
21
|
+
- ~8 GB de VRAM recomendados para `large-v3-turbo` en `float16`.
|
|
22
|
+
|
|
23
|
+
## 1. Instalar WSL y Ubuntu
|
|
24
|
+
|
|
25
|
+
En PowerShell como administrador:
|
|
26
|
+
|
|
27
|
+
```powershell
|
|
28
|
+
wsl --install -d Ubuntu-22.04
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Reinicia si hace falta y comprueba dentro de WSL:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uname -a
|
|
35
|
+
nvidia-smi
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`nvidia-smi` debe listar tu GPU. Si no aparece, actualiza el driver NVIDIA de
|
|
39
|
+
Windows a una versión con soporte WSL/CUDA.
|
|
40
|
+
|
|
41
|
+
## 2. Crear el entorno de WhisperX
|
|
42
|
+
|
|
43
|
+
Dentro de WSL:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
sudo apt update
|
|
47
|
+
sudo apt install -y python3 python3-venv python3-pip ffmpeg
|
|
48
|
+
|
|
49
|
+
mkdir -p ~/whisperx
|
|
50
|
+
cd ~/whisperx
|
|
51
|
+
python3 -m venv whisperx-env
|
|
52
|
+
source whisperx-env/bin/activate
|
|
53
|
+
|
|
54
|
+
pip install --upgrade pip
|
|
55
|
+
# El índice CUDA debe coincidir con tu driver y la versión de torch.
|
|
56
|
+
# cu128 sirve para torch 2.8; usa cu121/cu124 si tu driver es más antiguo.
|
|
57
|
+
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu128
|
|
58
|
+
pip install whisperx
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Verifica:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
python3 - <<'PY'
|
|
65
|
+
import torch, whisperx
|
|
66
|
+
print("torch", torch.__version__)
|
|
67
|
+
print("cuda", torch.cuda.is_available())
|
|
68
|
+
print("whisperx", whisperx.__file__)
|
|
69
|
+
PY
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Debe imprimir `cuda True`. Si `torch.cuda.is_available()` es `False`, el
|
|
73
|
+
problema es el driver NVIDIA/WSL o la versión de torch, no el plugin.
|
|
74
|
+
|
|
75
|
+
### Token de Hugging Face (si hace falta)
|
|
76
|
+
|
|
77
|
+
WhisperX descarga modelos de VAD de `pyannote`. Si pide autenticación:
|
|
78
|
+
|
|
79
|
+
1. Crea un token en <https://huggingface.co/settings/tokens>.
|
|
80
|
+
2. Acepta los términos del modelo de VAD que use tu versión de whisperx.
|
|
81
|
+
3. Inicia sesión:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
huggingface-cli login
|
|
85
|
+
# o exporta HF_TOKEN=...
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 3. Configurar el plugin
|
|
89
|
+
|
|
90
|
+
En **Ajustes → Dictado por voz**:
|
|
91
|
+
|
|
92
|
+
| Ajuste | Valor |
|
|
93
|
+
|---|---|
|
|
94
|
+
| Motor de dictado | `WhisperX local (WSL)` |
|
|
95
|
+
| Python del entorno | Ruta del Python del venv, por ejemplo `~/whisperx/whisperx-env/bin/python` |
|
|
96
|
+
| Modelo | `large-v3-turbo` |
|
|
97
|
+
| Idioma | `Automático` (o `es`, `en`…) |
|
|
98
|
+
| Comprobar WhisperX | Arranca el worker y confirma que el modelo carga |
|
|
99
|
+
|
|
100
|
+
El valor por defecto del plugin apunta a:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
~/peopleby/voice_to_text/api_voice/demo/whisperx-env/bin/python
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Cámbialo por tu ruta si instalaste el venv en otro sitio.
|
|
107
|
+
|
|
108
|
+
Pulsa **Comprobar**. La primera vez tarda 10–30 s porque carga el modelo en la
|
|
109
|
+
GPU. Después, cada dictado de una frase corta tarda ~1–2 s.
|
|
110
|
+
|
|
111
|
+
## 4. Usar el dictado
|
|
112
|
+
|
|
113
|
+
- Pulsa la píldora del micrófono → `Grabando…`.
|
|
114
|
+
- Vuelve a pulsarla → `Transcribiendo…`.
|
|
115
|
+
- El texto se inserta en el composer con `composer.insert()`.
|
|
116
|
+
|
|
117
|
+
La grabación se hace en la ventana (`getUserMedia` + `MediaRecorder`, WebM/Opus)
|
|
118
|
+
y se envía por RPC al servidor del plugin.
|
|
119
|
+
|
|
120
|
+
## Cómo funciona por dentro
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
Ventana (Windows) Servidor OpenCode
|
|
124
|
+
getUserMedia + MediaRecorder RPC whisperTranscribe
|
|
125
|
+
audio WebM base64 ───────► escribe %TEMP%\opencode-voice-dictation\whisper-*.webm
|
|
126
|
+
lanza: wsl.exe -d Ubuntu-22.04 -e bash -lc
|
|
127
|
+
'"$HOME/.../python" "/mnt/c/.../src/whisper/worker.py"'
|
|
128
|
+
texto insertado ◄─────── worker: whisperx large-v3-turbo en CUDA
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
- El worker es `src/whisper/worker.py` y se mantiene vivo: carga el modelo una
|
|
132
|
+
sola vez.
|
|
133
|
+
- La ruta del audio en Windows (`C:\Users\...\Temp\...`) se convierte a
|
|
134
|
+
`/mnt/c/Users/...` para que WSL la lea.
|
|
135
|
+
- El Python del venv se pasa con `$HOME`, porque una `~` entre comillas no se
|
|
136
|
+
expande en `bash -lc`.
|
|
137
|
+
- Si el worker muere, el RPC devuelve el `stderr` real; ya no se queda en
|
|
138
|
+
«Transcribiendo…».
|
|
139
|
+
|
|
140
|
+
## Solución de problemas
|
|
141
|
+
|
|
142
|
+
| Síntoma | Causa / solución |
|
|
143
|
+
|---|---|
|
|
144
|
+
| `No such file or directory` al arrancar | La ruta del Python del venv no existe o no empieza por `$HOME`. Usa la ruta absoluta o `~/...`. |
|
|
145
|
+
| `torch.cuda.is_available()` es `False` | Driver NVIDIA de Windows desactualizado o falta soporte WSL. `nvidia-smi` debe funcionar en WSL. |
|
|
146
|
+
| Pide token de Hugging Face | Inicia sesión con `huggingface-cli login` y acepta los términos del modelo de VAD. |
|
|
147
|
+
| Se queda en `Transcribiendo…` | Mira el toast de error y el log del servidor; el worker devuelve el `stderr`. |
|
|
148
|
+
| El RPC devuelve 400 | El plugin server no cargó. Ajustes → Extensiones → Plugins → **Reload**, o reinicia el servicio. |
|
|
149
|
+
| La primera transcripción tarda mucho | Es la carga del modelo. Las siguientes son rápidas. |
|
|
150
|
+
| `Cannot find package 'msedge-tts'` | Es del motor de lectura Edge, no de Whisper. Edge se carga de forma perezosa y no impide Whisper. |
|
|
151
|
+
|
|
152
|
+
## Privacidad
|
|
153
|
+
|
|
154
|
+
El audio se queda en tu equipo: se escribe en `%TEMP%`, se pasa a WSL y se
|
|
155
|
+
transcribe en local. WhisperX no envía el audio a ningún servicio. Solo se
|
|
156
|
+
descargan los modelos la primera vez.
|
|
157
|
+
|
|
158
|
+
## Roadmap de motores
|
|
159
|
+
|
|
160
|
+
La idea es añadir más motores de dictado con la misma interfaz:
|
|
161
|
+
|
|
162
|
+
| Motor | Estado | Notas |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| Windows Voice Typing (Win+H) | Disponible | Cero configuración, online |
|
|
165
|
+
| System.Speech | Disponible | Offline, calidad antigua |
|
|
166
|
+
| WhisperX local (WSL) | Disponible | Avanzado, NVIDIA + WSL |
|
|
167
|
+
| `whisper.cpp` nativo | Planeado | Sin WSL/Python; binario + modelo |
|
|
168
|
+
| Google Cloud Speech-to-Text | Planeado | API key, online |
|
|
169
|
+
| OpenAI (`gpt-4o-transcribe` / `whisper-1`) | Planeado | API key, online |
|
|
170
|
+
| Deepgram / AssemblyAI | Planeado | API key, online |
|
|
171
|
+
|
|
172
|
+
Para añadir un motor en la nube, la ventana ya graba el audio y lo envía por
|
|
173
|
+
RPC. Solo hace falta:
|
|
174
|
+
|
|
175
|
+
1. Un método RPC por motor (o un `transcribe({ engine, audio, ... })` genérico).
|
|
176
|
+
2. La llamada al proveedor en el servidor.
|
|
177
|
+
3. Los ajustes de API key e idioma.
|
|
178
|
+
4. Mostrar el texto con `composer.insert()` o, si se quiere dictar hacia otra
|
|
179
|
+
app, copiarlo con `ctx.system.copy()`.
|
|
180
|
+
|
|
181
|
+
Las claves de API no deben viajar al renderer: se guardan en el store del plugin
|
|
182
|
+
o, mejor, en variables de entorno del servidor.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-voice-dictation",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Offline voice dictation and read-aloud for OpenCode Desktop on Windows",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Fran Carlos <francarlos803@gmail.com>",
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"src",
|
|
33
33
|
"dist",
|
|
34
34
|
"README.md",
|
|
35
|
-
"LICENSE"
|
|
35
|
+
"LICENSE",
|
|
36
|
+
"docs"
|
|
36
37
|
],
|
|
37
38
|
"dependencies": {
|
|
38
39
|
"msedge-tts": "^2.1.1",
|
package/src/whisper/server.ts
CHANGED
|
@@ -42,7 +42,10 @@ function toWslPath(path: string): string {
|
|
|
42
42
|
|
|
43
43
|
function spawnWorker(python: string, model: string): ChildProcess {
|
|
44
44
|
const env = { ...process.env, WHISPER_MODEL: model, WHISPER_DEVICE: "cuda" }
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
// Inside `bash -lc`, a quoted `~` does not expand. Use $HOME instead.
|
|
47
|
+
const pythonArg = python.startsWith("~/") ? `"$HOME/${python.slice(2)}"` : `"${python}"`
|
|
48
|
+
const command = `${pythonArg} "${toWslPath(workerPath())}"`
|
|
46
49
|
|
|
47
50
|
if (process.platform === "win32") {
|
|
48
51
|
return spawn("wsl.exe", ["-d", "Ubuntu-22.04", "-e", "bash", "-lc", command], {
|
|
@@ -119,14 +122,25 @@ export class WhisperEngine {
|
|
|
119
122
|
|
|
120
123
|
child.on("close", (code) => {
|
|
121
124
|
clearTimeout(timer)
|
|
122
|
-
|
|
125
|
+
const detail = this.stderr.trim()
|
|
126
|
+
|
|
127
|
+
if (!this.status.ready) {
|
|
128
|
+
this.status = {
|
|
129
|
+
ready: false,
|
|
130
|
+
model: this.model,
|
|
131
|
+
device: "cuda",
|
|
132
|
+
error: detail || `Whisper worker exited with code ${code ?? "unknown"}`,
|
|
133
|
+
}
|
|
134
|
+
this.readyReject?.(new Error(this.status.error))
|
|
135
|
+
} else {
|
|
123
136
|
this.status = {
|
|
124
137
|
ready: false,
|
|
125
138
|
model: this.model,
|
|
126
139
|
device: "cuda",
|
|
127
|
-
error:
|
|
140
|
+
error: detail || `Whisper worker exited with code ${code ?? "unknown"}`,
|
|
128
141
|
}
|
|
129
142
|
}
|
|
143
|
+
|
|
130
144
|
this.failWaiters(new Error(this.status.error || "Whisper worker stopped"))
|
|
131
145
|
this.child = undefined
|
|
132
146
|
this.readyPromise = undefined
|