@livekit/agents-plugin-azure 1.5.0
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/LICENSE +201 -0
- package/README.md +18 -0
- package/dist/index.cjs +34 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/stt.cjs +465 -0
- package/dist/stt.cjs.map +1 -0
- package/dist/stt.d.cts +106 -0
- package/dist/stt.d.ts +106 -0
- package/dist/stt.d.ts.map +1 -0
- package/dist/stt.js +435 -0
- package/dist/stt.js.map +1 -0
- package/dist/stt.test.cjs +209 -0
- package/dist/stt.test.cjs.map +1 -0
- package/dist/stt.test.d.cts +2 -0
- package/dist/stt.test.d.ts +2 -0
- package/dist/stt.test.d.ts.map +1 -0
- package/dist/stt.test.js +208 -0
- package/dist/stt.test.js.map +1 -0
- package/package.json +50 -0
- package/src/index.ts +18 -0
- package/src/stt.test.ts +245 -0
- package/src/stt.ts +585 -0
package/dist/stt.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { type APIConnectOptions, type AudioBuffer, stt } from '@livekit/agents';
|
|
2
|
+
import * as speechsdk from 'microsoft-cognitiveservices-speech-sdk';
|
|
3
|
+
export { speechsdk };
|
|
4
|
+
/** @public */
|
|
5
|
+
export interface STTOptions {
|
|
6
|
+
/** Azure Speech subscription key. Defaults to `AZURE_SPEECH_KEY`. */
|
|
7
|
+
speechKey?: string;
|
|
8
|
+
/** Azure Speech region. Defaults to `AZURE_SPEECH_REGION`. */
|
|
9
|
+
speechRegion?: string;
|
|
10
|
+
/** Azure Speech container host. Defaults to `AZURE_SPEECH_HOST`. */
|
|
11
|
+
speechHost?: string;
|
|
12
|
+
/** Ephemeral Microsoft Entra auth token. */
|
|
13
|
+
speechAuthToken?: string;
|
|
14
|
+
/** Azure Speech endpoint URL. */
|
|
15
|
+
speechEndpoint?: string;
|
|
16
|
+
sampleRate: number;
|
|
17
|
+
numChannels: number;
|
|
18
|
+
segmentationSilenceTimeoutMs?: number;
|
|
19
|
+
segmentationMaxTimeMs?: number;
|
|
20
|
+
segmentationStrategy?: string;
|
|
21
|
+
language: string[];
|
|
22
|
+
profanity?: speechsdk.ProfanityOption;
|
|
23
|
+
phraseList?: string[] | null;
|
|
24
|
+
explicitPunctuation: boolean;
|
|
25
|
+
trueTextPostProcessing: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** @public */
|
|
28
|
+
export type STTUpdateOptions = Partial<Pick<STTOptions, 'segmentationSilenceTimeoutMs' | 'segmentationMaxTimeMs' | 'segmentationStrategy'>> & {
|
|
29
|
+
language?: string | string[];
|
|
30
|
+
};
|
|
31
|
+
/** @public */
|
|
32
|
+
export interface STTConstructorOptions extends STTUpdateOptions {
|
|
33
|
+
speechKey?: string;
|
|
34
|
+
speechRegion?: string;
|
|
35
|
+
speechHost?: string;
|
|
36
|
+
speechAuthToken?: string;
|
|
37
|
+
speechEndpoint?: string;
|
|
38
|
+
sampleRate?: number;
|
|
39
|
+
numChannels?: number;
|
|
40
|
+
profanity?: speechsdk.ProfanityOption;
|
|
41
|
+
phraseList?: string[] | null;
|
|
42
|
+
explicitPunctuation?: boolean;
|
|
43
|
+
trueTextPostProcessing?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** @internal */
|
|
46
|
+
export interface _CanceledEvent {
|
|
47
|
+
errorDetails?: string;
|
|
48
|
+
reason: speechsdk.CancellationReason;
|
|
49
|
+
errorCode?: speechsdk.CancellationErrorCode;
|
|
50
|
+
}
|
|
51
|
+
/** @internal */
|
|
52
|
+
export interface _WaitableEvent {
|
|
53
|
+
isSet: boolean;
|
|
54
|
+
wait(): Promise<void>;
|
|
55
|
+
set(): void;
|
|
56
|
+
clear(): void;
|
|
57
|
+
}
|
|
58
|
+
/** @public */
|
|
59
|
+
export declare class STT extends stt.STT {
|
|
60
|
+
#private;
|
|
61
|
+
label: string;
|
|
62
|
+
get model(): string;
|
|
63
|
+
get provider(): string;
|
|
64
|
+
constructor(opts?: STTConstructorOptions);
|
|
65
|
+
_recognize(_frame: AudioBuffer): Promise<stt.SpeechEvent>;
|
|
66
|
+
updateOptions(opts: STTUpdateOptions): void;
|
|
67
|
+
stream(options?: {
|
|
68
|
+
language?: string;
|
|
69
|
+
connOptions?: APIConnectOptions;
|
|
70
|
+
}): SpeechStream;
|
|
71
|
+
}
|
|
72
|
+
/** @public */
|
|
73
|
+
export declare class SpeechStream extends stt.SpeechStream {
|
|
74
|
+
#private;
|
|
75
|
+
/** @internal */
|
|
76
|
+
_opts: STTOptions;
|
|
77
|
+
/** @internal */
|
|
78
|
+
_speaking: boolean;
|
|
79
|
+
/** @internal */
|
|
80
|
+
_sessionStoppedEvent: _WaitableEvent;
|
|
81
|
+
/** @internal */
|
|
82
|
+
_sessionStartedEvent: _WaitableEvent;
|
|
83
|
+
/** @internal */
|
|
84
|
+
_reconnectEvent: _WaitableEvent;
|
|
85
|
+
/** @internal */
|
|
86
|
+
_cancellationError: _CanceledEvent | null;
|
|
87
|
+
label: string;
|
|
88
|
+
constructor(stt: STT, opts: STTOptions, connOptions: APIConnectOptions);
|
|
89
|
+
updateOptions(opts: STTUpdateOptions): void;
|
|
90
|
+
protected run(): Promise<void>;
|
|
91
|
+
/** @internal */
|
|
92
|
+
_onRecognized(evt: speechsdk.SpeechRecognitionEventArgs): void;
|
|
93
|
+
/** @internal */
|
|
94
|
+
_onRecognizing(evt: speechsdk.SpeechRecognitionEventArgs): void;
|
|
95
|
+
/** @internal */
|
|
96
|
+
_onSpeechStart(_evt: speechsdk.RecognitionEventArgs): void;
|
|
97
|
+
/** @internal */
|
|
98
|
+
_onSpeechEnd(_evt: speechsdk.RecognitionEventArgs): void;
|
|
99
|
+
/** @internal */
|
|
100
|
+
_onSessionStarted(_evt: speechsdk.SessionEventArgs): void;
|
|
101
|
+
/** @internal */
|
|
102
|
+
_onSessionStopped(_evt: speechsdk.SessionEventArgs): void;
|
|
103
|
+
/** @internal */
|
|
104
|
+
_onCanceled(evt: _CanceledEvent): void;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=stt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stt.d.ts","sourceRoot":"","sources":["../src/stt.ts"],"names":[],"mappings":"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"}
|
package/dist/stt.js
ADDED
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import {
|
|
2
|
+
APIConnectionError,
|
|
3
|
+
DEFAULT_API_CONNECT_OPTIONS,
|
|
4
|
+
asLanguageCode,
|
|
5
|
+
log,
|
|
6
|
+
stt
|
|
7
|
+
} from "@livekit/agents";
|
|
8
|
+
import * as speechsdk from "microsoft-cognitiveservices-speech-sdk";
|
|
9
|
+
class DeferredEvent {
|
|
10
|
+
#resolve;
|
|
11
|
+
#promise;
|
|
12
|
+
isSet = false;
|
|
13
|
+
constructor() {
|
|
14
|
+
this.#promise = new Promise((resolve) => {
|
|
15
|
+
this.#resolve = resolve;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
wait() {
|
|
19
|
+
return this.#promise;
|
|
20
|
+
}
|
|
21
|
+
set() {
|
|
22
|
+
var _a;
|
|
23
|
+
if (this.isSet) return;
|
|
24
|
+
this.isSet = true;
|
|
25
|
+
(_a = this.#resolve) == null ? void 0 : _a.call(this);
|
|
26
|
+
}
|
|
27
|
+
clear() {
|
|
28
|
+
if (!this.isSet) return;
|
|
29
|
+
this.isSet = false;
|
|
30
|
+
this.#promise = new Promise((resolve) => {
|
|
31
|
+
this.#resolve = resolve;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const defaultSTTOptions = {
|
|
36
|
+
sampleRate: 16e3,
|
|
37
|
+
numChannels: 1,
|
|
38
|
+
language: ["en-US"],
|
|
39
|
+
explicitPunctuation: false,
|
|
40
|
+
trueTextPostProcessing: false
|
|
41
|
+
};
|
|
42
|
+
class STT extends stt.STT {
|
|
43
|
+
#opts;
|
|
44
|
+
#streams = /* @__PURE__ */ new Set();
|
|
45
|
+
label = "azure.STT";
|
|
46
|
+
get model() {
|
|
47
|
+
return "unknown";
|
|
48
|
+
}
|
|
49
|
+
get provider() {
|
|
50
|
+
return "Azure STT";
|
|
51
|
+
}
|
|
52
|
+
constructor(opts = {}) {
|
|
53
|
+
super({ streaming: true, interimResults: true, alignedTranscript: "chunk" });
|
|
54
|
+
const speechHost = opts.speechHost ?? process.env.AZURE_SPEECH_HOST;
|
|
55
|
+
const speechKey = opts.speechKey ?? process.env.AZURE_SPEECH_KEY;
|
|
56
|
+
const speechRegion = opts.speechRegion ?? process.env.AZURE_SPEECH_REGION;
|
|
57
|
+
const speechAuthToken = opts.speechAuthToken;
|
|
58
|
+
const speechEndpoint = opts.speechEndpoint;
|
|
59
|
+
if (!speechHost && !(speechKey && speechRegion) && !(speechAuthToken && speechRegion) && !(speechKey && speechEndpoint)) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
"AZURE_SPEECH_HOST or AZURE_SPEECH_KEY and AZURE_SPEECH_REGION or speechAuthToken and AZURE_SPEECH_REGION or AZURE_SPEECH_KEY and speechEndpoint must be set"
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
if (speechRegion && speechEndpoint) {
|
|
65
|
+
log().warn("speechRegion and speechEndpoint both are set, using speechEndpoint");
|
|
66
|
+
}
|
|
67
|
+
this.#opts = {
|
|
68
|
+
...defaultSTTOptions,
|
|
69
|
+
...opts,
|
|
70
|
+
speechHost,
|
|
71
|
+
speechKey,
|
|
72
|
+
speechRegion: speechEndpoint ? void 0 : speechRegion,
|
|
73
|
+
speechAuthToken,
|
|
74
|
+
speechEndpoint,
|
|
75
|
+
language: normalizeLanguages(opts.language)
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async _recognize(_frame) {
|
|
79
|
+
throw new Error("Azure STT does not support single frame recognition");
|
|
80
|
+
}
|
|
81
|
+
updateOptions(opts) {
|
|
82
|
+
this.#opts = {
|
|
83
|
+
...this.#opts,
|
|
84
|
+
...opts,
|
|
85
|
+
language: opts.language === void 0 ? this.#opts.language : normalizeLanguages(opts.language)
|
|
86
|
+
};
|
|
87
|
+
for (const ref of this.#streams) {
|
|
88
|
+
const stream = ref.deref();
|
|
89
|
+
if (stream) {
|
|
90
|
+
stream.updateOptions(opts);
|
|
91
|
+
} else {
|
|
92
|
+
this.#streams.delete(ref);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
stream(options = {}) {
|
|
97
|
+
const opts = {
|
|
98
|
+
...this.#opts,
|
|
99
|
+
language: options.language ? [options.language] : [...this.#opts.language]
|
|
100
|
+
};
|
|
101
|
+
const stream = new SpeechStream(this, opts, options.connOptions ?? DEFAULT_API_CONNECT_OPTIONS);
|
|
102
|
+
this.#streams.add(new WeakRef(stream));
|
|
103
|
+
return stream;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
class SpeechStream extends stt.SpeechStream {
|
|
107
|
+
/** @internal */
|
|
108
|
+
_opts;
|
|
109
|
+
/** @internal */
|
|
110
|
+
_speaking = false;
|
|
111
|
+
/** @internal */
|
|
112
|
+
_sessionStoppedEvent = new DeferredEvent();
|
|
113
|
+
/** @internal */
|
|
114
|
+
_sessionStartedEvent = new DeferredEvent();
|
|
115
|
+
/** @internal */
|
|
116
|
+
_reconnectEvent = new DeferredEvent();
|
|
117
|
+
/** @internal */
|
|
118
|
+
_cancellationError = null;
|
|
119
|
+
#connOptions;
|
|
120
|
+
#audioDuration = 0;
|
|
121
|
+
#lastAudioDurationReportTime = performance.now();
|
|
122
|
+
label = "azure.SpeechStream";
|
|
123
|
+
constructor(stt2, opts, connOptions) {
|
|
124
|
+
super(stt2, opts.sampleRate, connOptions);
|
|
125
|
+
this._opts = opts;
|
|
126
|
+
this.#connOptions = connOptions;
|
|
127
|
+
}
|
|
128
|
+
updateOptions(opts) {
|
|
129
|
+
this._opts = {
|
|
130
|
+
...this._opts,
|
|
131
|
+
...opts,
|
|
132
|
+
language: opts.language === void 0 ? this._opts.language : normalizeLanguages(opts.language)
|
|
133
|
+
};
|
|
134
|
+
this._reconnectEvent.set();
|
|
135
|
+
}
|
|
136
|
+
async run() {
|
|
137
|
+
while (!this.input.closed && !this.closed) {
|
|
138
|
+
this._sessionStoppedEvent.clear();
|
|
139
|
+
this._sessionStartedEvent.clear();
|
|
140
|
+
this._cancellationError = null;
|
|
141
|
+
this._speaking = false;
|
|
142
|
+
const pushStream = speechsdk.AudioInputStream.createPushStream(
|
|
143
|
+
speechsdk.AudioStreamFormat.getWaveFormatPCM(
|
|
144
|
+
this._opts.sampleRate,
|
|
145
|
+
16,
|
|
146
|
+
this._opts.numChannels
|
|
147
|
+
)
|
|
148
|
+
);
|
|
149
|
+
const recognizer = createSpeechRecognizer(this._opts, pushStream);
|
|
150
|
+
this.#connectRecognizerEvents(recognizer);
|
|
151
|
+
await new Promise((resolve, reject) => {
|
|
152
|
+
recognizer.startContinuousRecognitionAsync(resolve, (error) => reject(new Error(error)));
|
|
153
|
+
});
|
|
154
|
+
try {
|
|
155
|
+
await withTimeout(this._sessionStartedEvent.wait(), this.#connOptions.timeoutMs);
|
|
156
|
+
const inputAbortController = new AbortController();
|
|
157
|
+
const inputTask = this.#processInput(pushStream, inputAbortController.signal);
|
|
158
|
+
let inputEnded = false;
|
|
159
|
+
try {
|
|
160
|
+
const completed = await Promise.race([
|
|
161
|
+
inputTask.then(() => "input"),
|
|
162
|
+
this._reconnectEvent.wait().then(() => "reconnect"),
|
|
163
|
+
this._sessionStoppedEvent.wait().then(() => "stopped")
|
|
164
|
+
]);
|
|
165
|
+
if (completed === "stopped") {
|
|
166
|
+
const details = this._cancellationError;
|
|
167
|
+
if (details !== null) {
|
|
168
|
+
throw new APIConnectionError({
|
|
169
|
+
message: `Azure STT canceled: ${details.errorDetails || details.reason} (${details.errorCode})`
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
throw new APIConnectionError({ message: "SpeechRecognition session stopped" });
|
|
173
|
+
}
|
|
174
|
+
if (completed === "reconnect") {
|
|
175
|
+
this._reconnectEvent.clear();
|
|
176
|
+
}
|
|
177
|
+
inputEnded = completed === "input";
|
|
178
|
+
} finally {
|
|
179
|
+
inputAbortController.abort();
|
|
180
|
+
await inputTask;
|
|
181
|
+
pushStream.close();
|
|
182
|
+
}
|
|
183
|
+
if (inputEnded) {
|
|
184
|
+
await this._sessionStoppedEvent.wait();
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
} finally {
|
|
188
|
+
await new Promise((resolve) => {
|
|
189
|
+
recognizer.stopContinuousRecognitionAsync(resolve, () => resolve());
|
|
190
|
+
});
|
|
191
|
+
recognizer.close();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async #processInput(pushStream, abortSignal) {
|
|
196
|
+
try {
|
|
197
|
+
while (!this.closed) {
|
|
198
|
+
let result;
|
|
199
|
+
try {
|
|
200
|
+
result = await this.input.next({ signal: abortSignal });
|
|
201
|
+
} catch (error) {
|
|
202
|
+
if (abortSignal.aborted) break;
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
if (result.done) break;
|
|
206
|
+
const input = result.value;
|
|
207
|
+
if (input === SpeechStream.FLUSH_SENTINEL) {
|
|
208
|
+
this.#emitRecognitionUsage();
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
this.#audioDuration += input.samplesPerChannel / input.sampleRate;
|
|
212
|
+
this.#maybeEmitRecognitionUsage();
|
|
213
|
+
pushStream.write(toArrayBuffer(input));
|
|
214
|
+
}
|
|
215
|
+
} finally {
|
|
216
|
+
this.#emitRecognitionUsage();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
#connectRecognizerEvents(recognizer) {
|
|
220
|
+
recognizer.recognizing = (_sender, evt) => this._onRecognizing(evt);
|
|
221
|
+
recognizer.recognized = (_sender, evt) => this._onRecognized(evt);
|
|
222
|
+
recognizer.speechStartDetected = (_sender, evt) => this._onSpeechStart(evt);
|
|
223
|
+
recognizer.speechEndDetected = (_sender, evt) => this._onSpeechEnd(evt);
|
|
224
|
+
recognizer.sessionStarted = (_sender, evt) => this._onSessionStarted(evt);
|
|
225
|
+
recognizer.sessionStopped = (_sender, evt) => this._onSessionStopped(evt);
|
|
226
|
+
recognizer.canceled = (_sender, evt) => this._onCanceled(evt);
|
|
227
|
+
}
|
|
228
|
+
/** @internal */
|
|
229
|
+
_onRecognized(evt) {
|
|
230
|
+
const text = evt.result.text.trim();
|
|
231
|
+
if (!text) return;
|
|
232
|
+
this.queue.put({
|
|
233
|
+
type: stt.SpeechEventType.FINAL_TRANSCRIPT,
|
|
234
|
+
alternatives: [this.#speechData(evt, 1)]
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/** @internal */
|
|
238
|
+
_onRecognizing(evt) {
|
|
239
|
+
const text = evt.result.text.trim();
|
|
240
|
+
if (!text) return;
|
|
241
|
+
this.queue.put({
|
|
242
|
+
type: stt.SpeechEventType.INTERIM_TRANSCRIPT,
|
|
243
|
+
alternatives: [this.#speechData(evt, 0)]
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
/** @internal */
|
|
247
|
+
_onSpeechStart(_evt) {
|
|
248
|
+
if (this._speaking) return;
|
|
249
|
+
this._speaking = true;
|
|
250
|
+
this.queue.put({ type: stt.SpeechEventType.START_OF_SPEECH });
|
|
251
|
+
}
|
|
252
|
+
/** @internal */
|
|
253
|
+
_onSpeechEnd(_evt) {
|
|
254
|
+
if (!this._speaking) return;
|
|
255
|
+
this._speaking = false;
|
|
256
|
+
this.queue.put({ type: stt.SpeechEventType.END_OF_SPEECH });
|
|
257
|
+
}
|
|
258
|
+
/** @internal */
|
|
259
|
+
_onSessionStarted(_evt) {
|
|
260
|
+
this._sessionStartedEvent.set();
|
|
261
|
+
}
|
|
262
|
+
/** @internal */
|
|
263
|
+
_onSessionStopped(_evt) {
|
|
264
|
+
this._sessionStoppedEvent.set();
|
|
265
|
+
}
|
|
266
|
+
/** @internal */
|
|
267
|
+
_onCanceled(evt) {
|
|
268
|
+
if (evt.reason === speechsdk.CancellationReason.Error) {
|
|
269
|
+
log().warn(
|
|
270
|
+
{
|
|
271
|
+
code: evt.errorCode,
|
|
272
|
+
reason: evt.reason,
|
|
273
|
+
errorDetails: evt.errorDetails
|
|
274
|
+
},
|
|
275
|
+
`Speech recognition canceled: ${evt.errorDetails || evt.reason}`
|
|
276
|
+
);
|
|
277
|
+
this._cancellationError = evt;
|
|
278
|
+
this._sessionStoppedEvent.set();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
#speechData(evt, confidence) {
|
|
282
|
+
const result = speechsdk.AutoDetectSourceLanguageResult.fromResult(evt.result);
|
|
283
|
+
const language = result.language || this._opts.language[0] || "";
|
|
284
|
+
return {
|
|
285
|
+
language: asLanguageCode(language),
|
|
286
|
+
confidence,
|
|
287
|
+
text: evt.result.text,
|
|
288
|
+
startTime: evt.result.offset / 10 ** 7 + this.startTimeOffset,
|
|
289
|
+
endTime: (evt.result.offset + evt.result.duration) / 10 ** 7 + this.startTimeOffset
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
#maybeEmitRecognitionUsage() {
|
|
293
|
+
if (performance.now() - this.#lastAudioDurationReportTime >= 5e3) {
|
|
294
|
+
this.#emitRecognitionUsage();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
#emitRecognitionUsage() {
|
|
298
|
+
if (this.#audioDuration <= 0) return;
|
|
299
|
+
const audioDuration = this.#audioDuration;
|
|
300
|
+
this.#audioDuration = 0;
|
|
301
|
+
this.#lastAudioDurationReportTime = performance.now();
|
|
302
|
+
this.queue.put({
|
|
303
|
+
type: stt.SpeechEventType.RECOGNITION_USAGE,
|
|
304
|
+
recognitionUsage: { audioDuration }
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function normalizeLanguages(language) {
|
|
309
|
+
if (language === void 0) return [...defaultSTTOptions.language];
|
|
310
|
+
return Array.isArray(language) ? [...language] : [language];
|
|
311
|
+
}
|
|
312
|
+
function createSpeechRecognizer(config, stream) {
|
|
313
|
+
var _a;
|
|
314
|
+
const speechConfig = createSpeechConfig(config);
|
|
315
|
+
if (config.segmentationSilenceTimeoutMs !== void 0) {
|
|
316
|
+
speechConfig.setProperty(
|
|
317
|
+
speechsdk.PropertyId.Speech_SegmentationSilenceTimeoutMs,
|
|
318
|
+
String(config.segmentationSilenceTimeoutMs)
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
if (config.segmentationMaxTimeMs !== void 0) {
|
|
322
|
+
speechConfig.setProperty(
|
|
323
|
+
speechsdk.PropertyId.Speech_SegmentationMaximumTimeMs,
|
|
324
|
+
String(config.segmentationMaxTimeMs)
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
if (config.segmentationStrategy !== void 0) {
|
|
328
|
+
speechConfig.setProperty(
|
|
329
|
+
speechsdk.PropertyId.Speech_SegmentationStrategy,
|
|
330
|
+
config.segmentationStrategy
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
if (config.profanity !== void 0) {
|
|
334
|
+
speechConfig.setProfanity(config.profanity);
|
|
335
|
+
}
|
|
336
|
+
if (config.explicitPunctuation) {
|
|
337
|
+
speechConfig.setServiceProperty(
|
|
338
|
+
"punctuation",
|
|
339
|
+
"explicit",
|
|
340
|
+
speechsdk.ServicePropertyChannel.UriQueryParameter
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
if (config.trueTextPostProcessing) {
|
|
344
|
+
speechConfig.setProperty(
|
|
345
|
+
speechsdk.PropertyId.SpeechServiceResponse_PostProcessingOption,
|
|
346
|
+
"TrueText"
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
const audioConfig = speechsdk.AudioConfig.fromStreamInput(stream);
|
|
350
|
+
const recognizer = config.language.length > 1 ? createMultiLanguageRecognizer(speechConfig, audioConfig, config.language) : new speechsdk.SpeechRecognizer(speechConfig, audioConfig);
|
|
351
|
+
if ((_a = config.phraseList) == null ? void 0 : _a.length) {
|
|
352
|
+
const phraseListGrammar = speechsdk.PhraseListGrammar.fromRecognizer(recognizer);
|
|
353
|
+
for (const phrase of config.phraseList) {
|
|
354
|
+
phraseListGrammar.addPhrase(phrase);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return recognizer;
|
|
358
|
+
}
|
|
359
|
+
function createSpeechConfig(config) {
|
|
360
|
+
if (config.speechEndpoint) {
|
|
361
|
+
const speechConfig2 = speechsdk.SpeechConfig.fromEndpoint(
|
|
362
|
+
new URL(config.speechEndpoint),
|
|
363
|
+
config.speechKey
|
|
364
|
+
);
|
|
365
|
+
if (config.speechAuthToken) speechConfig2.authorizationToken = config.speechAuthToken;
|
|
366
|
+
speechConfig2.speechRecognitionLanguage = firstLanguage(config);
|
|
367
|
+
return speechConfig2;
|
|
368
|
+
}
|
|
369
|
+
if (config.speechHost) {
|
|
370
|
+
const speechConfig2 = speechsdk.SpeechConfig.fromHost(
|
|
371
|
+
new URL(config.speechHost),
|
|
372
|
+
config.speechKey
|
|
373
|
+
);
|
|
374
|
+
if (config.speechAuthToken) speechConfig2.authorizationToken = config.speechAuthToken;
|
|
375
|
+
speechConfig2.speechRecognitionLanguage = firstLanguage(config);
|
|
376
|
+
return speechConfig2;
|
|
377
|
+
}
|
|
378
|
+
if (config.speechAuthToken) {
|
|
379
|
+
const speechConfig2 = speechsdk.SpeechConfig.fromAuthorizationToken(
|
|
380
|
+
config.speechAuthToken,
|
|
381
|
+
config.speechRegion
|
|
382
|
+
);
|
|
383
|
+
speechConfig2.speechRecognitionLanguage = firstLanguage(config);
|
|
384
|
+
return speechConfig2;
|
|
385
|
+
}
|
|
386
|
+
const speechConfig = speechsdk.SpeechConfig.fromSubscription(
|
|
387
|
+
config.speechKey,
|
|
388
|
+
config.speechRegion
|
|
389
|
+
);
|
|
390
|
+
speechConfig.speechRecognitionLanguage = firstLanguage(config);
|
|
391
|
+
return speechConfig;
|
|
392
|
+
}
|
|
393
|
+
function firstLanguage(config) {
|
|
394
|
+
return config.language[0] ?? "en-US";
|
|
395
|
+
}
|
|
396
|
+
function createMultiLanguageRecognizer(speechConfig, audioConfig, languages) {
|
|
397
|
+
speechConfig.setProperty(
|
|
398
|
+
speechsdk.PropertyId.SpeechServiceConnection_LanguageIdMode,
|
|
399
|
+
"Continuous"
|
|
400
|
+
);
|
|
401
|
+
const autoDetectSourceLanguageConfig = speechsdk.AutoDetectSourceLanguageConfig.fromLanguages(languages);
|
|
402
|
+
return speechsdk.SpeechRecognizer.FromConfig(
|
|
403
|
+
speechConfig,
|
|
404
|
+
autoDetectSourceLanguageConfig,
|
|
405
|
+
audioConfig
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
function toArrayBuffer(frame) {
|
|
409
|
+
const view = new Uint8Array(frame.data.buffer, frame.data.byteOffset, frame.data.byteLength);
|
|
410
|
+
const buffer = new ArrayBuffer(view.byteLength);
|
|
411
|
+
new Uint8Array(buffer).set(view);
|
|
412
|
+
return buffer;
|
|
413
|
+
}
|
|
414
|
+
async function withTimeout(promise, timeoutMs) {
|
|
415
|
+
let timeout;
|
|
416
|
+
try {
|
|
417
|
+
await Promise.race([
|
|
418
|
+
promise,
|
|
419
|
+
new Promise((_, reject) => {
|
|
420
|
+
timeout = setTimeout(
|
|
421
|
+
() => reject(new APIConnectionError({ message: "Request timed out." })),
|
|
422
|
+
timeoutMs
|
|
423
|
+
);
|
|
424
|
+
})
|
|
425
|
+
]);
|
|
426
|
+
} finally {
|
|
427
|
+
if (timeout) clearTimeout(timeout);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
export {
|
|
431
|
+
STT,
|
|
432
|
+
SpeechStream,
|
|
433
|
+
speechsdk
|
|
434
|
+
};
|
|
435
|
+
//# sourceMappingURL=stt.js.map
|
package/dist/stt.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/stt.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport {\n type APIConnectOptions,\n APIConnectionError,\n type AudioBuffer,\n DEFAULT_API_CONNECT_OPTIONS,\n asLanguageCode,\n log,\n stt,\n} from '@livekit/agents';\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport * as speechsdk from 'microsoft-cognitiveservices-speech-sdk';\n\nexport { speechsdk };\n\n/** @public */\nexport interface STTOptions {\n /** Azure Speech subscription key. Defaults to `AZURE_SPEECH_KEY`. */\n speechKey?: string;\n /** Azure Speech region. Defaults to `AZURE_SPEECH_REGION`. */\n speechRegion?: string;\n /** Azure Speech container host. Defaults to `AZURE_SPEECH_HOST`. */\n speechHost?: string;\n /** Ephemeral Microsoft Entra auth token. */\n speechAuthToken?: string;\n /** Azure Speech endpoint URL. */\n speechEndpoint?: string;\n sampleRate: number;\n numChannels: number;\n segmentationSilenceTimeoutMs?: number;\n segmentationMaxTimeMs?: number;\n segmentationStrategy?: string;\n language: string[];\n profanity?: speechsdk.ProfanityOption;\n phraseList?: string[] | null;\n explicitPunctuation: boolean;\n trueTextPostProcessing: boolean;\n}\n\n/** @public */\nexport type STTUpdateOptions = Partial<\n Pick<\n STTOptions,\n 'segmentationSilenceTimeoutMs' | 'segmentationMaxTimeMs' | 'segmentationStrategy'\n >\n> & {\n language?: string | string[];\n};\n\n/** @public */\nexport interface STTConstructorOptions extends STTUpdateOptions {\n speechKey?: string;\n speechRegion?: string;\n speechHost?: string;\n speechAuthToken?: string;\n speechEndpoint?: string;\n sampleRate?: number;\n numChannels?: number;\n profanity?: speechsdk.ProfanityOption;\n phraseList?: string[] | null;\n explicitPunctuation?: boolean;\n trueTextPostProcessing?: boolean;\n}\n\n/** @internal */\nexport interface _CanceledEvent {\n errorDetails?: string;\n reason: speechsdk.CancellationReason;\n errorCode?: speechsdk.CancellationErrorCode;\n}\n\n/** @internal */\nexport interface _WaitableEvent {\n isSet: boolean;\n wait(): Promise<void>;\n set(): void;\n clear(): void;\n}\n\nclass DeferredEvent implements _WaitableEvent {\n #resolve?: () => void;\n #promise: Promise<void>;\n isSet = false;\n\n constructor() {\n this.#promise = new Promise<void>((resolve) => {\n this.#resolve = resolve;\n });\n }\n\n wait(): Promise<void> {\n return this.#promise;\n }\n\n set(): void {\n if (this.isSet) return;\n this.isSet = true;\n this.#resolve?.();\n }\n\n clear(): void {\n if (!this.isSet) return;\n this.isSet = false;\n this.#promise = new Promise<void>((resolve) => {\n this.#resolve = resolve;\n });\n }\n}\n\nconst defaultSTTOptions = {\n sampleRate: 16000,\n numChannels: 1,\n language: ['en-US'],\n explicitPunctuation: false,\n trueTextPostProcessing: false,\n} satisfies Pick<\n STTOptions,\n 'sampleRate' | 'numChannels' | 'language' | 'explicitPunctuation' | 'trueTextPostProcessing'\n>;\n\n/** @public */\nexport class STT extends stt.STT {\n #opts: STTOptions;\n #streams = new Set<WeakRef<SpeechStream>>();\n label = 'azure.STT';\n\n get model(): string {\n return 'unknown';\n }\n\n get provider(): string {\n return 'Azure STT';\n }\n\n constructor(opts: STTConstructorOptions = {}) {\n super({ streaming: true, interimResults: true, alignedTranscript: 'chunk' });\n\n const speechHost = opts.speechHost ?? process.env.AZURE_SPEECH_HOST;\n const speechKey = opts.speechKey ?? process.env.AZURE_SPEECH_KEY;\n const speechRegion = opts.speechRegion ?? process.env.AZURE_SPEECH_REGION;\n const speechAuthToken = opts.speechAuthToken;\n const speechEndpoint = opts.speechEndpoint;\n\n if (\n !speechHost &&\n !(speechKey && speechRegion) &&\n !(speechAuthToken && speechRegion) &&\n !(speechKey && speechEndpoint)\n ) {\n throw new Error(\n 'AZURE_SPEECH_HOST or AZURE_SPEECH_KEY and AZURE_SPEECH_REGION or speechAuthToken and AZURE_SPEECH_REGION or AZURE_SPEECH_KEY and speechEndpoint must be set',\n );\n }\n\n if (speechRegion && speechEndpoint) {\n log().warn('speechRegion and speechEndpoint both are set, using speechEndpoint');\n }\n\n this.#opts = {\n ...defaultSTTOptions,\n ...opts,\n speechHost,\n speechKey,\n speechRegion: speechEndpoint ? undefined : speechRegion,\n speechAuthToken,\n speechEndpoint,\n language: normalizeLanguages(opts.language),\n };\n }\n\n async _recognize(_frame: AudioBuffer): Promise<stt.SpeechEvent> {\n throw new Error('Azure STT does not support single frame recognition');\n }\n\n updateOptions(opts: STTUpdateOptions): void {\n this.#opts = {\n ...this.#opts,\n ...opts,\n language:\n opts.language === undefined ? this.#opts.language : normalizeLanguages(opts.language),\n };\n\n for (const ref of this.#streams) {\n const stream = ref.deref();\n if (stream) {\n stream.updateOptions(opts);\n } else {\n this.#streams.delete(ref);\n }\n }\n }\n\n stream(options: { language?: string; connOptions?: APIConnectOptions } = {}): SpeechStream {\n const opts = {\n ...this.#opts,\n language: options.language ? [options.language] : [...this.#opts.language],\n };\n const stream = new SpeechStream(this, opts, options.connOptions ?? DEFAULT_API_CONNECT_OPTIONS);\n this.#streams.add(new WeakRef(stream));\n return stream;\n }\n}\n\n/** @public */\nexport class SpeechStream extends stt.SpeechStream {\n /** @internal */\n _opts: STTOptions;\n /** @internal */\n _speaking = false;\n /** @internal */\n _sessionStoppedEvent: _WaitableEvent = new DeferredEvent();\n /** @internal */\n _sessionStartedEvent: _WaitableEvent = new DeferredEvent();\n /** @internal */\n _reconnectEvent: _WaitableEvent = new DeferredEvent();\n /** @internal */\n _cancellationError: _CanceledEvent | null = null;\n #connOptions: APIConnectOptions;\n #audioDuration = 0;\n #lastAudioDurationReportTime = performance.now();\n label = 'azure.SpeechStream';\n\n constructor(stt: STT, opts: STTOptions, connOptions: APIConnectOptions) {\n super(stt, opts.sampleRate, connOptions);\n this._opts = opts;\n this.#connOptions = connOptions;\n }\n\n updateOptions(opts: STTUpdateOptions): void {\n this._opts = {\n ...this._opts,\n ...opts,\n language:\n opts.language === undefined ? this._opts.language : normalizeLanguages(opts.language),\n };\n this._reconnectEvent.set();\n }\n\n protected async run(): Promise<void> {\n while (!this.input.closed && !this.closed) {\n this._sessionStoppedEvent.clear();\n this._sessionStartedEvent.clear();\n this._cancellationError = null;\n this._speaking = false;\n\n const pushStream = speechsdk.AudioInputStream.createPushStream(\n speechsdk.AudioStreamFormat.getWaveFormatPCM(\n this._opts.sampleRate,\n 16,\n this._opts.numChannels,\n ),\n );\n const recognizer = createSpeechRecognizer(this._opts, pushStream);\n this.#connectRecognizerEvents(recognizer);\n\n await new Promise<void>((resolve, reject) => {\n recognizer.startContinuousRecognitionAsync(resolve, (error) => reject(new Error(error)));\n });\n\n try {\n await withTimeout(this._sessionStartedEvent.wait(), this.#connOptions.timeoutMs);\n\n const inputAbortController = new AbortController();\n const inputTask = this.#processInput(pushStream, inputAbortController.signal);\n let inputEnded = false;\n try {\n const completed = await Promise.race([\n inputTask.then(() => 'input' as const),\n this._reconnectEvent.wait().then(() => 'reconnect' as const),\n this._sessionStoppedEvent.wait().then(() => 'stopped' as const),\n ]);\n\n if (completed === 'stopped') {\n const details = this._cancellationError as _CanceledEvent | null;\n if (details !== null) {\n throw new APIConnectionError({\n message:\n `Azure STT canceled: ${details.errorDetails || details.reason} ` +\n `(${details.errorCode})`,\n });\n }\n throw new APIConnectionError({ message: 'SpeechRecognition session stopped' });\n }\n\n if (completed === 'reconnect') {\n this._reconnectEvent.clear();\n }\n\n inputEnded = completed === 'input';\n } finally {\n inputAbortController.abort();\n await inputTask;\n pushStream.close();\n }\n\n if (inputEnded) {\n await this._sessionStoppedEvent.wait();\n break;\n }\n } finally {\n await new Promise<void>((resolve) => {\n recognizer.stopContinuousRecognitionAsync(resolve, () => resolve());\n });\n recognizer.close();\n }\n }\n }\n\n async #processInput(\n pushStream: speechsdk.PushAudioInputStream,\n abortSignal: AbortSignal,\n ): Promise<void> {\n try {\n while (!this.closed) {\n let result: IteratorResult<AudioFrame | typeof SpeechStream.FLUSH_SENTINEL>;\n try {\n result = await this.input.next({ signal: abortSignal });\n } catch (error) {\n if (abortSignal.aborted) break;\n throw error;\n }\n if (result.done) break;\n\n const input = result.value;\n if (input === SpeechStream.FLUSH_SENTINEL) {\n this.#emitRecognitionUsage();\n continue;\n }\n\n this.#audioDuration += input.samplesPerChannel / input.sampleRate;\n this.#maybeEmitRecognitionUsage();\n pushStream.write(toArrayBuffer(input));\n }\n } finally {\n this.#emitRecognitionUsage();\n }\n }\n\n #connectRecognizerEvents(recognizer: speechsdk.SpeechRecognizer): void {\n recognizer.recognizing = (_sender, evt) => this._onRecognizing(evt);\n recognizer.recognized = (_sender, evt) => this._onRecognized(evt);\n recognizer.speechStartDetected = (_sender, evt) => this._onSpeechStart(evt);\n recognizer.speechEndDetected = (_sender, evt) => this._onSpeechEnd(evt);\n recognizer.sessionStarted = (_sender, evt) => this._onSessionStarted(evt);\n recognizer.sessionStopped = (_sender, evt) => this._onSessionStopped(evt);\n recognizer.canceled = (_sender, evt) => this._onCanceled(evt);\n }\n\n /** @internal */\n _onRecognized(evt: speechsdk.SpeechRecognitionEventArgs): void {\n const text = evt.result.text.trim();\n if (!text) return;\n\n this.queue.put({\n type: stt.SpeechEventType.FINAL_TRANSCRIPT,\n alternatives: [this.#speechData(evt, 1)],\n });\n }\n\n /** @internal */\n _onRecognizing(evt: speechsdk.SpeechRecognitionEventArgs): void {\n const text = evt.result.text.trim();\n if (!text) return;\n\n this.queue.put({\n type: stt.SpeechEventType.INTERIM_TRANSCRIPT,\n alternatives: [this.#speechData(evt, 0)],\n });\n }\n\n /** @internal */\n _onSpeechStart(_evt: speechsdk.RecognitionEventArgs): void {\n if (this._speaking) return;\n this._speaking = true;\n this.queue.put({ type: stt.SpeechEventType.START_OF_SPEECH });\n }\n\n /** @internal */\n _onSpeechEnd(_evt: speechsdk.RecognitionEventArgs): void {\n if (!this._speaking) return;\n this._speaking = false;\n this.queue.put({ type: stt.SpeechEventType.END_OF_SPEECH });\n }\n\n /** @internal */\n _onSessionStarted(_evt: speechsdk.SessionEventArgs): void {\n this._sessionStartedEvent.set();\n }\n\n /** @internal */\n _onSessionStopped(_evt: speechsdk.SessionEventArgs): void {\n this._sessionStoppedEvent.set();\n }\n\n /** @internal */\n _onCanceled(evt: _CanceledEvent): void {\n if (evt.reason === speechsdk.CancellationReason.Error) {\n log().warn(\n {\n code: evt.errorCode,\n reason: evt.reason,\n errorDetails: evt.errorDetails,\n },\n `Speech recognition canceled: ${evt.errorDetails || evt.reason}`,\n );\n this._cancellationError = evt;\n this._sessionStoppedEvent.set();\n }\n }\n\n #speechData(evt: speechsdk.SpeechRecognitionEventArgs, confidence: number): stt.SpeechData {\n const result = speechsdk.AutoDetectSourceLanguageResult.fromResult(evt.result);\n const language = result.language || this._opts.language[0] || '';\n return {\n language: asLanguageCode(language),\n confidence,\n text: evt.result.text,\n startTime: evt.result.offset / 10 ** 7 + this.startTimeOffset,\n endTime: (evt.result.offset + evt.result.duration) / 10 ** 7 + this.startTimeOffset,\n };\n }\n\n #maybeEmitRecognitionUsage(): void {\n if (performance.now() - this.#lastAudioDurationReportTime >= 5000) {\n this.#emitRecognitionUsage();\n }\n }\n\n #emitRecognitionUsage(): void {\n if (this.#audioDuration <= 0) return;\n\n const audioDuration = this.#audioDuration;\n this.#audioDuration = 0;\n this.#lastAudioDurationReportTime = performance.now();\n this.queue.put({\n type: stt.SpeechEventType.RECOGNITION_USAGE,\n recognitionUsage: { audioDuration },\n });\n }\n}\n\nfunction normalizeLanguages(language?: string | string[]): string[] {\n if (language === undefined) return [...defaultSTTOptions.language];\n return Array.isArray(language) ? [...language] : [language];\n}\n\nfunction createSpeechRecognizer(\n config: STTOptions,\n stream: speechsdk.PushAudioInputStream,\n): speechsdk.SpeechRecognizer {\n const speechConfig = createSpeechConfig(config);\n\n if (config.segmentationSilenceTimeoutMs !== undefined) {\n speechConfig.setProperty(\n speechsdk.PropertyId.Speech_SegmentationSilenceTimeoutMs,\n String(config.segmentationSilenceTimeoutMs),\n );\n }\n if (config.segmentationMaxTimeMs !== undefined) {\n speechConfig.setProperty(\n speechsdk.PropertyId.Speech_SegmentationMaximumTimeMs,\n String(config.segmentationMaxTimeMs),\n );\n }\n if (config.segmentationStrategy !== undefined) {\n speechConfig.setProperty(\n speechsdk.PropertyId.Speech_SegmentationStrategy,\n config.segmentationStrategy,\n );\n }\n if (config.profanity !== undefined) {\n speechConfig.setProfanity(config.profanity);\n }\n if (config.explicitPunctuation) {\n speechConfig.setServiceProperty(\n 'punctuation',\n 'explicit',\n speechsdk.ServicePropertyChannel.UriQueryParameter,\n );\n }\n if (config.trueTextPostProcessing) {\n speechConfig.setProperty(\n speechsdk.PropertyId.SpeechServiceResponse_PostProcessingOption,\n 'TrueText',\n );\n }\n\n const audioConfig = speechsdk.AudioConfig.fromStreamInput(stream);\n const recognizer =\n config.language.length > 1\n ? createMultiLanguageRecognizer(speechConfig, audioConfig, config.language)\n : new speechsdk.SpeechRecognizer(speechConfig, audioConfig);\n\n if (config.phraseList?.length) {\n const phraseListGrammar = speechsdk.PhraseListGrammar.fromRecognizer(recognizer);\n for (const phrase of config.phraseList) {\n phraseListGrammar.addPhrase(phrase);\n }\n }\n\n return recognizer;\n}\n\nfunction createSpeechConfig(config: STTOptions): speechsdk.SpeechConfig {\n if (config.speechEndpoint) {\n const speechConfig = speechsdk.SpeechConfig.fromEndpoint(\n new URL(config.speechEndpoint),\n config.speechKey,\n );\n if (config.speechAuthToken) speechConfig.authorizationToken = config.speechAuthToken;\n speechConfig.speechRecognitionLanguage = firstLanguage(config);\n return speechConfig;\n }\n if (config.speechHost) {\n const speechConfig = speechsdk.SpeechConfig.fromHost(\n new URL(config.speechHost),\n config.speechKey,\n );\n if (config.speechAuthToken) speechConfig.authorizationToken = config.speechAuthToken;\n speechConfig.speechRecognitionLanguage = firstLanguage(config);\n return speechConfig;\n }\n if (config.speechAuthToken) {\n const speechConfig = speechsdk.SpeechConfig.fromAuthorizationToken(\n config.speechAuthToken,\n config.speechRegion!,\n );\n speechConfig.speechRecognitionLanguage = firstLanguage(config);\n return speechConfig;\n }\n const speechConfig = speechsdk.SpeechConfig.fromSubscription(\n config.speechKey!,\n config.speechRegion!,\n );\n speechConfig.speechRecognitionLanguage = firstLanguage(config);\n return speechConfig;\n}\n\nfunction firstLanguage(config: STTOptions): string {\n return config.language[0] ?? 'en-US';\n}\n\nfunction createMultiLanguageRecognizer(\n speechConfig: speechsdk.SpeechConfig,\n audioConfig: speechsdk.AudioConfig,\n languages: string[],\n): speechsdk.SpeechRecognizer {\n speechConfig.setProperty(\n speechsdk.PropertyId.SpeechServiceConnection_LanguageIdMode,\n 'Continuous',\n );\n const autoDetectSourceLanguageConfig =\n speechsdk.AutoDetectSourceLanguageConfig.fromLanguages(languages);\n return speechsdk.SpeechRecognizer.FromConfig(\n speechConfig,\n autoDetectSourceLanguageConfig,\n audioConfig,\n );\n}\n\nfunction toArrayBuffer(frame: AudioFrame): ArrayBuffer {\n const view = new Uint8Array(frame.data.buffer, frame.data.byteOffset, frame.data.byteLength);\n const buffer = new ArrayBuffer(view.byteLength);\n new Uint8Array(buffer).set(view);\n return buffer;\n}\n\nasync function withTimeout(promise: Promise<void>, timeoutMs: number): Promise<void> {\n let timeout: NodeJS.Timeout | undefined;\n try {\n await Promise.race([\n promise,\n new Promise<void>((_, reject) => {\n timeout = setTimeout(\n () => reject(new APIConnectionError({ message: 'Request timed out.' })),\n timeoutMs,\n );\n }),\n ]);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n"],"mappings":"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","names":["stt","speechConfig"]}
|