RealTimeSTT 1.0.4__tar.gz → 1.1.0__tar.gz
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.
- {realtimestt-1.0.4 → realtimestt-1.1.0}/MANIFEST.in +3 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/PKG-INFO +13 -4
- {realtimestt-1.0.4 → realtimestt-1.1.0}/README.md +2 -1
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RELEASE_NOTES.md +51 -2
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/__init__.py +10 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/audio_recorder.py +106 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/initialization.py +295 -1
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/lifecycle.py +50 -0
- realtimestt-1.1.0/RealtimeSTT/core/preview_transcription.py +322 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/realtime.py +450 -26
- realtimestt-1.1.0/RealtimeSTT/core/realtime_merge.py +821 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/recorder_config.py +44 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/recording.py +83 -2
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/recording_buffers.py +48 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/runtime.py +1 -1
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/shutdown.py +48 -0
- realtimestt-1.1.0/RealtimeSTT/core/tail_transcription.py +593 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/transcription.py +195 -11
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/transcription_api.py +35 -14
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/install_sherpa_models.py +1 -1
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/factory.py +5 -0
- realtimestt-1.1.0/RealtimeSTT/transcription_engines/transcribe_cpp_engine.py +521 -0
- realtimestt-1.1.0/RealtimeSTT_server/PRODUCTION_SERVER.md +274 -0
- realtimestt-1.1.0/RealtimeSTT_server/production_server.py +5241 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/example_fastapi_server/server.py +293 -15
- {realtimestt-1.0.4 → realtimestt-1.1.0}/realtimestt.egg-info/PKG-INFO +13 -4
- {realtimestt-1.0.4 → realtimestt-1.1.0}/realtimestt.egg-info/SOURCES.txt +7 -1
- {realtimestt-1.0.4 → realtimestt-1.1.0}/realtimestt.egg-info/requires.txt +10 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/setup.py +9 -3
- realtimestt-1.1.0/tests/test_preview_transcription.py +339 -0
- realtimestt-1.1.0/tests/test_tail_transcription.py +456 -0
- realtimestt-1.0.4/RealtimeSTT_server/PRODUCTION_SERVER.md +0 -161
- realtimestt-1.0.4/RealtimeSTT_server/production_server.py +0 -2734
- {realtimestt-1.0.4 → realtimestt-1.1.0}/LICENSE +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/assets/__init__.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/assets/warmup_audio.wav +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/audio_input.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/audio_recorder_client.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/__init__.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/audio_input_worker.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/manual_audio_input.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/preroll.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/realtime_boundary_detector.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/realtime_callbacks.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/realtime_text_stabilizer.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/safepipe.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/silero_vad.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/state.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/text_formatting.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/voice_activity.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/core/wakeword.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/engines/__init__.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/engines/base_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/install_kroko.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/model_manifests.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/__init__.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/_model_utils.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/base.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/cohere_transcribe_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/faster_whisper_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/funasr_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/granite_speech_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/hf_transformers_engines.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/kroko_onnx_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/moonshine_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/nemotron_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/omnilingual_asr_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/openai_api_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/openai_whisper_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/parakeet_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/qwen3_asr_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/sherpa_onnx_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT/transcription_engines/whisper_cpp_engine.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT_server/__init__.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT_server/install_packages.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT_server/stt_cli_client.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/RealtimeSTT_server/stt_server.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/example_fastapi_server/__init__.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/example_fastapi_server/protocol.py +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/realtimestt.egg-info/dependency_links.txt +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/realtimestt.egg-info/entry_points.txt +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/realtimestt.egg-info/top_level.txt +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/requirements.txt +0 -0
- {realtimestt-1.0.4 → realtimestt-1.1.0}/setup.cfg +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: realtimestt
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: A fast Voice Activity Detection and Transcription System
|
|
5
|
-
Home-page: https://github.com/KoljaB/
|
|
5
|
+
Home-page: https://github.com/KoljaB/RealtimeSTT
|
|
6
6
|
Author: Kolja Beigel
|
|
7
7
|
Author-email: kolja.beigel@web.de
|
|
8
8
|
License: MIT
|
|
9
9
|
Keywords: real-time,audio,transcription,speech-to-text,voice-activity-detection,VAD,real-time-transcription,ambient-noise-detection,microphone-input,faster_whisper,speech-recognition,voice-assistants,audio-processing,buffered-transcription,pyaudio,ambient-noise-level,voice-deactivity
|
|
10
|
-
Requires-Python: >=3.11
|
|
10
|
+
Requires-Python: >=3.11,<3.13
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
13
|
Requires-Dist: PyAudio==0.2.14
|
|
@@ -27,6 +27,12 @@ Provides-Extra: whisper-cpp
|
|
|
27
27
|
Requires-Dist: pywhispercpp; extra == "whisper-cpp"
|
|
28
28
|
Provides-Extra: whispercpp
|
|
29
29
|
Requires-Dist: pywhispercpp; extra == "whispercpp"
|
|
30
|
+
Provides-Extra: transcribe-cpp
|
|
31
|
+
Requires-Dist: transcribe-cpp==0.2.1; extra == "transcribe-cpp"
|
|
32
|
+
Provides-Extra: transcribecpp
|
|
33
|
+
Requires-Dist: transcribe-cpp==0.2.1; extra == "transcribecpp"
|
|
34
|
+
Provides-Extra: parakeet-transcribe-cpp
|
|
35
|
+
Requires-Dist: transcribe-cpp==0.2.1; extra == "parakeet-transcribe-cpp"
|
|
30
36
|
Provides-Extra: openai-whisper
|
|
31
37
|
Requires-Dist: openai-whisper; extra == "openai-whisper"
|
|
32
38
|
Provides-Extra: sherpa-onnx
|
|
@@ -120,6 +126,7 @@ Requires-Dist: silero-vad[onnx-cpu]>=6.2.1; python_version >= "3.8" and extra ==
|
|
|
120
126
|
Provides-Extra: all
|
|
121
127
|
Requires-Dist: faster-whisper==1.2.1; extra == "all"
|
|
122
128
|
Requires-Dist: pywhispercpp; extra == "all"
|
|
129
|
+
Requires-Dist: transcribe-cpp==0.2.1; extra == "all"
|
|
123
130
|
Requires-Dist: openai-whisper; extra == "all"
|
|
124
131
|
Requires-Dist: sherpa-onnx==1.13.4; extra == "all"
|
|
125
132
|
Requires-Dist: fastapi<1,>=0.115; extra == "all"
|
|
@@ -179,6 +186,7 @@ Available extras include:
|
|
|
179
186
|
|
|
180
187
|
- faster-whisper: default CTranslate2 Whisper backend
|
|
181
188
|
- whisper-cpp: whisper.cpp backend through pywhispercpp
|
|
189
|
+
- transcribe-cpp: first-party transcribe.cpp Python binding; add the matching CUDA provider separately
|
|
182
190
|
- openai-whisper: original OpenAI Whisper Python backend
|
|
183
191
|
- sherpa-onnx: sherpa-onnx CPU backends
|
|
184
192
|
- server/production-server: versioned FastAPI HTTP and WebSocket ASR server
|
|
@@ -319,7 +327,8 @@ See the [Kroko-ONNX engine guide](docs/engines/kroko-onnx.md),
|
|
|
319
327
|
|
|
320
328
|
## Install
|
|
321
329
|
|
|
322
|
-
|
|
330
|
+
The current CI matrix covers Python 3.11 and 3.12. Python 3.13 and newer are
|
|
331
|
+
not release targets until dependency and CI gates are available.
|
|
323
332
|
|
|
324
333
|
```bash
|
|
325
334
|
pip install "RealtimeSTT[faster-whisper]"
|
|
@@ -72,7 +72,8 @@ See the [Kroko-ONNX engine guide](docs/engines/kroko-onnx.md),
|
|
|
72
72
|
|
|
73
73
|
## Install
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
The current CI matrix covers Python 3.11 and 3.12. Python 3.13 and newer are
|
|
76
|
+
not release targets until dependency and CI gates are available.
|
|
76
77
|
|
|
77
78
|
```bash
|
|
78
79
|
pip install "RealtimeSTT[faster-whisper]"
|
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# Release Notes
|
|
2
2
|
|
|
3
|
+
## 1.1.0 - 2026-08-27
|
|
4
|
+
|
|
5
|
+
This stable release promotes the externally validated `1.1.0rc1` candidate.
|
|
6
|
+
See [the release-readiness checklist](docs/release-1.1.0-readiness.md) for the
|
|
7
|
+
required evidence gates and supported platform boundaries.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Added correlated Preview `resume` handling for the versioned production
|
|
12
|
+
WebSocket API, including an ordered acknowledgement barrier and explicit
|
|
13
|
+
candidate/audio provenance fields.
|
|
14
|
+
- Added an opt-in authenticated late full-turn correction operation for
|
|
15
|
+
Preview-only deployments, bounded by a configurable maximum audio duration.
|
|
16
|
+
- Added recorder Preview/tail transcription support with package-level result
|
|
17
|
+
types and the documented dual-realtime merge contracts.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Preview-only production turns retain the complete logical-turn audio for model
|
|
22
|
+
input; live text remains diagnostic and is never substituted for Preview or
|
|
23
|
+
Final output.
|
|
24
|
+
- Empty Preview results use one bounded silence-padding retry, while Final
|
|
25
|
+
remains authoritative whenever Final ASR is enabled.
|
|
26
|
+
- Preview admission is now bounded and coalesced: one native dispatch lane
|
|
27
|
+
retains only the latest pending snapshot while an older inference is active.
|
|
28
|
+
- Unexpected live-lane exits now produce structured, observable degraded events
|
|
29
|
+
while preserving the authoritative-final fallback path.
|
|
30
|
+
- Raw-PCM responses propagate provider-reported language and finite language
|
|
31
|
+
probability metadata when the selected provider supplies it.
|
|
32
|
+
- Realtime punctuation splitting commits the frame boundary atomically, and the
|
|
33
|
+
local Preview worker rejects new speculative requests once its bounded queue
|
|
34
|
+
is full.
|
|
35
|
+
- Release packaging checks now validate the requested version, inspect archive
|
|
36
|
+
names/content for private material, and install both wheel and sdist from
|
|
37
|
+
outside the source checkout.
|
|
38
|
+
|
|
39
|
+
### Release boundaries
|
|
40
|
+
|
|
41
|
+
- The documented Nemotron-live/Parakeet-final profile targets Linux x86-64 with
|
|
42
|
+
the pinned sherpa-onnx runtime. Native Windows remains a development target
|
|
43
|
+
for this pair; use another authoritative final engine there unless the
|
|
44
|
+
cumulative-recovery behavior is independently validated.
|
|
45
|
+
- Model weights remain external artifacts. Users must review and accept the
|
|
46
|
+
exact model/runtime licenses before downloading or redistributing them.
|
|
47
|
+
- The final source tree must pass supported CI, Linux real-model acceptance,
|
|
48
|
+
and isolated wheel and sdist installation before stable publication.
|
|
49
|
+
- `1.1.0` supersedes the `1.1.0rc1` prerelease; stable installations should pin
|
|
50
|
+
`RealtimeSTT==1.1.0` when an exact version is required.
|
|
51
|
+
|
|
3
52
|
## 1.0.4 - 2026-08-21
|
|
4
53
|
|
|
5
54
|
### Fixed
|
|
@@ -86,8 +135,8 @@
|
|
|
86
135
|
streaming WebSocket APIs. Non-loopback binds require bearer authentication
|
|
87
136
|
and TLS. The server includes bounded queues and sessions, backpressure,
|
|
88
137
|
limits, structured errors, warmup, and graceful resource cleanup.
|
|
89
|
-
- Added a reproducible same-host A/B benchmark harness for the
|
|
90
|
-
|
|
138
|
+
- Added a reproducible same-host A/B benchmark harness for the raw PCM16 client
|
|
139
|
+
contract and release CI for unit, distribution, and isolated wheel
|
|
91
140
|
installation checks.
|
|
92
141
|
|
|
93
142
|
### Changed
|
|
@@ -16,6 +16,8 @@ __all__ = [
|
|
|
16
16
|
"TranscriptionEngineError",
|
|
17
17
|
"TranscriptionInfo",
|
|
18
18
|
"TranscriptionResult",
|
|
19
|
+
"PreviewTranscriptionResult",
|
|
20
|
+
"RealtimeTranscriptionMergeResult",
|
|
19
21
|
"UnsupportedTranscriptionEngineError",
|
|
20
22
|
]
|
|
21
23
|
|
|
@@ -65,6 +67,14 @@ def __getattr__(name):
|
|
|
65
67
|
from .engines import TranscriptionResult
|
|
66
68
|
|
|
67
69
|
return TranscriptionResult
|
|
70
|
+
if name == "PreviewTranscriptionResult":
|
|
71
|
+
from .core.preview_transcription import PreviewTranscriptionResult
|
|
72
|
+
|
|
73
|
+
return PreviewTranscriptionResult
|
|
74
|
+
if name == "RealtimeTranscriptionMergeResult":
|
|
75
|
+
from .core.realtime_merge import RealtimeTranscriptionMergeResult
|
|
76
|
+
|
|
77
|
+
return RealtimeTranscriptionMergeResult
|
|
68
78
|
if name == "UnsupportedTranscriptionEngineError":
|
|
69
79
|
from .engines import UnsupportedTranscriptionEngineError
|
|
70
80
|
|
|
@@ -32,6 +32,10 @@ from .core.recording_buffers import (
|
|
|
32
32
|
flush_buffered_audio as flush_recorder_buffered_audio,
|
|
33
33
|
has_pending_recordings as recorder_has_pending_recordings,
|
|
34
34
|
)
|
|
35
|
+
from .core.tail_transcription import (
|
|
36
|
+
MIN_LIVE_WORDS_FOR_FUZZY_REPAIR,
|
|
37
|
+
PREVIEW_TRANSCRIPTION_TAIL_SECONDS,
|
|
38
|
+
)
|
|
35
39
|
from .core.shutdown import shutdown_recorder
|
|
36
40
|
from .core.text_formatting import format_number
|
|
37
41
|
from .core.transcription_api import (
|
|
@@ -206,6 +210,29 @@ class AudioToTextRecorder:
|
|
|
206
210
|
deactivity_silence_confirmation_duration: float = (
|
|
207
211
|
DEACTIVITY_SILENCE_CONFIRMATION_DURATION
|
|
208
212
|
),
|
|
213
|
+
# Speculative Preview transcription parameters
|
|
214
|
+
enable_preview_transcription: bool = False,
|
|
215
|
+
preview_model_type: Optional[str] = None,
|
|
216
|
+
preview_transcription_engine: Optional[str] = None,
|
|
217
|
+
preview_transcription_engine_options: Optional[dict] = None,
|
|
218
|
+
preview_transcription_tail_seconds: float = (
|
|
219
|
+
PREVIEW_TRANSCRIPTION_TAIL_SECONDS
|
|
220
|
+
),
|
|
221
|
+
on_preview_transcription_finished=None,
|
|
222
|
+
preview_transcription_executor: Optional[Callable] = None,
|
|
223
|
+
preview_transcription_min_live_words_for_fuzzy_repair: int = (
|
|
224
|
+
MIN_LIVE_WORDS_FOR_FUZZY_REPAIR
|
|
225
|
+
),
|
|
226
|
+
# Optional second, lower-latency realtime transcription lane
|
|
227
|
+
ultrafast_realtime_model_type: Optional[str] = None,
|
|
228
|
+
ultrafast_realtime_transcription_engine: Optional[str] = None,
|
|
229
|
+
ultrafast_realtime_transcription_engine_options: Optional[
|
|
230
|
+
dict
|
|
231
|
+
] = None,
|
|
232
|
+
on_ultrafast_transcription_update=None,
|
|
233
|
+
on_merged_realtime_transcription_update=None,
|
|
234
|
+
on_realtime_transcription_merge_update=None,
|
|
235
|
+
ultrafast_realtime_max_tail_words: int = 5,
|
|
209
236
|
):
|
|
210
237
|
"""
|
|
211
238
|
Initializes an audio recorder and transcription
|
|
@@ -315,6 +342,54 @@ class AudioToTextRecorder:
|
|
|
315
342
|
recordings. Use "sentence" for the supported `. ? !` mode.
|
|
316
343
|
- realtime_batch_size (int, default=16): Batch size for the real-time
|
|
317
344
|
transcription model.
|
|
345
|
+
- ultrafast_realtime_model_type (str, default=None): Optional second
|
|
346
|
+
streaming realtime model. Its text may only append a bounded,
|
|
347
|
+
safely anchored suffix to the authoritative realtime model text.
|
|
348
|
+
- ultrafast_realtime_transcription_engine (str, default=None): Backend
|
|
349
|
+
for the ultrafast lane. If omitted, the realtime backend is used.
|
|
350
|
+
The backend must support streaming sessions.
|
|
351
|
+
- ultrafast_realtime_transcription_engine_options (dict,
|
|
352
|
+
default=None): Backend-specific ultrafast options. If omitted,
|
|
353
|
+
realtime engine options are reused.
|
|
354
|
+
- on_ultrafast_transcription_update (callable, default=None): Receives
|
|
355
|
+
the raw ultrafast text independently of the central callbacks.
|
|
356
|
+
- on_merged_realtime_transcription_update (callable, default=None):
|
|
357
|
+
Receives the complete sticky merged text only when it changes.
|
|
358
|
+
- on_realtime_transcription_merge_update (callable, default=None):
|
|
359
|
+
Receives every structured RealtimeTranscriptionMergeResult,
|
|
360
|
+
including held/no-anchor transitions.
|
|
361
|
+
- ultrafast_realtime_max_tail_words (int, default=5): Maximum number
|
|
362
|
+
of words the ultrafast model may append after a safe anchor. Lower
|
|
363
|
+
this value to reduce the speculative error radius.
|
|
364
|
+
|
|
365
|
+
Speculative Preview transcription:
|
|
366
|
+
- enable_preview_transcription (bool, default=False): Runs an
|
|
367
|
+
independent low-latency Preview transcription at confirmed VAD
|
|
368
|
+
silence. Preview is intended for speculative consumers such as an
|
|
369
|
+
early LLM response and is not authoritative Final ASR.
|
|
370
|
+
- preview_model_type (str, default=None): Model used for Preview. If
|
|
371
|
+
omitted while Preview is enabled, the loaded main model is reused
|
|
372
|
+
when the Preview engine and options also match; otherwise an
|
|
373
|
+
independent Preview model is initialized.
|
|
374
|
+
- preview_transcription_engine (str, default=None): Backend used for
|
|
375
|
+
Preview. If omitted, the main transcription backend is used.
|
|
376
|
+
- preview_transcription_engine_options (dict, default=None): Optional
|
|
377
|
+
backend-specific Preview options. If omitted, main-engine options
|
|
378
|
+
are reused and allow the loaded main model to be shared.
|
|
379
|
+
- preview_transcription_tail_seconds (float, default=3.0): Amount of
|
|
380
|
+
recent active speech sent to Preview ASR.
|
|
381
|
+
- preview_transcription_min_live_words_for_fuzzy_repair (int,
|
|
382
|
+
default=3): Minimum Live words required before constrained fuzzy
|
|
383
|
+
repair is allowed. Exact anchors remain available for shorter
|
|
384
|
+
Live text; values below the 3-word anchor length cannot lower the
|
|
385
|
+
matcher further.
|
|
386
|
+
- on_preview_transcription_finished (callable, default=None): Callback
|
|
387
|
+
receiving a PreviewTranscriptionResult. The result includes the
|
|
388
|
+
speculative text, Live boundary snapshot, tail text, alignment
|
|
389
|
+
status, and recording id.
|
|
390
|
+
- preview_transcription_executor (callable, default=None): Optional
|
|
391
|
+
external Preview ASR executor. It is called only with the bounded
|
|
392
|
+
Preview tail; it never receives or triggers the full Final audio.
|
|
318
393
|
|
|
319
394
|
Voice activity and turn detection:
|
|
320
395
|
- silero_sensitivity (float, default=SILERO_SENSITIVITY): Sensitivity
|
|
@@ -623,6 +698,37 @@ class AudioToTextRecorder:
|
|
|
623
698
|
deactivity_silence_confirmation_duration=(
|
|
624
699
|
deactivity_silence_confirmation_duration
|
|
625
700
|
),
|
|
701
|
+
enable_preview_transcription=enable_preview_transcription,
|
|
702
|
+
preview_model_type=preview_model_type,
|
|
703
|
+
preview_transcription_engine=preview_transcription_engine,
|
|
704
|
+
preview_transcription_engine_options=(
|
|
705
|
+
preview_transcription_engine_options
|
|
706
|
+
),
|
|
707
|
+
preview_transcription_tail_seconds=preview_transcription_tail_seconds,
|
|
708
|
+
preview_transcription_min_live_words_for_fuzzy_repair=(
|
|
709
|
+
preview_transcription_min_live_words_for_fuzzy_repair
|
|
710
|
+
),
|
|
711
|
+
on_preview_transcription_finished=on_preview_transcription_finished,
|
|
712
|
+
preview_transcription_executor=preview_transcription_executor,
|
|
713
|
+
ultrafast_realtime_model_type=ultrafast_realtime_model_type,
|
|
714
|
+
ultrafast_realtime_transcription_engine=(
|
|
715
|
+
ultrafast_realtime_transcription_engine
|
|
716
|
+
),
|
|
717
|
+
ultrafast_realtime_transcription_engine_options=(
|
|
718
|
+
ultrafast_realtime_transcription_engine_options
|
|
719
|
+
),
|
|
720
|
+
on_ultrafast_transcription_update=(
|
|
721
|
+
on_ultrafast_transcription_update
|
|
722
|
+
),
|
|
723
|
+
on_merged_realtime_transcription_update=(
|
|
724
|
+
on_merged_realtime_transcription_update
|
|
725
|
+
),
|
|
726
|
+
on_realtime_transcription_merge_update=(
|
|
727
|
+
on_realtime_transcription_merge_update
|
|
728
|
+
),
|
|
729
|
+
ultrafast_realtime_max_tail_words=(
|
|
730
|
+
ultrafast_realtime_max_tail_words
|
|
731
|
+
),
|
|
626
732
|
)
|
|
627
733
|
|
|
628
734
|
initialize_recorder(
|
|
@@ -19,6 +19,8 @@ from .realtime import (
|
|
|
19
19
|
run_realtime_worker,
|
|
20
20
|
)
|
|
21
21
|
from .realtime_text_stabilizer import RealtimeTextStabilizer
|
|
22
|
+
from .realtime_merge import StickyRealtimeTranscriptionMerger
|
|
23
|
+
from .preview_transcription import start_preview_transcription_worker
|
|
22
24
|
from .recording import run_recording_worker
|
|
23
25
|
from ..transcription_engines import (
|
|
24
26
|
TranscriptionEngineConfig,
|
|
@@ -29,7 +31,10 @@ from .safepipe import SafePipe
|
|
|
29
31
|
from .wakeword import OPENWAKEWORD_BACKENDS, setup_wakeword_detection
|
|
30
32
|
from .audio_input_worker import run_audio_data_worker
|
|
31
33
|
from .runtime import read_stdout_pipe, start_recorder_worker
|
|
32
|
-
from .transcription import
|
|
34
|
+
from .transcription import (
|
|
35
|
+
SharedFinalModelExecutor,
|
|
36
|
+
run_transcription_worker,
|
|
37
|
+
)
|
|
33
38
|
from .voice_activity import warmup_voice_activity_detectors
|
|
34
39
|
|
|
35
40
|
|
|
@@ -63,6 +68,7 @@ def initialize_recorder(
|
|
|
63
68
|
_initialize_transcription_runtime(recorder, recorder_cls)
|
|
64
69
|
_start_audio_reader(recorder, recorder_cls)
|
|
65
70
|
_initialize_realtime_transcription_model(recorder)
|
|
71
|
+
_initialize_preview_transcription_model(recorder)
|
|
66
72
|
_initialize_wakeword_detection(
|
|
67
73
|
recorder,
|
|
68
74
|
normalized_wakeword_backend,
|
|
@@ -175,6 +181,69 @@ def _assign_initial_attributes(recorder, init_args, normalize_wakeword_backend):
|
|
|
175
181
|
recorder.on_realtime_text_stabilization_update = (
|
|
176
182
|
init_args["on_realtime_text_stabilization_update"]
|
|
177
183
|
)
|
|
184
|
+
recorder.ultrafast_realtime_model_type = init_args[
|
|
185
|
+
"ultrafast_realtime_model_type"
|
|
186
|
+
]
|
|
187
|
+
recorder.ultrafast_realtime_transcription_engine = (
|
|
188
|
+
init_args["ultrafast_realtime_transcription_engine"]
|
|
189
|
+
or recorder.realtime_transcription_engine
|
|
190
|
+
)
|
|
191
|
+
recorder.ultrafast_realtime_transcription_engine_options = (
|
|
192
|
+
init_args["ultrafast_realtime_transcription_engine_options"]
|
|
193
|
+
if init_args["ultrafast_realtime_transcription_engine_options"]
|
|
194
|
+
is not None
|
|
195
|
+
else recorder.realtime_transcription_engine_options
|
|
196
|
+
)
|
|
197
|
+
recorder.ultrafast_realtime_transcription_model = None
|
|
198
|
+
recorder._ultrafast_uses_realtime_model = False
|
|
199
|
+
recorder.on_ultrafast_transcription_update = init_args[
|
|
200
|
+
"on_ultrafast_transcription_update"
|
|
201
|
+
]
|
|
202
|
+
recorder.on_merged_realtime_transcription_update = init_args[
|
|
203
|
+
"on_merged_realtime_transcription_update"
|
|
204
|
+
]
|
|
205
|
+
recorder.on_realtime_transcription_merge_update = init_args[
|
|
206
|
+
"on_realtime_transcription_merge_update"
|
|
207
|
+
]
|
|
208
|
+
recorder.ultrafast_realtime_max_tail_words = int(
|
|
209
|
+
init_args["ultrafast_realtime_max_tail_words"]
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
recorder.enable_preview_transcription = bool(
|
|
213
|
+
init_args["enable_preview_transcription"]
|
|
214
|
+
)
|
|
215
|
+
recorder.preview_model_type = (
|
|
216
|
+
init_args["preview_model_type"] or init_args["model"]
|
|
217
|
+
)
|
|
218
|
+
recorder.preview_transcription_engine = (
|
|
219
|
+
init_args["preview_transcription_engine"]
|
|
220
|
+
or init_args["transcription_engine"]
|
|
221
|
+
)
|
|
222
|
+
recorder.preview_transcription_engine_options = (
|
|
223
|
+
init_args["preview_transcription_engine_options"]
|
|
224
|
+
if init_args["preview_transcription_engine_options"] is not None
|
|
225
|
+
else recorder.transcription_engine_options
|
|
226
|
+
)
|
|
227
|
+
recorder.preview_transcription_tail_seconds = float(
|
|
228
|
+
init_args["preview_transcription_tail_seconds"]
|
|
229
|
+
)
|
|
230
|
+
recorder.preview_transcription_min_live_words_for_fuzzy_repair = int(
|
|
231
|
+
init_args["preview_transcription_min_live_words_for_fuzzy_repair"]
|
|
232
|
+
)
|
|
233
|
+
recorder.on_preview_transcription_finished = (
|
|
234
|
+
init_args["on_preview_transcription_finished"]
|
|
235
|
+
)
|
|
236
|
+
recorder.preview_transcription_executor = (
|
|
237
|
+
init_args["preview_transcription_executor"]
|
|
238
|
+
)
|
|
239
|
+
recorder._uses_external_preview_transcription_executor = (
|
|
240
|
+
recorder.preview_transcription_executor is not None
|
|
241
|
+
)
|
|
242
|
+
recorder.preview_transcription_uses_main_model = False
|
|
243
|
+
recorder._preview_uses_main_model = False
|
|
244
|
+
recorder._preview_uses_shared_final_worker = False
|
|
245
|
+
recorder.preview_transcription_model = None
|
|
246
|
+
recorder.preview_transcription_worker = None
|
|
178
247
|
recorder.realtime_punctuation_split_marks = (
|
|
179
248
|
_normalize_realtime_punctuation_split_marks(
|
|
180
249
|
init_args["realtime_punctuation_split_marks"]
|
|
@@ -225,8 +294,20 @@ def _assign_initial_attributes(recorder, init_args, normalize_wakeword_backend):
|
|
|
225
294
|
recorder.realtime_stabilized_text = ""
|
|
226
295
|
recorder.realtime_stabilized_safetext = ""
|
|
227
296
|
recorder.realtime_text_stabilizer = RealtimeTextStabilizer()
|
|
297
|
+
recorder.realtime_transcription_merger = StickyRealtimeTranscriptionMerger(
|
|
298
|
+
max_ultrafast_tail_words=(
|
|
299
|
+
recorder.ultrafast_realtime_max_tail_words
|
|
300
|
+
)
|
|
301
|
+
)
|
|
302
|
+
recorder.realtime_transcription_merger.reset(0)
|
|
228
303
|
recorder.realtime_recording_id = 0
|
|
229
304
|
recorder.realtime_observation_sequence = 0
|
|
305
|
+
recorder.ultrafast_realtime_observation_sequence = 0
|
|
306
|
+
recorder.ultrafast_realtime_transcription_text = ""
|
|
307
|
+
recorder.merged_realtime_transcription_text = ""
|
|
308
|
+
recorder.last_ultrafast_transcription = ""
|
|
309
|
+
recorder.last_merged_realtime_transcription = ""
|
|
310
|
+
recorder.last_realtime_transcription_merge_result = None
|
|
230
311
|
recorder.realtime_text_stabilization_event = None
|
|
231
312
|
recorder.realtime_stabilization_accepted_count = 0
|
|
232
313
|
recorder.realtime_stabilization_outlier_count = 0
|
|
@@ -255,6 +336,16 @@ def _assign_initial_attributes(recorder, init_args, normalize_wakeword_backend):
|
|
|
255
336
|
recorder.last_transcription_bytes = None
|
|
256
337
|
recorder.last_transcription_bytes_b64 = None
|
|
257
338
|
recorder.last_transcription_metadata = None
|
|
339
|
+
recorder.active_speech_tail_buffer = bytearray()
|
|
340
|
+
recorder._current_transcription_live_text = None
|
|
341
|
+
recorder._current_transcription_tail_audio = None
|
|
342
|
+
recorder._preview_transcription_submitted = False
|
|
343
|
+
recorder._pending_vad_live_text = None
|
|
344
|
+
recorder.preview_transcription_queue = None
|
|
345
|
+
recorder.preview_transcription_stop_event = None
|
|
346
|
+
recorder.preview_transcription_thread = None
|
|
347
|
+
recorder.last_preview_transcription = ""
|
|
348
|
+
recorder.last_preview_transcription_result = None
|
|
258
349
|
recorder.last_preroll_selection = None
|
|
259
350
|
recorder._pending_preroll_selection = None
|
|
260
351
|
recorder.initial_prompt = init_args["initial_prompt"]
|
|
@@ -398,12 +489,16 @@ def _initialize_transcription_runtime(recorder, recorder_cls):
|
|
|
398
489
|
recorder.stdout_thread = None
|
|
399
490
|
recorder.parent_transcription_pipe = None
|
|
400
491
|
recorder.parent_stdout_pipe = None
|
|
492
|
+
recorder.shared_preview_transcription_result_queue = None
|
|
401
493
|
child_transcription_pipe = None
|
|
402
494
|
child_stdout_pipe = None
|
|
403
495
|
|
|
404
496
|
if not recorder._uses_external_transcription_executor:
|
|
405
497
|
recorder.parent_transcription_pipe, child_transcription_pipe = SafePipe()
|
|
406
498
|
recorder.parent_stdout_pipe, child_stdout_pipe = SafePipe()
|
|
499
|
+
if _should_share_preview_model(recorder):
|
|
500
|
+
recorder.shared_preview_transcription_result_queue = mp.Queue()
|
|
501
|
+
recorder._preview_uses_shared_final_worker = True
|
|
407
502
|
|
|
408
503
|
recorder.device = "cuda" if recorder.device == "cuda" and torch.cuda.is_available() else "cpu"
|
|
409
504
|
|
|
@@ -432,10 +527,72 @@ def _initialize_transcription_runtime(recorder, recorder_cls):
|
|
|
432
527
|
recorder.batch_size,
|
|
433
528
|
recorder.faster_whisper_vad_filter,
|
|
434
529
|
recorder.normalize_audio,
|
|
530
|
+
recorder.shared_preview_transcription_result_queue,
|
|
435
531
|
)
|
|
436
532
|
)
|
|
437
533
|
|
|
438
534
|
|
|
535
|
+
def _values_equal(left, right):
|
|
536
|
+
"""Compares optional engine settings without assuming scalar values."""
|
|
537
|
+
|
|
538
|
+
if left is right:
|
|
539
|
+
return True
|
|
540
|
+
try:
|
|
541
|
+
result = left == right
|
|
542
|
+
except Exception:
|
|
543
|
+
return False
|
|
544
|
+
return result if isinstance(result, bool) else False
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
def _should_share_preview_model(recorder):
|
|
548
|
+
"""Returns whether Preview can use the loaded Final model safely."""
|
|
549
|
+
|
|
550
|
+
return bool(
|
|
551
|
+
getattr(recorder, "enable_preview_transcription", False)
|
|
552
|
+
and not getattr(
|
|
553
|
+
recorder,
|
|
554
|
+
"_uses_external_preview_transcription_executor",
|
|
555
|
+
False,
|
|
556
|
+
)
|
|
557
|
+
and recorder.preview_model_type == recorder.main_model_type
|
|
558
|
+
and recorder.preview_transcription_engine
|
|
559
|
+
== recorder.transcription_engine
|
|
560
|
+
and _values_equal(
|
|
561
|
+
recorder.preview_transcription_engine_options,
|
|
562
|
+
recorder.transcription_engine_options,
|
|
563
|
+
)
|
|
564
|
+
)
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
def _should_share_ultrafast_realtime_model(recorder):
|
|
568
|
+
"""Returns whether both realtime lanes can share one loaded model."""
|
|
569
|
+
|
|
570
|
+
return bool(
|
|
571
|
+
getattr(recorder, "ultrafast_realtime_model_type", None)
|
|
572
|
+
and getattr(recorder, "realtime_transcription_model", None) is not None
|
|
573
|
+
and recorder.ultrafast_realtime_model_type
|
|
574
|
+
== recorder.realtime_model_type
|
|
575
|
+
and recorder.ultrafast_realtime_transcription_engine
|
|
576
|
+
== recorder.realtime_transcription_engine
|
|
577
|
+
and _values_equal(
|
|
578
|
+
recorder.ultrafast_realtime_transcription_engine_options,
|
|
579
|
+
recorder.realtime_transcription_engine_options,
|
|
580
|
+
)
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
def _require_streaming_realtime_model(model, lane_name):
|
|
585
|
+
"""Rejects an optional lane that cannot maintain streaming sessions."""
|
|
586
|
+
|
|
587
|
+
if not getattr(model, "supports_streaming", False) or not hasattr(
|
|
588
|
+
model,
|
|
589
|
+
"create_streaming_session",
|
|
590
|
+
):
|
|
591
|
+
raise ValueError(
|
|
592
|
+
f"{lane_name} realtime model must support streaming sessions"
|
|
593
|
+
)
|
|
594
|
+
|
|
595
|
+
|
|
439
596
|
def _start_audio_reader(recorder, recorder_cls):
|
|
440
597
|
"""
|
|
441
598
|
Starts the background audio reader process.
|
|
@@ -515,6 +672,143 @@ def _initialize_realtime_transcription_model(recorder):
|
|
|
515
672
|
f"{recorder.realtime_transcription_engine} realtime speech to text transcription model initialized successfully"
|
|
516
673
|
)
|
|
517
674
|
|
|
675
|
+
if not (
|
|
676
|
+
recorder.enable_realtime_transcription
|
|
677
|
+
and recorder.ultrafast_realtime_model_type
|
|
678
|
+
):
|
|
679
|
+
return
|
|
680
|
+
|
|
681
|
+
try:
|
|
682
|
+
if _should_share_ultrafast_realtime_model(recorder):
|
|
683
|
+
recorder.ultrafast_realtime_transcription_model = (
|
|
684
|
+
recorder.realtime_transcription_model
|
|
685
|
+
)
|
|
686
|
+
recorder._ultrafast_uses_realtime_model = True
|
|
687
|
+
else:
|
|
688
|
+
logger.info(
|
|
689
|
+
"Initializing %s ultrafast realtime transcription model %s",
|
|
690
|
+
recorder.ultrafast_realtime_transcription_engine,
|
|
691
|
+
recorder.ultrafast_realtime_model_type,
|
|
692
|
+
)
|
|
693
|
+
recorder.ultrafast_realtime_transcription_model = (
|
|
694
|
+
create_transcription_engine(
|
|
695
|
+
recorder.ultrafast_realtime_transcription_engine,
|
|
696
|
+
TranscriptionEngineConfig(
|
|
697
|
+
model=recorder.ultrafast_realtime_model_type,
|
|
698
|
+
download_root=recorder.download_root,
|
|
699
|
+
compute_type=recorder.compute_type,
|
|
700
|
+
gpu_device_index=recorder.gpu_device_index,
|
|
701
|
+
device=recorder.device,
|
|
702
|
+
beam_size=recorder.beam_size_realtime,
|
|
703
|
+
initial_prompt=recorder.initial_prompt_realtime,
|
|
704
|
+
suppress_tokens=recorder.suppress_tokens,
|
|
705
|
+
batch_size=recorder.realtime_batch_size,
|
|
706
|
+
vad_filter=recorder.faster_whisper_vad_filter,
|
|
707
|
+
normalize_audio=recorder.normalize_audio,
|
|
708
|
+
engine_options=(
|
|
709
|
+
recorder.ultrafast_realtime_transcription_engine_options
|
|
710
|
+
),
|
|
711
|
+
),
|
|
712
|
+
)
|
|
713
|
+
)
|
|
714
|
+
|
|
715
|
+
_require_streaming_realtime_model(
|
|
716
|
+
recorder.ultrafast_realtime_transcription_model,
|
|
717
|
+
"ultrafast",
|
|
718
|
+
)
|
|
719
|
+
|
|
720
|
+
if not recorder._ultrafast_uses_realtime_model:
|
|
721
|
+
current_dir = os.path.dirname(
|
|
722
|
+
os.path.dirname(os.path.realpath(__file__))
|
|
723
|
+
)
|
|
724
|
+
warmup_audio_path = os.path.join(
|
|
725
|
+
current_dir,
|
|
726
|
+
"assets",
|
|
727
|
+
"warmup_audio.wav",
|
|
728
|
+
)
|
|
729
|
+
warmup_audio_data, _ = sf.read(
|
|
730
|
+
warmup_audio_path,
|
|
731
|
+
dtype="float32",
|
|
732
|
+
)
|
|
733
|
+
recorder.ultrafast_realtime_transcription_model.warmup(
|
|
734
|
+
warmup_audio_data
|
|
735
|
+
)
|
|
736
|
+
except Exception as error:
|
|
737
|
+
logger.exception(
|
|
738
|
+
"Error initializing ultrafast realtime transcription model: %s",
|
|
739
|
+
error,
|
|
740
|
+
)
|
|
741
|
+
raise
|
|
742
|
+
|
|
743
|
+
logger.debug("Ultrafast realtime transcription model initialized")
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
def _initialize_preview_transcription_model(recorder):
|
|
747
|
+
"""
|
|
748
|
+
Initializes the optional independent speculative Preview model.
|
|
749
|
+
"""
|
|
750
|
+
|
|
751
|
+
if not recorder.enable_preview_transcription:
|
|
752
|
+
return
|
|
753
|
+
|
|
754
|
+
recorder._preview_uses_main_model = _should_share_preview_model(recorder)
|
|
755
|
+
if recorder._preview_uses_main_model:
|
|
756
|
+
recorder.preview_transcription_uses_main_model = True
|
|
757
|
+
if recorder._uses_external_transcription_executor:
|
|
758
|
+
recorder.preview_transcription_executor = (
|
|
759
|
+
recorder.transcription_executor
|
|
760
|
+
)
|
|
761
|
+
else:
|
|
762
|
+
recorder.preview_transcription_executor = SharedFinalModelExecutor(
|
|
763
|
+
recorder
|
|
764
|
+
)
|
|
765
|
+
recorder._uses_external_preview_transcription_executor = True
|
|
766
|
+
start_preview_transcription_worker(recorder)
|
|
767
|
+
return
|
|
768
|
+
|
|
769
|
+
if not recorder._uses_external_preview_transcription_executor:
|
|
770
|
+
try:
|
|
771
|
+
logger.info(
|
|
772
|
+
f"Initializing {recorder.preview_transcription_engine} preview "
|
|
773
|
+
f"transcription model {recorder.preview_model_type}, "
|
|
774
|
+
f"device: {recorder.device}, compute type: {recorder.compute_type}, "
|
|
775
|
+
f"download root: {recorder.download_root}"
|
|
776
|
+
)
|
|
777
|
+
recorder.preview_transcription_model = create_transcription_engine(
|
|
778
|
+
recorder.preview_transcription_engine,
|
|
779
|
+
TranscriptionEngineConfig(
|
|
780
|
+
model=recorder.preview_model_type,
|
|
781
|
+
download_root=recorder.download_root,
|
|
782
|
+
compute_type=recorder.compute_type,
|
|
783
|
+
gpu_device_index=recorder.gpu_device_index,
|
|
784
|
+
device=recorder.device,
|
|
785
|
+
beam_size=recorder.beam_size_realtime,
|
|
786
|
+
initial_prompt=recorder.initial_prompt,
|
|
787
|
+
suppress_tokens=recorder.suppress_tokens,
|
|
788
|
+
batch_size=0,
|
|
789
|
+
vad_filter=recorder.faster_whisper_vad_filter,
|
|
790
|
+
normalize_audio=recorder.normalize_audio,
|
|
791
|
+
engine_options=recorder.preview_transcription_engine_options,
|
|
792
|
+
),
|
|
793
|
+
)
|
|
794
|
+
|
|
795
|
+
current_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
|
796
|
+
warmup_audio_path = os.path.join(
|
|
797
|
+
current_dir,
|
|
798
|
+
"assets",
|
|
799
|
+
"warmup_audio.wav",
|
|
800
|
+
)
|
|
801
|
+
warmup_audio_data, _ = sf.read(warmup_audio_path, dtype="float32")
|
|
802
|
+
recorder.preview_transcription_model.warmup(warmup_audio_data)
|
|
803
|
+
except Exception as error:
|
|
804
|
+
logger.exception(
|
|
805
|
+
"Error initializing preview transcription model: %s",
|
|
806
|
+
error,
|
|
807
|
+
)
|
|
808
|
+
raise
|
|
809
|
+
|
|
810
|
+
start_preview_transcription_worker(recorder)
|
|
811
|
+
|
|
518
812
|
|
|
519
813
|
def _initialize_wakeword_detection(
|
|
520
814
|
recorder,
|