@andresaya/edge-tts 1.6.1 → 1.7.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.
@@ -63,6 +63,47 @@ var EdgeTTSModule = (() => {
63
63
  "Sec-Fetch-Site": "none",
64
64
  "Sec-Fetch-Mode": "cors",
65
65
  "Sec-Fetch-Dest": "empty"
66
+ },
67
+ // https://learn.microsoft.com/en-us/azure/ai-services/speech-service/rest-text-to-speech?tabs=nonstreaming
68
+ OUTPUT_FORMAT: {
69
+ // Streaming
70
+ AMR_WB_16000HZ: "amr-wb-16000hz",
71
+ AUDIO_16KHZ_16BIT_32KBPS_MONO_OPUS: "audio-16khz-16bit-32kbps-mono-opus",
72
+ AUDIO_16KHZ_32KBITRATE_MONO_MP3: "audio-16khz-32kbitrate-mono-mp3",
73
+ AUDIO_16KHZ_64KBITRATE_MONO_MP3: "audio-16khz-64kbitrate-mono-mp3",
74
+ AUDIO_16KHZ_128KBITRATE_MONO_MP3: "audio-16khz-128kbitrate-mono-mp3",
75
+ AUDIO_24KHZ_16BIT_24KBPS_MONO_OPUS: "audio-24khz-16bit-24kbps-mono-opus",
76
+ AUDIO_24KHZ_16BIT_48KBPS_MONO_OPUS: "audio-24khz-16bit-48kbps-mono-opus",
77
+ AUDIO_24KHZ_48KBITRATE_MONO_MP3: "audio-24khz-48kbitrate-mono-mp3",
78
+ AUDIO_24KHZ_96KBITRATE_MONO_MP3: "audio-24khz-96kbitrate-mono-mp3",
79
+ AUDIO_24KHZ_160KBITRATE_MONO_MP3: "audio-24khz-160kbitrate-mono-mp3",
80
+ AUDIO_48KHZ_96KBITRATE_MONO_MP3: "audio-48khz-96kbitrate-mono-mp3",
81
+ AUDIO_48KHZ_192KBITRATE_MONO_MP3: "audio-48khz-192kbitrate-mono-mp3",
82
+ G722_16KHZ_64KBPS: "g722-16khz-64kbps",
83
+ OGG_16KHZ_16BIT_MONO_OPUS: "ogg-16khz-16bit-mono-opus",
84
+ OGG_24KHZ_16BIT_MONO_OPUS: "ogg-24khz-16bit-mono-opus",
85
+ OGG_48KHZ_16BIT_MONO_OPUS: "ogg-48khz-16bit-mono-opus",
86
+ RAW_8KHZ_8BIT_MONO_ALAW: "raw-8khz-8bit-mono-alaw",
87
+ RAW_8KHZ_8BIT_MONO_MULAW: "raw-8khz-8bit-mono-mulaw",
88
+ RAW_8KHZ_16BIT_MONO_PCM: "raw-8khz-16bit-mono-pcm",
89
+ RAW_16KHZ_16BIT_MONO_PCM: "raw-16khz-16bit-mono-pcm",
90
+ RAW_16KHZ_16BIT_MONO_TRUESILK: "raw-16khz-16bit-mono-truesilk",
91
+ RAW_22050HZ_16BIT_MONO_PCM: "raw-22050hz-16bit-mono-pcm",
92
+ RAW_24KHZ_16BIT_MONO_PCM: "raw-24khz-16bit-mono-pcm",
93
+ RAW_24KHZ_16BIT_MONO_TRUESILK: "raw-24khz-16bit-mono-truesilk",
94
+ RAW_44100HZ_16BIT_MONO_PCM: "raw-44100hz-16bit-mono-pcm",
95
+ RAW_48KHZ_16BIT_MONO_PCM: "raw-48khz-16bit-mono-pcm",
96
+ WEBM_16KHZ_16BIT_MONO_OPUS: "webm-16khz-16bit-mono-opus",
97
+ WEBM_24KHZ_16BIT_24KBPS_MONO_OPUS: "webm-24khz-16bit-24kbps-mono-opus",
98
+ WEBM_24KHZ_16BIT_MONO_OPUS: "webm-24khz-16bit-mono-opus",
99
+ // NonStreaming
100
+ RIFF_8KHZ_8BIT_MONO_ALAW: "riff-8khz-8bit-mono-alaw",
101
+ RIFF_8KHZ_8BIT_MONO_MULAW: "riff-8khz-8bit-mono-mulaw",
102
+ RIFF_8KHZ_16BIT_MONO_PCM: "riff-8khz-16bit-mono-pcm",
103
+ RIFF_22050HZ_16BIT_MONO_PCM: "riff-22050hz-16bit-mono-pcm",
104
+ RIFF_24KHZ_16BIT_MONO_PCM: "riff-24khz-16bit-mono-pcm",
105
+ RIFF_44100HZ_16BIT_MONO_PCM: "riff-44100hz-16bit-mono-pcm",
106
+ RIFF_48KHZ_16BIT_MONO_PCM: "riff-48khz-16bit-mono-pcm"
66
107
  }
67
108
  };
68
109
 
@@ -223,13 +264,20 @@ Path:speech.config\r
223
264
  console.log("WebSocket URL:", url);
224
265
  this.ws = new WebSocket(url);
225
266
  const SSML_text = this.getSSML(text, voice, options);
226
- const timeout = setTimeout(() => {
227
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
228
- this.ws.close();
229
- }
230
- reject(new Error("Synthesis timeout"));
231
- }, 3e4);
267
+ let timedOut = false;
268
+ let inactivityTimeout;
269
+ const resetInactivityTimeout = () => {
270
+ clearTimeout(inactivityTimeout);
271
+ inactivityTimeout = window.setTimeout(() => {
272
+ timedOut = true;
273
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
274
+ this.ws.close();
275
+ }
276
+ reject(new Error("WebSocket inactivity timeout - no response from server"));
277
+ }, 3e4);
278
+ };
232
279
  this.ws.onopen = () => {
280
+ resetInactivityTimeout();
233
281
  const message = this.buildTTSConfigMessage();
234
282
  this.ws.send(message);
235
283
  const timestamp = this.nowRFC1123();
@@ -242,6 +290,7 @@ ${SSML_text}`;
242
290
  this.ws.send(speechMessage);
243
291
  };
244
292
  this.ws.onmessage = (event) => {
293
+ resetInactivityTimeout();
245
294
  if (typeof event.data === "string") {
246
295
  if (event.data.includes("Path:turn.end")) {
247
296
  this.ws?.close();
@@ -257,15 +306,17 @@ ${SSML_text}`;
257
306
  }
258
307
  };
259
308
  this.ws.onerror = (err) => {
260
- clearTimeout(timeout);
309
+ clearTimeout(inactivityTimeout);
261
310
  if (this.ws && this.ws.readyState === WebSocket.OPEN) {
262
311
  this.ws.close();
263
312
  }
264
313
  reject(new Error("WebSocket error"));
265
314
  };
266
315
  this.ws.onclose = () => {
267
- clearTimeout(timeout);
268
- resolve();
316
+ clearTimeout(inactivityTimeout);
317
+ if (!timedOut) {
318
+ resolve();
319
+ }
269
320
  };
270
321
  });
271
322
  }
@@ -287,12 +338,25 @@ ${SSML_text}`;
287
338
  notify = null;
288
339
  }
289
340
  };
290
- const timeout = setTimeout(() => {
291
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
292
- this.ws.close();
293
- }
294
- }, 3e4);
341
+ let timedOut = false;
342
+ let inactivityTimeout;
343
+ const resetInactivityTimeout = () => {
344
+ clearTimeout(inactivityTimeout);
345
+ inactivityTimeout = window.setTimeout(() => {
346
+ timedOut = true;
347
+ error = new Error("WebSocket inactivity timeout - no response from server");
348
+ done = true;
349
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
350
+ this.ws.close();
351
+ }
352
+ if (notify) {
353
+ notify();
354
+ notify = null;
355
+ }
356
+ }, 3e4);
357
+ };
295
358
  this.ws.onopen = () => {
359
+ resetInactivityTimeout();
296
360
  const message = this.buildTTSConfigMessage();
297
361
  this.ws.send(message);
298
362
  const timestamp = this.nowRFC1123();
@@ -305,6 +369,7 @@ ${SSML_text}`;
305
369
  this.ws.send(speechMessage);
306
370
  };
307
371
  this.ws.onmessage = (event) => {
372
+ resetInactivityTimeout();
308
373
  if (typeof event.data === "string") {
309
374
  if (event.data.includes("Path:turn.end")) {
310
375
  this.ws?.close();
@@ -326,6 +391,7 @@ ${SSML_text}`;
326
391
  }
327
392
  };
328
393
  this.ws.onerror = (err) => {
394
+ clearTimeout(inactivityTimeout);
329
395
  error = new Error("WebSocket error");
330
396
  done = true;
331
397
  if (notify) {
@@ -334,7 +400,7 @@ ${SSML_text}`;
334
400
  }
335
401
  };
336
402
  this.ws.onclose = () => {
337
- clearTimeout(timeout);
403
+ clearTimeout(inactivityTimeout);
338
404
  done = true;
339
405
  if (notify) {
340
406
  notify();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/browser/EdgeTTS.browser.ts", "../../src/config/constants.ts"],
4
- "sourcesContent": ["import { Constants } from '../config/constants';\r\n\r\nexport interface Voice {\r\n Name: string;\r\n ShortName: string;\r\n Gender: string;\r\n Locale: string;\r\n FriendlyName: string;\r\n LocalName: string;\r\n}\r\n\r\nexport interface SynthesisOptions {\r\n pitch?: string | number;\r\n rate?: string | number;\r\n volume?: string | number;\r\n inputType?: 'auto' | 'ssml' | 'text';\r\n}\r\n\r\ninterface SSMLValidationResult {\r\n isValid: boolean;\r\n isSSML: boolean;\r\n errors?: string[];\r\n}\r\n\r\nexport class EdgeTTS {\r\n private audio_stream: Uint8Array[] = [];\r\n private ws?: WebSocket;\r\n\r\n async getVoices(): Promise<Voice[]> {\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n \r\n const response = await fetch(\r\n `${Constants.VOICES_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}`,\r\n { headers: Constants.getBaseHeaders() }\r\n );\r\n \r\n const data = await response.json();\r\n return data.map((voice: any) => {\r\n voice.FriendlyName = voice.FriendlyName || voice.LocalName;\r\n delete voice.SampleRateHertz;\r\n delete voice.Status;\r\n return voice;\r\n });\r\n }\r\n\r\n async getVoicesByLanguage(locale: string): Promise<Voice[]> {\r\n const voices = await this.getVoices();\r\n return voices.filter(voice => voice.Locale.startsWith(locale));\r\n }\r\n\r\n async getVoicesByGender(gender: 'Male' | 'Female'): Promise<Voice[]> {\r\n const voices = await this.getVoices();\r\n return voices.filter(voice => voice.Gender === gender);\r\n }\r\n\r\n private generateUUID(): string {\r\n return 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\r\n const r = Math.random() * 16 | 0;\r\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\r\n return v.toString(16);\r\n });\r\n }\r\n\r\n private validatePitch(pitch: string | number): string {\r\n if (typeof pitch === 'number') {\r\n return (pitch >= 0 ? `+${pitch}Hz` : `${pitch}Hz`);\r\n }\r\n return pitch;\r\n }\r\n\r\n private validateRate(rate: string | number): string {\r\n let rateValue: number;\r\n if (typeof rate === 'string') {\r\n rateValue = parseFloat(rate.replace('%', ''));\r\n } else {\r\n rateValue = rate;\r\n }\r\n return rateValue >= 0 ? `+${rateValue}%` : `${rateValue}%`;\r\n }\r\n\r\n private validateVolume(volume: string | number): string {\r\n let volumeValue: number;\r\n if (typeof volume === 'string') {\r\n volumeValue = parseInt(volume.replace('%', ''), 10);\r\n } else {\r\n volumeValue = volume;\r\n }\r\n return `${volumeValue}%`;\r\n }\r\n\r\n private detectSSML(content: string): SSMLValidationResult {\r\n const trimmedContent = content.trim();\r\n const looksLikeSSML = /^<\\?xml|^<speak/i.test(trimmedContent);\r\n\r\n if (!looksLikeSSML) {\r\n return { isValid: true, isSSML: false };\r\n }\r\n\r\n const errors: string[] = [];\r\n const hasSpeakTag = /<speak\\b[^>]*>[\\s\\S]*<\\/speak>/i.test(trimmedContent);\r\n const hasVoiceTag = /<voice\\b[^>]*>[\\s\\S]*<\\/voice>/i.test(trimmedContent);\r\n\r\n if (!hasSpeakTag) {\r\n throw new Error('Invalid SSML: Missing <speak> tag');\r\n }\r\n\r\n if (!hasVoiceTag) {\r\n throw new Error('Invalid SSML: Missing <voice> tag');\r\n }\r\n\r\n const hasCorrectNamespace = /xmlns=\"http:\\/\\/www\\.w3\\.org\\/2001\\/10\\/synthesis\"/i.test(trimmedContent);\r\n if (!hasCorrectNamespace && hasSpeakTag) {\r\n throw new Error('Invalid SSML: Missing or incorrect namespace declaration');\r\n }\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n isSSML: hasSpeakTag || hasVoiceTag,\r\n errors: errors.length > 0 ? errors : undefined\r\n };\r\n }\r\n\r\n private escapeXML(text: string): string {\r\n return text\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&apos;');\r\n }\r\n\r\n private getSSML(content: string, voice: string, options: SynthesisOptions = {}): string {\r\n const inputType = options.inputType || 'auto';\r\n let treatAsSSML = false;\r\n\r\n if (inputType === 'ssml') {\r\n treatAsSSML = true;\r\n } else if (inputType === 'text') {\r\n treatAsSSML = false;\r\n } else { // 'auto'\r\n const detection = this.detectSSML(content);\r\n treatAsSSML = detection.isSSML;\r\n\r\n if (detection.isSSML) {\r\n console.log('\u2192 Detected SSML input');\r\n if (!detection.isValid) {\r\n console.warn('\u26A0 SSML validation warnings:', detection.errors);\r\n }\r\n } else {\r\n console.log('\u2192 Detected plain text input');\r\n }\r\n }\r\n\r\n if (treatAsSSML) {\r\n let ssml = content.trim();\r\n\r\n if (!ssml.includes('xmlns=')) {\r\n ssml = ssml.replace(\r\n /<speak([^>]*)>/i,\r\n '<speak$1 xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"https://www.w3.org/2001/mstts\">'\r\n );\r\n }\r\n\r\n if (!/<voice\\b[^>]*>/i.test(ssml) && voice) {\r\n ssml = ssml.replace(\r\n /(<speak[^>]*>)([\\s\\S]*?)(<\\/speak>)/i,\r\n `$1<voice name=\"${voice}\">$2</voice>$3`\r\n );\r\n }\r\n\r\n return ssml;\r\n }\r\n\r\n const pitch = this.validatePitch(options.pitch ?? 0);\r\n const rate = this.validateRate(options.rate ?? 0);\r\n const volume = this.validateVolume(options.volume ?? 0);\r\n const escapedText = this.escapeXML(content);\r\n\r\n return `<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"https://www.w3.org/2001/mstts\" xml:lang=\"en-US\">\r\n <voice name=\"${voice}\">\r\n <prosody pitch=\"${pitch}\" rate=\"${rate}\" volume=\"${volume}\">\r\n ${escapedText}\r\n </prosody>\r\n </voice>\r\n </speak>`;\r\n }\r\n\r\n private nowRFC1123(): string {\r\n return new Date().toUTCString();\r\n }\r\n\r\n private parseRFC1123(rfcStr: string): Date {\r\n return new Date(rfcStr);\r\n }\r\n\r\n private buildTTSConfigMessage(): string {\r\n const timestamp = this.nowRFC1123();\r\n return `X-Timestamp:${timestamp}\\r\\nContent-Type:application/json; charset=utf-8\\r\\nPath:speech.config\\r\\n\\r\\n` +\r\n `{\"context\":{\"synthesis\":{\"audio\":{\"metadataoptions\":{\"sentenceBoundaryEnabled\":false,\"wordBoundaryEnabled\":true},\"outputFormat\":\"audio-24khz-48kbitrate-mono-mp3\"}}}}`;\r\n }\r\n\r\n async synthesize(text: string, voice: string = 'en-US-JennyNeural', options: SynthesisOptions = {}): Promise<void> {\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n\r\n return new Promise((resolve, reject) => {\r\n this.audio_stream = [];\r\n const reqId = this.generateUUID();\r\n const url = `${Constants.WSS_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}&ConnectionId=${reqId}`;\r\n \r\n console.log('WebSocket URL:', url);\r\n this.ws = new WebSocket(url);\r\n\r\n const SSML_text = this.getSSML(text, voice, options);\r\n \r\n const timeout = setTimeout(() => {\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n reject(new Error(\"Synthesis timeout\"));\r\n }, 30000);\r\n\r\n this.ws.onopen = () => {\r\n const message = this.buildTTSConfigMessage();\r\n this.ws!.send(message);\r\n const timestamp = this.nowRFC1123();\r\n const speechMessage = `X-RequestId:${reqId}\\r\\nContent-Type:application/ssml+xml\\r\\nX-Timestamp:${timestamp}\\r\\nPath:ssml\\r\\n\\r\\n${SSML_text}`;\r\n this.ws!.send(speechMessage);\r\n };\r\n\r\n this.ws.onmessage = (event) => {\r\n if (typeof event.data === 'string') {\r\n if (event.data.includes('Path:turn.end')) {\r\n this.ws?.close();\r\n }\r\n } else {\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const arrayBuffer = reader.result as ArrayBuffer;\r\n const uint8Array = new Uint8Array(arrayBuffer);\r\n this.processAudioData(uint8Array);\r\n };\r\n reader.readAsArrayBuffer(event.data);\r\n }\r\n };\r\n\r\n this.ws.onerror = (err: any) => {\r\n clearTimeout(timeout);\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n reject(new Error('WebSocket error'));\r\n };\r\n\r\n this.ws.onclose = () => {\r\n clearTimeout(timeout);\r\n resolve();\r\n };\r\n });\r\n }\r\n\r\n async *synthesizeStream(text: string, voice: string = 'en-US-JennyNeural', options: SynthesisOptions = {}): AsyncGenerator<Uint8Array, void, unknown> {\r\n this.audio_stream = [];\r\n\r\n const reqId = this.generateUUID();\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n\r\n const url = `${Constants.WSS_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}&ConnectionId=${reqId}`;\r\n\r\n this.ws = new WebSocket(url);\r\n\r\n const SSML_text = this.getSSML(text, voice, options);\r\n\r\n const queue: Uint8Array[] = [];\r\n let done = false;\r\n let error: Error | null = null;\r\n let notify: (() => void) | null = null;\r\n\r\n const push = (chunk: Uint8Array) => {\r\n queue.push(chunk);\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n const timeout = setTimeout(() => {\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n }, 30000);\r\n\r\n this.ws.onopen = () => {\r\n const message = this.buildTTSConfigMessage();\r\n this.ws!.send(message);\r\n\r\n const timestamp = this.nowRFC1123();\r\n const speechMessage = `X-RequestId:${reqId}\\r\\nContent-Type:application/ssml+xml\\r\\nX-Timestamp:${timestamp}\\r\\nPath:ssml\\r\\n\\r\\n${SSML_text}`;\r\n this.ws!.send(speechMessage);\r\n };\r\n\r\n this.ws.onmessage = (event) => {\r\n if (typeof event.data === 'string') {\r\n if (event.data.includes('Path:turn.end')) {\r\n this.ws?.close();\r\n }\r\n } else {\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const arrayBuffer = reader.result as ArrayBuffer;\r\n const uint8Array = new Uint8Array(arrayBuffer);\r\n \r\n const needle = new TextEncoder().encode(\"Path:audio\\r\\n\");\r\n const audioStartIndex = this.indexOf(uint8Array, needle);\r\n\r\n if (audioStartIndex !== -1) {\r\n const audioChunk = uint8Array.slice(audioStartIndex + needle.length);\r\n this.audio_stream.push(audioChunk);\r\n push(audioChunk);\r\n }\r\n };\r\n reader.readAsArrayBuffer(event.data);\r\n }\r\n };\r\n\r\n this.ws.onerror = (err: any) => {\r\n error = new Error('WebSocket error');\r\n done = true;\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n this.ws.onclose = () => {\r\n clearTimeout(timeout);\r\n done = true;\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n while (!done || queue.length > 0) {\r\n if (queue.length === 0) {\r\n await new Promise<void>(resolve => (notify = resolve));\r\n continue;\r\n }\r\n const chunk = queue.shift();\r\n if (chunk) {\r\n yield chunk;\r\n }\r\n }\r\n\r\n if (error) {\r\n throw error;\r\n }\r\n }\r\n\r\n private processAudioData(buffer: Uint8Array): void {\r\n const needle = new TextEncoder().encode(\"Path:audio\\r\\n\");\r\n const audioStartIndex = this.indexOf(buffer, needle);\r\n\r\n if (audioStartIndex !== -1) {\r\n const audioChunk = buffer.slice(audioStartIndex + needle.length);\r\n this.audio_stream.push(audioChunk);\r\n }\r\n }\r\n\r\n private indexOf(arr: Uint8Array, subarr: Uint8Array): number {\r\n for (let i = 0; i <= arr.length - subarr.length; i++) {\r\n let match = true;\r\n for (let j = 0; j < subarr.length; j++) {\r\n if (arr[i + j] !== subarr[j]) {\r\n match = false;\r\n break;\r\n }\r\n }\r\n if (match) return i;\r\n }\r\n return -1;\r\n }\r\n\r\n private async generateSecMsGec(trustedClientToken: string): Promise<string> {\r\n const now = this.nowRFC1123();\r\n const fixedDate = this.parseRFC1123(now);\r\n const ticks = Math.floor(fixedDate.getTime() / 1000) + 11644473600;\r\n const rounded = ticks - (ticks % 300);\r\n const windowsTicks = rounded * 10_000_000;\r\n\r\n const encoder = new TextEncoder();\r\n const data = encoder.encode(`${windowsTicks}${trustedClientToken}`);\r\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\r\n\r\n return Array.from(new Uint8Array(hashBuffer))\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .toUpperCase();\r\n }\r\n\r\n getAudioData(): Uint8Array {\r\n if (this.audio_stream.length === 0) {\r\n throw new Error(\"No audio data available\");\r\n }\r\n const totalLength = this.audio_stream.reduce((acc, chunk) => acc + chunk.length, 0);\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const chunk of this.audio_stream) {\r\n result.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n return result;\r\n }\r\n}\r\n", "export const Constants = {\r\n TRUSTED_CLIENT_TOKEN: '6A5AA1D4EAFF4E9FB37E23D68491D6F4',\r\n BASE_URL: 'https://api.msedgeservices.com/tts/cognitiveservices',\r\n WSS_URL: 'wss://api.msedgeservices.com/tts/cognitiveservices/websocket/v1',\r\n VOICES_URL: 'https://api.msedgeservices.com/tts/cognitiveservices/voices/list',\r\n \r\n CHROMIUM_FULL_VERSION: '142.0.3595.0',\r\n CHROMIUM_MAJOR_VERSION: '142',\r\n VERSION_MS_GEC: '1-142.0.3595',\r\n \r\n token32() {\r\n const bytes = new Uint8Array(16);\r\n crypto.getRandomValues(bytes);\r\n \r\n return Array.from(bytes)\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .toUpperCase();\r\n },\r\n \r\n getBaseHeaders() {\r\n return {\r\n 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\r\n 'Accept-Encoding': 'gzip, deflate, br, zstd',\r\n 'Accept-Language': 'es,es-ES;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,es-CO;q=0.5,es-MX;q=0.4',\r\n 'Cookie': 'MUID=' + this.token32()\r\n };\r\n },\r\n \r\n WSS_HEADERS: {\r\n 'Pragma': 'no-cache',\r\n 'Cache-Control': 'no-cache',\r\n 'Origin': 'chrome-extension://jdiccldimpdaibmpdkjnbmckianbfold',\r\n 'Sec-WebSocket-Protocol': 'synthesize',\r\n 'Sec-WebSocket-Version': '13',\r\n 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0'\r\n },\r\n \r\n VOICE_HEADERS: {\r\n 'Sec-CH-UA': '\" Not;A Brand\";v=\"99\", \"Microsoft Edge\";v=\"140\", \"Chromium\";v=\"140\"',\r\n 'Sec-CH-UA-Mobile': '?0',\r\n 'Accept': '*/*',\r\n 'Sec-Fetch-Site': 'none',\r\n 'Sec-Fetch-Mode': 'cors',\r\n 'Sec-Fetch-Dest': 'empty'\r\n }\r\n};\r\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Constants } from '../config/constants';\r\n\r\nexport interface Voice {\r\n Name: string;\r\n ShortName: string;\r\n Gender: string;\r\n Locale: string;\r\n FriendlyName: string;\r\n LocalName: string;\r\n}\r\n\r\nexport interface SynthesisOptions {\r\n pitch?: string | number;\r\n rate?: string | number;\r\n volume?: string | number;\r\n inputType?: 'auto' | 'ssml' | 'text';\r\n}\r\n\r\ninterface SSMLValidationResult {\r\n isValid: boolean;\r\n isSSML: boolean;\r\n errors?: string[];\r\n}\r\n\r\nexport class EdgeTTS {\r\n private audio_stream: Uint8Array[] = [];\r\n private ws?: WebSocket;\r\n\r\n async getVoices(): Promise<Voice[]> {\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n \r\n const response = await fetch(\r\n `${Constants.VOICES_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}`,\r\n { headers: Constants.getBaseHeaders() }\r\n );\r\n \r\n const data = await response.json();\r\n return data.map((voice: any) => {\r\n voice.FriendlyName = voice.FriendlyName || voice.LocalName;\r\n delete voice.SampleRateHertz;\r\n delete voice.Status;\r\n return voice;\r\n });\r\n }\r\n\r\n async getVoicesByLanguage(locale: string): Promise<Voice[]> {\r\n const voices = await this.getVoices();\r\n return voices.filter(voice => voice.Locale.startsWith(locale));\r\n }\r\n\r\n async getVoicesByGender(gender: 'Male' | 'Female'): Promise<Voice[]> {\r\n const voices = await this.getVoices();\r\n return voices.filter(voice => voice.Gender === gender);\r\n }\r\n\r\n private generateUUID(): string {\r\n return 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\r\n const r = Math.random() * 16 | 0;\r\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\r\n return v.toString(16);\r\n });\r\n }\r\n\r\n private validatePitch(pitch: string | number): string {\r\n if (typeof pitch === 'number') {\r\n return (pitch >= 0 ? `+${pitch}Hz` : `${pitch}Hz`);\r\n }\r\n return pitch;\r\n }\r\n\r\n private validateRate(rate: string | number): string {\r\n let rateValue: number;\r\n if (typeof rate === 'string') {\r\n rateValue = parseFloat(rate.replace('%', ''));\r\n } else {\r\n rateValue = rate;\r\n }\r\n return rateValue >= 0 ? `+${rateValue}%` : `${rateValue}%`;\r\n }\r\n\r\n private validateVolume(volume: string | number): string {\r\n let volumeValue: number;\r\n if (typeof volume === 'string') {\r\n volumeValue = parseInt(volume.replace('%', ''), 10);\r\n } else {\r\n volumeValue = volume;\r\n }\r\n return `${volumeValue}%`;\r\n }\r\n\r\n private detectSSML(content: string): SSMLValidationResult {\r\n const trimmedContent = content.trim();\r\n const looksLikeSSML = /^<\\?xml|^<speak/i.test(trimmedContent);\r\n\r\n if (!looksLikeSSML) {\r\n return { isValid: true, isSSML: false };\r\n }\r\n\r\n const errors: string[] = [];\r\n const hasSpeakTag = /<speak\\b[^>]*>[\\s\\S]*<\\/speak>/i.test(trimmedContent);\r\n const hasVoiceTag = /<voice\\b[^>]*>[\\s\\S]*<\\/voice>/i.test(trimmedContent);\r\n\r\n if (!hasSpeakTag) {\r\n throw new Error('Invalid SSML: Missing <speak> tag');\r\n }\r\n\r\n if (!hasVoiceTag) {\r\n throw new Error('Invalid SSML: Missing <voice> tag');\r\n }\r\n\r\n const hasCorrectNamespace = /xmlns=\"http:\\/\\/www\\.w3\\.org\\/2001\\/10\\/synthesis\"/i.test(trimmedContent);\r\n if (!hasCorrectNamespace && hasSpeakTag) {\r\n throw new Error('Invalid SSML: Missing or incorrect namespace declaration');\r\n }\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n isSSML: hasSpeakTag || hasVoiceTag,\r\n errors: errors.length > 0 ? errors : undefined\r\n };\r\n }\r\n\r\n private escapeXML(text: string): string {\r\n return text\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&apos;');\r\n }\r\n\r\n private getSSML(content: string, voice: string, options: SynthesisOptions = {}): string {\r\n const inputType = options.inputType || 'auto';\r\n let treatAsSSML = false;\r\n\r\n if (inputType === 'ssml') {\r\n treatAsSSML = true;\r\n } else if (inputType === 'text') {\r\n treatAsSSML = false;\r\n } else { // 'auto'\r\n const detection = this.detectSSML(content);\r\n treatAsSSML = detection.isSSML;\r\n\r\n if (detection.isSSML) {\r\n console.log('\u2192 Detected SSML input');\r\n if (!detection.isValid) {\r\n console.warn('\u26A0 SSML validation warnings:', detection.errors);\r\n }\r\n } else {\r\n console.log('\u2192 Detected plain text input');\r\n }\r\n }\r\n\r\n if (treatAsSSML) {\r\n let ssml = content.trim();\r\n\r\n if (!ssml.includes('xmlns=')) {\r\n ssml = ssml.replace(\r\n /<speak([^>]*)>/i,\r\n '<speak$1 xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"https://www.w3.org/2001/mstts\">'\r\n );\r\n }\r\n\r\n if (!/<voice\\b[^>]*>/i.test(ssml) && voice) {\r\n ssml = ssml.replace(\r\n /(<speak[^>]*>)([\\s\\S]*?)(<\\/speak>)/i,\r\n `$1<voice name=\"${voice}\">$2</voice>$3`\r\n );\r\n }\r\n\r\n return ssml;\r\n }\r\n\r\n const pitch = this.validatePitch(options.pitch ?? 0);\r\n const rate = this.validateRate(options.rate ?? 0);\r\n const volume = this.validateVolume(options.volume ?? 0);\r\n const escapedText = this.escapeXML(content);\r\n\r\n return `<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"https://www.w3.org/2001/mstts\" xml:lang=\"en-US\">\r\n <voice name=\"${voice}\">\r\n <prosody pitch=\"${pitch}\" rate=\"${rate}\" volume=\"${volume}\">\r\n ${escapedText}\r\n </prosody>\r\n </voice>\r\n </speak>`;\r\n }\r\n\r\n private nowRFC1123(): string {\r\n return new Date().toUTCString();\r\n }\r\n\r\n private parseRFC1123(rfcStr: string): Date {\r\n return new Date(rfcStr);\r\n }\r\n\r\n private buildTTSConfigMessage(): string {\r\n const timestamp = this.nowRFC1123();\r\n return `X-Timestamp:${timestamp}\\r\\nContent-Type:application/json; charset=utf-8\\r\\nPath:speech.config\\r\\n\\r\\n` +\r\n `{\"context\":{\"synthesis\":{\"audio\":{\"metadataoptions\":{\"sentenceBoundaryEnabled\":false,\"wordBoundaryEnabled\":true},\"outputFormat\":\"audio-24khz-48kbitrate-mono-mp3\"}}}}`;\r\n }\r\n\r\n async synthesize(text: string, voice: string = 'en-US-JennyNeural', options: SynthesisOptions = {}): Promise<void> {\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n\r\n return new Promise((resolve, reject) => {\r\n this.audio_stream = [];\r\n const reqId = this.generateUUID();\r\n const url = `${Constants.WSS_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}&ConnectionId=${reqId}`;\r\n \r\n console.log('WebSocket URL:', url);\r\n this.ws = new WebSocket(url);\r\n\r\n const SSML_text = this.getSSML(text, voice, options);\r\n \r\n let timedOut = false;\r\n let inactivityTimeout: number;\r\n \r\n const resetInactivityTimeout = () => {\r\n clearTimeout(inactivityTimeout);\r\n inactivityTimeout = window.setTimeout(() => {\r\n timedOut = true;\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n reject(new Error(\"WebSocket inactivity timeout - no response from server\"));\r\n }, 30000); // 30 seconds of inactivity\r\n };\r\n\r\n this.ws.onopen = () => {\r\n resetInactivityTimeout(); // start the inactivity timeout\r\n const message = this.buildTTSConfigMessage();\r\n this.ws!.send(message);\r\n const timestamp = this.nowRFC1123();\r\n const speechMessage = `X-RequestId:${reqId}\\r\\nContent-Type:application/ssml+xml\\r\\nX-Timestamp:${timestamp}\\r\\nPath:ssml\\r\\n\\r\\n${SSML_text}`;\r\n this.ws!.send(speechMessage);\r\n };\r\n\r\n this.ws.onmessage = (event) => {\r\n resetInactivityTimeout(); // restart inactivity timeout \r\n if (typeof event.data === 'string') {\r\n if (event.data.includes('Path:turn.end')) {\r\n this.ws?.close();\r\n }\r\n } else {\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const arrayBuffer = reader.result as ArrayBuffer;\r\n const uint8Array = new Uint8Array(arrayBuffer);\r\n this.processAudioData(uint8Array);\r\n };\r\n reader.readAsArrayBuffer(event.data);\r\n }\r\n };\r\n\r\n this.ws.onerror = (err: any) => {\r\n clearTimeout(inactivityTimeout);\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n reject(new Error('WebSocket error'));\r\n };\r\n\r\n this.ws.onclose = () => {\r\n clearTimeout(inactivityTimeout);\r\n if (!timedOut) {\r\n resolve();\r\n }\r\n };\r\n });\r\n }\r\n\r\n async *synthesizeStream(text: string, voice: string = 'en-US-JennyNeural', options: SynthesisOptions = {}): AsyncGenerator<Uint8Array, void, unknown> {\r\n this.audio_stream = [];\r\n\r\n const reqId = this.generateUUID();\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n\r\n const url = `${Constants.WSS_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}&ConnectionId=${reqId}`;\r\n\r\n this.ws = new WebSocket(url);\r\n\r\n const SSML_text = this.getSSML(text, voice, options);\r\n\r\n const queue: Uint8Array[] = [];\r\n let done = false;\r\n let error: Error | null = null;\r\n let notify: (() => void) | null = null;\r\n\r\n const push = (chunk: Uint8Array) => {\r\n queue.push(chunk);\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n let timedOut = false;\r\n let inactivityTimeout: number;\r\n \r\n const resetInactivityTimeout = () => {\r\n clearTimeout(inactivityTimeout);\r\n inactivityTimeout = window.setTimeout(() => {\r\n timedOut = true;\r\n error = new Error(\"WebSocket inactivity timeout - no response from server\");\r\n done = true;\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n }, 30000); // 30 seconds of inactivity\r\n };\r\n\r\n this.ws.onopen = () => {\r\n resetInactivityTimeout(); // start the inactivity timeout\r\n const message = this.buildTTSConfigMessage();\r\n this.ws!.send(message);\r\n\r\n const timestamp = this.nowRFC1123();\r\n const speechMessage = `X-RequestId:${reqId}\\r\\nContent-Type:application/ssml+xml\\r\\nX-Timestamp:${timestamp}\\r\\nPath:ssml\\r\\n\\r\\n${SSML_text}`;\r\n this.ws!.send(speechMessage);\r\n };\r\n\r\n this.ws.onmessage = (event) => {\r\n resetInactivityTimeout(); // restart inactivity timeout\r\n if (typeof event.data === 'string') {\r\n if (event.data.includes('Path:turn.end')) {\r\n this.ws?.close();\r\n }\r\n } else {\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const arrayBuffer = reader.result as ArrayBuffer;\r\n const uint8Array = new Uint8Array(arrayBuffer);\r\n \r\n const needle = new TextEncoder().encode(\"Path:audio\\r\\n\");\r\n const audioStartIndex = this.indexOf(uint8Array, needle);\r\n\r\n if (audioStartIndex !== -1) {\r\n const audioChunk = uint8Array.slice(audioStartIndex + needle.length);\r\n this.audio_stream.push(audioChunk);\r\n push(audioChunk);\r\n }\r\n };\r\n reader.readAsArrayBuffer(event.data);\r\n }\r\n };\r\n\r\n this.ws.onerror = (err: any) => {\r\n clearTimeout(inactivityTimeout);\r\n error = new Error('WebSocket error');\r\n done = true;\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n this.ws.onclose = () => {\r\n clearTimeout(inactivityTimeout);\r\n done = true;\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n while (!done || queue.length > 0) {\r\n if (queue.length === 0) {\r\n await new Promise<void>(resolve => (notify = resolve));\r\n continue;\r\n }\r\n const chunk = queue.shift();\r\n if (chunk) {\r\n yield chunk;\r\n }\r\n }\r\n\r\n if (error) {\r\n throw error;\r\n }\r\n }\r\n\r\n private processAudioData(buffer: Uint8Array): void {\r\n const needle = new TextEncoder().encode(\"Path:audio\\r\\n\");\r\n const audioStartIndex = this.indexOf(buffer, needle);\r\n\r\n if (audioStartIndex !== -1) {\r\n const audioChunk = buffer.slice(audioStartIndex + needle.length);\r\n this.audio_stream.push(audioChunk);\r\n }\r\n }\r\n\r\n private indexOf(arr: Uint8Array, subarr: Uint8Array): number {\r\n for (let i = 0; i <= arr.length - subarr.length; i++) {\r\n let match = true;\r\n for (let j = 0; j < subarr.length; j++) {\r\n if (arr[i + j] !== subarr[j]) {\r\n match = false;\r\n break;\r\n }\r\n }\r\n if (match) return i;\r\n }\r\n return -1;\r\n }\r\n\r\n private async generateSecMsGec(trustedClientToken: string): Promise<string> {\r\n const now = this.nowRFC1123();\r\n const fixedDate = this.parseRFC1123(now);\r\n const ticks = Math.floor(fixedDate.getTime() / 1000) + 11644473600;\r\n const rounded = ticks - (ticks % 300);\r\n const windowsTicks = rounded * 10_000_000;\r\n\r\n const encoder = new TextEncoder();\r\n const data = encoder.encode(`${windowsTicks}${trustedClientToken}`);\r\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\r\n\r\n return Array.from(new Uint8Array(hashBuffer))\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .toUpperCase();\r\n }\r\n\r\n getAudioData(): Uint8Array {\r\n if (this.audio_stream.length === 0) {\r\n throw new Error(\"No audio data available\");\r\n }\r\n const totalLength = this.audio_stream.reduce((acc, chunk) => acc + chunk.length, 0);\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const chunk of this.audio_stream) {\r\n result.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n return result;\r\n }\r\n}\r\n", "export const Constants = {\r\n TRUSTED_CLIENT_TOKEN: '6A5AA1D4EAFF4E9FB37E23D68491D6F4',\r\n BASE_URL: 'https://api.msedgeservices.com/tts/cognitiveservices',\r\n WSS_URL: 'wss://api.msedgeservices.com/tts/cognitiveservices/websocket/v1',\r\n VOICES_URL: 'https://api.msedgeservices.com/tts/cognitiveservices/voices/list',\r\n\r\n CHROMIUM_FULL_VERSION: '142.0.3595.0',\r\n CHROMIUM_MAJOR_VERSION: '142',\r\n VERSION_MS_GEC: '1-142.0.3595',\r\n\r\n token32() {\r\n const bytes = new Uint8Array(16);\r\n crypto.getRandomValues(bytes);\r\n\r\n return Array.from(bytes)\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .toUpperCase();\r\n },\r\n\r\n getBaseHeaders() {\r\n return {\r\n 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\r\n 'Accept-Encoding': 'gzip, deflate, br, zstd',\r\n 'Accept-Language': 'es,es-ES;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,es-CO;q=0.5,es-MX;q=0.4',\r\n 'Cookie': 'MUID=' + this.token32()\r\n };\r\n },\r\n\r\n WSS_HEADERS: {\r\n 'Pragma': 'no-cache',\r\n 'Cache-Control': 'no-cache',\r\n 'Origin': 'chrome-extension://jdiccldimpdaibmpdkjnbmckianbfold',\r\n 'Sec-WebSocket-Protocol': 'synthesize',\r\n 'Sec-WebSocket-Version': '13',\r\n 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0'\r\n },\r\n\r\n VOICE_HEADERS: {\r\n 'Sec-CH-UA': '\" Not;A Brand\";v=\"99\", \"Microsoft Edge\";v=\"140\", \"Chromium\";v=\"140\"',\r\n 'Sec-CH-UA-Mobile': '?0',\r\n 'Accept': '*/*',\r\n 'Sec-Fetch-Site': 'none',\r\n 'Sec-Fetch-Mode': 'cors',\r\n 'Sec-Fetch-Dest': 'empty'\r\n },\r\n \r\n // https://learn.microsoft.com/en-us/azure/ai-services/speech-service/rest-text-to-speech?tabs=nonstreaming\r\n OUTPUT_FORMAT: {\r\n // Streaming \r\n AMR_WB_16000HZ: 'amr-wb-16000hz',\r\n AUDIO_16KHZ_16BIT_32KBPS_MONO_OPUS: 'audio-16khz-16bit-32kbps-mono-opus',\r\n AUDIO_16KHZ_32KBITRATE_MONO_MP3: 'audio-16khz-32kbitrate-mono-mp3',\r\n AUDIO_16KHZ_64KBITRATE_MONO_MP3: 'audio-16khz-64kbitrate-mono-mp3',\r\n AUDIO_16KHZ_128KBITRATE_MONO_MP3: 'audio-16khz-128kbitrate-mono-mp3',\r\n AUDIO_24KHZ_16BIT_24KBPS_MONO_OPUS: 'audio-24khz-16bit-24kbps-mono-opus',\r\n AUDIO_24KHZ_16BIT_48KBPS_MONO_OPUS: 'audio-24khz-16bit-48kbps-mono-opus',\r\n AUDIO_24KHZ_48KBITRATE_MONO_MP3: 'audio-24khz-48kbitrate-mono-mp3',\r\n AUDIO_24KHZ_96KBITRATE_MONO_MP3: 'audio-24khz-96kbitrate-mono-mp3',\r\n AUDIO_24KHZ_160KBITRATE_MONO_MP3: 'audio-24khz-160kbitrate-mono-mp3',\r\n AUDIO_48KHZ_96KBITRATE_MONO_MP3: 'audio-48khz-96kbitrate-mono-mp3',\r\n AUDIO_48KHZ_192KBITRATE_MONO_MP3: 'audio-48khz-192kbitrate-mono-mp3',\r\n G722_16KHZ_64KBPS: 'g722-16khz-64kbps',\r\n OGG_16KHZ_16BIT_MONO_OPUS: 'ogg-16khz-16bit-mono-opus',\r\n OGG_24KHZ_16BIT_MONO_OPUS: 'ogg-24khz-16bit-mono-opus',\r\n OGG_48KHZ_16BIT_MONO_OPUS: 'ogg-48khz-16bit-mono-opus',\r\n RAW_8KHZ_8BIT_MONO_ALAW: 'raw-8khz-8bit-mono-alaw',\r\n RAW_8KHZ_8BIT_MONO_MULAW: 'raw-8khz-8bit-mono-mulaw',\r\n RAW_8KHZ_16BIT_MONO_PCM: 'raw-8khz-16bit-mono-pcm',\r\n RAW_16KHZ_16BIT_MONO_PCM: 'raw-16khz-16bit-mono-pcm',\r\n RAW_16KHZ_16BIT_MONO_TRUESILK: 'raw-16khz-16bit-mono-truesilk',\r\n RAW_22050HZ_16BIT_MONO_PCM: 'raw-22050hz-16bit-mono-pcm',\r\n RAW_24KHZ_16BIT_MONO_PCM: 'raw-24khz-16bit-mono-pcm',\r\n RAW_24KHZ_16BIT_MONO_TRUESILK: 'raw-24khz-16bit-mono-truesilk',\r\n RAW_44100HZ_16BIT_MONO_PCM: 'raw-44100hz-16bit-mono-pcm',\r\n RAW_48KHZ_16BIT_MONO_PCM: 'raw-48khz-16bit-mono-pcm',\r\n WEBM_16KHZ_16BIT_MONO_OPUS: 'webm-16khz-16bit-mono-opus',\r\n WEBM_24KHZ_16BIT_24KBPS_MONO_OPUS: 'webm-24khz-16bit-24kbps-mono-opus',\r\n WEBM_24KHZ_16BIT_MONO_OPUS: 'webm-24khz-16bit-mono-opus',\r\n // NonStreaming \r\n RIFF_8KHZ_8BIT_MONO_ALAW: 'riff-8khz-8bit-mono-alaw',\r\n RIFF_8KHZ_8BIT_MONO_MULAW: 'riff-8khz-8bit-mono-mulaw',\r\n RIFF_8KHZ_16BIT_MONO_PCM: 'riff-8khz-16bit-mono-pcm',\r\n RIFF_22050HZ_16BIT_MONO_PCM: 'riff-22050hz-16bit-mono-pcm',\r\n RIFF_24KHZ_16BIT_MONO_PCM: 'riff-24khz-16bit-mono-pcm',\r\n RIFF_44100HZ_16BIT_MONO_PCM: 'riff-44100hz-16bit-mono-pcm',\r\n RIFF_48KHZ_16BIT_MONO_PCM: 'riff-48khz-16bit-mono-pcm'\r\n }\r\n\r\n\r\n};\r\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,25 +1,25 @@
1
- "use strict";var EdgeTTSModule=(()=>{var w=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var U=(o,e,t)=>e in o?w(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var k=(o,e)=>{for(var t in e)w(o,t,{get:e[t],enumerable:!0})},_=(o,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of L(e))!A.call(o,s)&&s!==t&&w(o,s,{get:()=>e[s],enumerable:!(n=v(e,s))||n.enumerable});return o};var b=o=>_(w({},"__esModule",{value:!0}),o);var y=(o,e,t)=>U(o,typeof e!="symbol"?e+"":e,t);var R={};k(R,{EdgeTTS:()=>E});var c={TRUSTED_CLIENT_TOKEN:"6A5AA1D4EAFF4E9FB37E23D68491D6F4",BASE_URL:"https://api.msedgeservices.com/tts/cognitiveservices",WSS_URL:"wss://api.msedgeservices.com/tts/cognitiveservices/websocket/v1",VOICES_URL:"https://api.msedgeservices.com/tts/cognitiveservices/voices/list",CHROMIUM_FULL_VERSION:"142.0.3595.0",CHROMIUM_MAJOR_VERSION:"142",VERSION_MS_GEC:"1-142.0.3595",token32(){let o=new Uint8Array(16);return crypto.getRandomValues(o),Array.from(o).map(e=>e.toString(16).padStart(2,"0")).join("").toUpperCase()},getBaseHeaders(){return{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0","Accept-Encoding":"gzip, deflate, br, zstd","Accept-Language":"es,es-ES;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,es-CO;q=0.5,es-MX;q=0.4",Cookie:"MUID="+this.token32()}},WSS_HEADERS:{Pragma:"no-cache","Cache-Control":"no-cache",Origin:"chrome-extension://jdiccldimpdaibmpdkjnbmckianbfold","Sec-WebSocket-Protocol":"synthesize","Sec-WebSocket-Version":"13","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0"},VOICE_HEADERS:{"Sec-CH-UA":'" Not;A Brand";v="99", "Microsoft Edge";v="140", "Chromium";v="140"',"Sec-CH-UA-Mobile":"?0",Accept:"*/*","Sec-Fetch-Site":"none","Sec-Fetch-Mode":"cors","Sec-Fetch-Dest":"empty"}};var E=class{constructor(){y(this,"audio_stream",[]);y(this,"ws")}async getVoices(){let e=await this.generateSecMsGec(c.TRUSTED_CLIENT_TOKEN);return(await(await fetch(`${c.VOICES_URL}?Ocp-Apim-Subscription-Key=${c.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${e}&Sec-MS-GEC-Version=${c.VERSION_MS_GEC}`,{headers:c.getBaseHeaders()})).json()).map(s=>(s.FriendlyName=s.FriendlyName||s.LocalName,delete s.SampleRateHertz,delete s.Status,s))}async getVoicesByLanguage(e){return(await this.getVoices()).filter(n=>n.Locale.startsWith(e))}async getVoicesByGender(e){return(await this.getVoices()).filter(n=>n.Gender===e)}generateUUID(){return"xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}validatePitch(e){return typeof e=="number"?e>=0?`+${e}Hz`:`${e}Hz`:e}validateRate(e){let t;return typeof e=="string"?t=parseFloat(e.replace("%","")):t=e,t>=0?`+${t}%`:`${t}%`}validateVolume(e){let t;return typeof e=="string"?t=parseInt(e.replace("%",""),10):t=e,`${t}%`}detectSSML(e){let t=e.trim();if(!/^<\?xml|^<speak/i.test(t))return{isValid:!0,isSSML:!1};let s=[],i=/<speak\b[^>]*>[\s\S]*<\/speak>/i.test(t),d=/<voice\b[^>]*>[\s\S]*<\/voice>/i.test(t);if(!i)throw new Error("Invalid SSML: Missing <speak> tag");if(!d)throw new Error("Invalid SSML: Missing <voice> tag");if(!/xmlns="http:\/\/www\.w3\.org\/2001\/10\/synthesis"/i.test(t)&&i)throw new Error("Invalid SSML: Missing or incorrect namespace declaration");return{isValid:s.length===0,isSSML:i||d,errors:s.length>0?s:void 0}}escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}getSSML(e,t,n={}){let s=n.inputType||"auto",i=!1;if(s==="ssml")i=!0;else if(s==="text")i=!1;else{let r=this.detectSSML(e);i=r.isSSML,r.isSSML?(console.log("\u2192 Detected SSML input"),r.isValid||console.warn("\u26A0 SSML validation warnings:",r.errors)):console.log("\u2192 Detected plain text input")}if(i){let r=e.trim();return r.includes("xmlns=")||(r=r.replace(/<speak([^>]*)>/i,'<speak$1 xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts">')),!/<voice\b[^>]*>/i.test(r)&&t&&(r=r.replace(/(<speak[^>]*>)([\s\S]*?)(<\/speak>)/i,`$1<voice name="${t}">$2</voice>$3`)),r}let d=this.validatePitch(n.pitch??0),p=this.validateRate(n.rate??0),u=this.validateVolume(n.volume??0),S=this.escapeXML(e);return`<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" xml:lang="en-US">
1
+ "use strict";var EdgeTTSModule=(()=>{var M=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var N=(a,e,t)=>e in a?M(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var R=(a,e)=>{for(var t in e)M(a,t,{get:e[t],enumerable:!0})},C=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of E(e))!U.call(a,s)&&s!==t&&M(a,s,{get:()=>e[s],enumerable:!(i=y(e,s))||i.enumerable});return a};var x=a=>C(M({},"__esModule",{value:!0}),a);var T=(a,e,t)=>N(a,typeof e!="symbol"?e+"":e,t);var v={};R(v,{EdgeTTS:()=>f});var c={TRUSTED_CLIENT_TOKEN:"6A5AA1D4EAFF4E9FB37E23D68491D6F4",BASE_URL:"https://api.msedgeservices.com/tts/cognitiveservices",WSS_URL:"wss://api.msedgeservices.com/tts/cognitiveservices/websocket/v1",VOICES_URL:"https://api.msedgeservices.com/tts/cognitiveservices/voices/list",CHROMIUM_FULL_VERSION:"142.0.3595.0",CHROMIUM_MAJOR_VERSION:"142",VERSION_MS_GEC:"1-142.0.3595",token32(){let a=new Uint8Array(16);return crypto.getRandomValues(a),Array.from(a).map(e=>e.toString(16).padStart(2,"0")).join("").toUpperCase()},getBaseHeaders(){return{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0","Accept-Encoding":"gzip, deflate, br, zstd","Accept-Language":"es,es-ES;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,es-CO;q=0.5,es-MX;q=0.4",Cookie:"MUID="+this.token32()}},WSS_HEADERS:{Pragma:"no-cache","Cache-Control":"no-cache",Origin:"chrome-extension://jdiccldimpdaibmpdkjnbmckianbfold","Sec-WebSocket-Protocol":"synthesize","Sec-WebSocket-Version":"13","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0"},VOICE_HEADERS:{"Sec-CH-UA":'" Not;A Brand";v="99", "Microsoft Edge";v="140", "Chromium";v="140"',"Sec-CH-UA-Mobile":"?0",Accept:"*/*","Sec-Fetch-Site":"none","Sec-Fetch-Mode":"cors","Sec-Fetch-Dest":"empty"},OUTPUT_FORMAT:{AMR_WB_16000HZ:"amr-wb-16000hz",AUDIO_16KHZ_16BIT_32KBPS_MONO_OPUS:"audio-16khz-16bit-32kbps-mono-opus",AUDIO_16KHZ_32KBITRATE_MONO_MP3:"audio-16khz-32kbitrate-mono-mp3",AUDIO_16KHZ_64KBITRATE_MONO_MP3:"audio-16khz-64kbitrate-mono-mp3",AUDIO_16KHZ_128KBITRATE_MONO_MP3:"audio-16khz-128kbitrate-mono-mp3",AUDIO_24KHZ_16BIT_24KBPS_MONO_OPUS:"audio-24khz-16bit-24kbps-mono-opus",AUDIO_24KHZ_16BIT_48KBPS_MONO_OPUS:"audio-24khz-16bit-48kbps-mono-opus",AUDIO_24KHZ_48KBITRATE_MONO_MP3:"audio-24khz-48kbitrate-mono-mp3",AUDIO_24KHZ_96KBITRATE_MONO_MP3:"audio-24khz-96kbitrate-mono-mp3",AUDIO_24KHZ_160KBITRATE_MONO_MP3:"audio-24khz-160kbitrate-mono-mp3",AUDIO_48KHZ_96KBITRATE_MONO_MP3:"audio-48khz-96kbitrate-mono-mp3",AUDIO_48KHZ_192KBITRATE_MONO_MP3:"audio-48khz-192kbitrate-mono-mp3",G722_16KHZ_64KBPS:"g722-16khz-64kbps",OGG_16KHZ_16BIT_MONO_OPUS:"ogg-16khz-16bit-mono-opus",OGG_24KHZ_16BIT_MONO_OPUS:"ogg-24khz-16bit-mono-opus",OGG_48KHZ_16BIT_MONO_OPUS:"ogg-48khz-16bit-mono-opus",RAW_8KHZ_8BIT_MONO_ALAW:"raw-8khz-8bit-mono-alaw",RAW_8KHZ_8BIT_MONO_MULAW:"raw-8khz-8bit-mono-mulaw",RAW_8KHZ_16BIT_MONO_PCM:"raw-8khz-16bit-mono-pcm",RAW_16KHZ_16BIT_MONO_PCM:"raw-16khz-16bit-mono-pcm",RAW_16KHZ_16BIT_MONO_TRUESILK:"raw-16khz-16bit-mono-truesilk",RAW_22050HZ_16BIT_MONO_PCM:"raw-22050hz-16bit-mono-pcm",RAW_24KHZ_16BIT_MONO_PCM:"raw-24khz-16bit-mono-pcm",RAW_24KHZ_16BIT_MONO_TRUESILK:"raw-24khz-16bit-mono-truesilk",RAW_44100HZ_16BIT_MONO_PCM:"raw-44100hz-16bit-mono-pcm",RAW_48KHZ_16BIT_MONO_PCM:"raw-48khz-16bit-mono-pcm",WEBM_16KHZ_16BIT_MONO_OPUS:"webm-16khz-16bit-mono-opus",WEBM_24KHZ_16BIT_24KBPS_MONO_OPUS:"webm-24khz-16bit-24kbps-mono-opus",WEBM_24KHZ_16BIT_MONO_OPUS:"webm-24khz-16bit-mono-opus",RIFF_8KHZ_8BIT_MONO_ALAW:"riff-8khz-8bit-mono-alaw",RIFF_8KHZ_8BIT_MONO_MULAW:"riff-8khz-8bit-mono-mulaw",RIFF_8KHZ_16BIT_MONO_PCM:"riff-8khz-16bit-mono-pcm",RIFF_22050HZ_16BIT_MONO_PCM:"riff-22050hz-16bit-mono-pcm",RIFF_24KHZ_16BIT_MONO_PCM:"riff-24khz-16bit-mono-pcm",RIFF_44100HZ_16BIT_MONO_PCM:"riff-44100hz-16bit-mono-pcm",RIFF_48KHZ_16BIT_MONO_PCM:"riff-48khz-16bit-mono-pcm"}};var f=class{constructor(){T(this,"audio_stream",[]);T(this,"ws")}async getVoices(){let e=await this.generateSecMsGec(c.TRUSTED_CLIENT_TOKEN);return(await(await fetch(`${c.VOICES_URL}?Ocp-Apim-Subscription-Key=${c.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${e}&Sec-MS-GEC-Version=${c.VERSION_MS_GEC}`,{headers:c.getBaseHeaders()})).json()).map(s=>(s.FriendlyName=s.FriendlyName||s.LocalName,delete s.SampleRateHertz,delete s.Status,s))}async getVoicesByLanguage(e){return(await this.getVoices()).filter(i=>i.Locale.startsWith(e))}async getVoicesByGender(e){return(await this.getVoices()).filter(i=>i.Gender===e)}generateUUID(){return"xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}validatePitch(e){return typeof e=="number"?e>=0?`+${e}Hz`:`${e}Hz`:e}validateRate(e){let t;return typeof e=="string"?t=parseFloat(e.replace("%","")):t=e,t>=0?`+${t}%`:`${t}%`}validateVolume(e){let t;return typeof e=="string"?t=parseInt(e.replace("%",""),10):t=e,`${t}%`}detectSSML(e){let t=e.trim();if(!/^<\?xml|^<speak/i.test(t))return{isValid:!0,isSSML:!1};let s=[],r=/<speak\b[^>]*>[\s\S]*<\/speak>/i.test(t),m=/<voice\b[^>]*>[\s\S]*<\/voice>/i.test(t);if(!r)throw new Error("Invalid SSML: Missing <speak> tag");if(!m)throw new Error("Invalid SSML: Missing <voice> tag");if(!/xmlns="http:\/\/www\.w3\.org\/2001\/10\/synthesis"/i.test(t)&&r)throw new Error("Invalid SSML: Missing or incorrect namespace declaration");return{isValid:s.length===0,isSSML:r||m,errors:s.length>0?s:void 0}}escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}getSSML(e,t,i={}){let s=i.inputType||"auto",r=!1;if(s==="ssml")r=!0;else if(s==="text")r=!1;else{let n=this.detectSSML(e);r=n.isSSML,n.isSSML?(console.log("\u2192 Detected SSML input"),n.isValid||console.warn("\u26A0 SSML validation warnings:",n.errors)):console.log("\u2192 Detected plain text input")}if(r){let n=e.trim();return n.includes("xmlns=")||(n=n.replace(/<speak([^>]*)>/i,'<speak$1 xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts">')),!/<voice\b[^>]*>/i.test(n)&&t&&(n=n.replace(/(<speak[^>]*>)([\s\S]*?)(<\/speak>)/i,`$1<voice name="${t}">$2</voice>$3`)),n}let m=this.validatePitch(i.pitch??0),h=this.validateRate(i.rate??0),_=this.validateVolume(i.volume??0),u=this.escapeXML(e);return`<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" xml:lang="en-US">
2
2
  <voice name="${t}">
3
- <prosody pitch="${d}" rate="${p}" volume="${u}">
4
- ${S}
3
+ <prosody pitch="${m}" rate="${h}" volume="${_}">
4
+ ${u}
5
5
  </prosody>
6
6
  </voice>
7
7
  </speak>`}nowRFC1123(){return new Date().toUTCString()}parseRFC1123(e){return new Date(e)}buildTTSConfigMessage(){return`X-Timestamp:${this.nowRFC1123()}\r
8
8
  Content-Type:application/json; charset=utf-8\r
9
9
  Path:speech.config\r
10
10
  \r
11
- {"context":{"synthesis":{"audio":{"metadataoptions":{"sentenceBoundaryEnabled":false,"wordBoundaryEnabled":true},"outputFormat":"audio-24khz-48kbitrate-mono-mp3"}}}}`}async synthesize(e,t="en-US-JennyNeural",n={}){let s=await this.generateSecMsGec(c.TRUSTED_CLIENT_TOKEN);return new Promise((i,d)=>{this.audio_stream=[];let p=this.generateUUID(),u=`${c.WSS_URL}?Ocp-Apim-Subscription-Key=${c.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${s}&Sec-MS-GEC-Version=${c.VERSION_MS_GEC}&ConnectionId=${p}`;console.log("WebSocket URL:",u),this.ws=new WebSocket(u);let S=this.getSSML(e,t,n),r=setTimeout(()=>{this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.close(),d(new Error("Synthesis timeout"))},3e4);this.ws.onopen=()=>{let a=this.buildTTSConfigMessage();this.ws.send(a);let h=this.nowRFC1123(),m=`X-RequestId:${p}\r
11
+ {"context":{"synthesis":{"audio":{"metadataoptions":{"sentenceBoundaryEnabled":false,"wordBoundaryEnabled":true},"outputFormat":"audio-24khz-48kbitrate-mono-mp3"}}}}`}async synthesize(e,t="en-US-JennyNeural",i={}){let s=await this.generateSecMsGec(c.TRUSTED_CLIENT_TOKEN);return new Promise((r,m)=>{this.audio_stream=[];let h=this.generateUUID(),_=`${c.WSS_URL}?Ocp-Apim-Subscription-Key=${c.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${s}&Sec-MS-GEC-Version=${c.VERSION_MS_GEC}&ConnectionId=${h}`;console.log("WebSocket URL:",_),this.ws=new WebSocket(_);let u=this.getSSML(e,t,i),n=!1,o,O=()=>{clearTimeout(o),o=window.setTimeout(()=>{n=!0,this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.close(),m(new Error("WebSocket inactivity timeout - no response from server"))},3e4)};this.ws.onopen=()=>{O();let d=this.buildTTSConfigMessage();this.ws.send(d);let p=this.nowRFC1123(),g=`X-RequestId:${h}\r
12
12
  Content-Type:application/ssml+xml\r
13
- X-Timestamp:${h}\r
13
+ X-Timestamp:${p}\r
14
14
  Path:ssml\r
15
15
  \r
16
- ${S}`;this.ws.send(m)},this.ws.onmessage=a=>{if(typeof a.data=="string")a.data.includes("Path:turn.end")&&this.ws?.close();else{let h=new FileReader;h.onload=()=>{let m=h.result,l=new Uint8Array(m);this.processAudioData(l)},h.readAsArrayBuffer(a.data)}},this.ws.onerror=a=>{clearTimeout(r),this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.close(),d(new Error("WebSocket error"))},this.ws.onclose=()=>{clearTimeout(r),i()}})}async*synthesizeStream(e,t="en-US-JennyNeural",n={}){this.audio_stream=[];let s=this.generateUUID(),i=await this.generateSecMsGec(c.TRUSTED_CLIENT_TOKEN),d=`${c.WSS_URL}?Ocp-Apim-Subscription-Key=${c.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${i}&Sec-MS-GEC-Version=${c.VERSION_MS_GEC}&ConnectionId=${s}`;this.ws=new WebSocket(d);let p=this.getSSML(e,t,n),u=[],S=!1,r=null,a=null,h=l=>{u.push(l),a&&(a(),a=null)},m=setTimeout(()=>{this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.close()},3e4);for(this.ws.onopen=()=>{let l=this.buildTTSConfigMessage();this.ws.send(l);let g=this.nowRFC1123(),f=`X-RequestId:${s}\r
16
+ ${u}`;this.ws.send(g)},this.ws.onmessage=d=>{if(O(),typeof d.data=="string")d.data.includes("Path:turn.end")&&this.ws?.close();else{let p=new FileReader;p.onload=()=>{let g=p.result,l=new Uint8Array(g);this.processAudioData(l)},p.readAsArrayBuffer(d.data)}},this.ws.onerror=d=>{clearTimeout(o),this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.close(),m(new Error("WebSocket error"))},this.ws.onclose=()=>{clearTimeout(o),n||r()}})}async*synthesizeStream(e,t="en-US-JennyNeural",i={}){this.audio_stream=[];let s=this.generateUUID(),r=await this.generateSecMsGec(c.TRUSTED_CLIENT_TOKEN),m=`${c.WSS_URL}?Ocp-Apim-Subscription-Key=${c.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${r}&Sec-MS-GEC-Version=${c.VERSION_MS_GEC}&ConnectionId=${s}`;this.ws=new WebSocket(m);let h=this.getSSML(e,t,i),_=[],u=!1,n=null,o=null,O=l=>{_.push(l),o&&(o(),o=null)},d=!1,p,g=()=>{clearTimeout(p),p=window.setTimeout(()=>{d=!0,n=new Error("WebSocket inactivity timeout - no response from server"),u=!0,this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.close(),o&&(o(),o=null)},3e4)};for(this.ws.onopen=()=>{g();let l=this.buildTTSConfigMessage();this.ws.send(l);let S=this.nowRFC1123(),w=`X-RequestId:${s}\r
17
17
  Content-Type:application/ssml+xml\r
18
- X-Timestamp:${g}\r
18
+ X-Timestamp:${S}\r
19
19
  Path:ssml\r
20
20
  \r
21
- ${p}`;this.ws.send(f)},this.ws.onmessage=l=>{if(typeof l.data=="string")l.data.includes("Path:turn.end")&&this.ws?.close();else{let g=new FileReader;g.onload=()=>{let f=g.result,x=new Uint8Array(f),M=new TextEncoder().encode(`Path:audio\r
22
- `),C=this.indexOf(x,M);if(C!==-1){let T=x.slice(C+M.length);this.audio_stream.push(T),h(T)}},g.readAsArrayBuffer(l.data)}},this.ws.onerror=l=>{r=new Error("WebSocket error"),S=!0,a&&(a(),a=null)},this.ws.onclose=()=>{clearTimeout(m),S=!0,a&&(a(),a=null)};!S||u.length>0;){if(u.length===0){await new Promise(g=>a=g);continue}let l=u.shift();l&&(yield l)}if(r)throw r}processAudioData(e){let t=new TextEncoder().encode(`Path:audio\r
23
- `),n=this.indexOf(e,t);if(n!==-1){let s=e.slice(n+t.length);this.audio_stream.push(s)}}indexOf(e,t){for(let n=0;n<=e.length-t.length;n++){let s=!0;for(let i=0;i<t.length;i++)if(e[n+i]!==t[i]){s=!1;break}if(s)return n}return-1}async generateSecMsGec(e){let t=this.nowRFC1123(),n=this.parseRFC1123(t),s=Math.floor(n.getTime()/1e3)+11644473600,d=(s-s%300)*1e7,u=new TextEncoder().encode(`${d}${e}`),S=await crypto.subtle.digest("SHA-256",u);return Array.from(new Uint8Array(S)).map(r=>r.toString(16).padStart(2,"0")).join("").toUpperCase()}getAudioData(){if(this.audio_stream.length===0)throw new Error("No audio data available");let e=this.audio_stream.reduce((s,i)=>s+i.length,0),t=new Uint8Array(e),n=0;for(let s of this.audio_stream)t.set(s,n),n+=s.length;return t}};return b(R);})();
21
+ ${h}`;this.ws.send(w)},this.ws.onmessage=l=>{if(g(),typeof l.data=="string")l.data.includes("Path:turn.end")&&this.ws?.close();else{let S=new FileReader;S.onload=()=>{let w=S.result,k=new Uint8Array(w),b=new TextEncoder().encode(`Path:audio\r
22
+ `),I=this.indexOf(k,b);if(I!==-1){let A=k.slice(I+b.length);this.audio_stream.push(A),O(A)}},S.readAsArrayBuffer(l.data)}},this.ws.onerror=l=>{clearTimeout(p),n=new Error("WebSocket error"),u=!0,o&&(o(),o=null)},this.ws.onclose=()=>{clearTimeout(p),u=!0,o&&(o(),o=null)};!u||_.length>0;){if(_.length===0){await new Promise(S=>o=S);continue}let l=_.shift();l&&(yield l)}if(n)throw n}processAudioData(e){let t=new TextEncoder().encode(`Path:audio\r
23
+ `),i=this.indexOf(e,t);if(i!==-1){let s=e.slice(i+t.length);this.audio_stream.push(s)}}indexOf(e,t){for(let i=0;i<=e.length-t.length;i++){let s=!0;for(let r=0;r<t.length;r++)if(e[i+r]!==t[r]){s=!1;break}if(s)return i}return-1}async generateSecMsGec(e){let t=this.nowRFC1123(),i=this.parseRFC1123(t),s=Math.floor(i.getTime()/1e3)+11644473600,m=(s-s%300)*1e7,_=new TextEncoder().encode(`${m}${e}`),u=await crypto.subtle.digest("SHA-256",_);return Array.from(new Uint8Array(u)).map(n=>n.toString(16).padStart(2,"0")).join("").toUpperCase()}getAudioData(){if(this.audio_stream.length===0)throw new Error("No audio data available");let e=this.audio_stream.reduce((s,r)=>s+r.length,0),t=new Uint8Array(e),i=0;for(let s of this.audio_stream)t.set(s,i),i+=s.length;return t}};return x(v);})();
24
24
  window.EdgeTTS = EdgeTTSModule.EdgeTTS; window.EdgeTTSVoice = EdgeTTSModule.Voice;
25
25
  //# sourceMappingURL=edge-tts.umd.min.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/browser/EdgeTTS.browser.ts", "../../src/config/constants.ts"],
4
- "sourcesContent": ["import { Constants } from '../config/constants';\r\n\r\nexport interface Voice {\r\n Name: string;\r\n ShortName: string;\r\n Gender: string;\r\n Locale: string;\r\n FriendlyName: string;\r\n LocalName: string;\r\n}\r\n\r\nexport interface SynthesisOptions {\r\n pitch?: string | number;\r\n rate?: string | number;\r\n volume?: string | number;\r\n inputType?: 'auto' | 'ssml' | 'text';\r\n}\r\n\r\ninterface SSMLValidationResult {\r\n isValid: boolean;\r\n isSSML: boolean;\r\n errors?: string[];\r\n}\r\n\r\nexport class EdgeTTS {\r\n private audio_stream: Uint8Array[] = [];\r\n private ws?: WebSocket;\r\n\r\n async getVoices(): Promise<Voice[]> {\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n \r\n const response = await fetch(\r\n `${Constants.VOICES_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}`,\r\n { headers: Constants.getBaseHeaders() }\r\n );\r\n \r\n const data = await response.json();\r\n return data.map((voice: any) => {\r\n voice.FriendlyName = voice.FriendlyName || voice.LocalName;\r\n delete voice.SampleRateHertz;\r\n delete voice.Status;\r\n return voice;\r\n });\r\n }\r\n\r\n async getVoicesByLanguage(locale: string): Promise<Voice[]> {\r\n const voices = await this.getVoices();\r\n return voices.filter(voice => voice.Locale.startsWith(locale));\r\n }\r\n\r\n async getVoicesByGender(gender: 'Male' | 'Female'): Promise<Voice[]> {\r\n const voices = await this.getVoices();\r\n return voices.filter(voice => voice.Gender === gender);\r\n }\r\n\r\n private generateUUID(): string {\r\n return 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\r\n const r = Math.random() * 16 | 0;\r\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\r\n return v.toString(16);\r\n });\r\n }\r\n\r\n private validatePitch(pitch: string | number): string {\r\n if (typeof pitch === 'number') {\r\n return (pitch >= 0 ? `+${pitch}Hz` : `${pitch}Hz`);\r\n }\r\n return pitch;\r\n }\r\n\r\n private validateRate(rate: string | number): string {\r\n let rateValue: number;\r\n if (typeof rate === 'string') {\r\n rateValue = parseFloat(rate.replace('%', ''));\r\n } else {\r\n rateValue = rate;\r\n }\r\n return rateValue >= 0 ? `+${rateValue}%` : `${rateValue}%`;\r\n }\r\n\r\n private validateVolume(volume: string | number): string {\r\n let volumeValue: number;\r\n if (typeof volume === 'string') {\r\n volumeValue = parseInt(volume.replace('%', ''), 10);\r\n } else {\r\n volumeValue = volume;\r\n }\r\n return `${volumeValue}%`;\r\n }\r\n\r\n private detectSSML(content: string): SSMLValidationResult {\r\n const trimmedContent = content.trim();\r\n const looksLikeSSML = /^<\\?xml|^<speak/i.test(trimmedContent);\r\n\r\n if (!looksLikeSSML) {\r\n return { isValid: true, isSSML: false };\r\n }\r\n\r\n const errors: string[] = [];\r\n const hasSpeakTag = /<speak\\b[^>]*>[\\s\\S]*<\\/speak>/i.test(trimmedContent);\r\n const hasVoiceTag = /<voice\\b[^>]*>[\\s\\S]*<\\/voice>/i.test(trimmedContent);\r\n\r\n if (!hasSpeakTag) {\r\n throw new Error('Invalid SSML: Missing <speak> tag');\r\n }\r\n\r\n if (!hasVoiceTag) {\r\n throw new Error('Invalid SSML: Missing <voice> tag');\r\n }\r\n\r\n const hasCorrectNamespace = /xmlns=\"http:\\/\\/www\\.w3\\.org\\/2001\\/10\\/synthesis\"/i.test(trimmedContent);\r\n if (!hasCorrectNamespace && hasSpeakTag) {\r\n throw new Error('Invalid SSML: Missing or incorrect namespace declaration');\r\n }\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n isSSML: hasSpeakTag || hasVoiceTag,\r\n errors: errors.length > 0 ? errors : undefined\r\n };\r\n }\r\n\r\n private escapeXML(text: string): string {\r\n return text\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&apos;');\r\n }\r\n\r\n private getSSML(content: string, voice: string, options: SynthesisOptions = {}): string {\r\n const inputType = options.inputType || 'auto';\r\n let treatAsSSML = false;\r\n\r\n if (inputType === 'ssml') {\r\n treatAsSSML = true;\r\n } else if (inputType === 'text') {\r\n treatAsSSML = false;\r\n } else { // 'auto'\r\n const detection = this.detectSSML(content);\r\n treatAsSSML = detection.isSSML;\r\n\r\n if (detection.isSSML) {\r\n console.log('\u2192 Detected SSML input');\r\n if (!detection.isValid) {\r\n console.warn('\u26A0 SSML validation warnings:', detection.errors);\r\n }\r\n } else {\r\n console.log('\u2192 Detected plain text input');\r\n }\r\n }\r\n\r\n if (treatAsSSML) {\r\n let ssml = content.trim();\r\n\r\n if (!ssml.includes('xmlns=')) {\r\n ssml = ssml.replace(\r\n /<speak([^>]*)>/i,\r\n '<speak$1 xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"https://www.w3.org/2001/mstts\">'\r\n );\r\n }\r\n\r\n if (!/<voice\\b[^>]*>/i.test(ssml) && voice) {\r\n ssml = ssml.replace(\r\n /(<speak[^>]*>)([\\s\\S]*?)(<\\/speak>)/i,\r\n `$1<voice name=\"${voice}\">$2</voice>$3`\r\n );\r\n }\r\n\r\n return ssml;\r\n }\r\n\r\n const pitch = this.validatePitch(options.pitch ?? 0);\r\n const rate = this.validateRate(options.rate ?? 0);\r\n const volume = this.validateVolume(options.volume ?? 0);\r\n const escapedText = this.escapeXML(content);\r\n\r\n return `<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"https://www.w3.org/2001/mstts\" xml:lang=\"en-US\">\r\n <voice name=\"${voice}\">\r\n <prosody pitch=\"${pitch}\" rate=\"${rate}\" volume=\"${volume}\">\r\n ${escapedText}\r\n </prosody>\r\n </voice>\r\n </speak>`;\r\n }\r\n\r\n private nowRFC1123(): string {\r\n return new Date().toUTCString();\r\n }\r\n\r\n private parseRFC1123(rfcStr: string): Date {\r\n return new Date(rfcStr);\r\n }\r\n\r\n private buildTTSConfigMessage(): string {\r\n const timestamp = this.nowRFC1123();\r\n return `X-Timestamp:${timestamp}\\r\\nContent-Type:application/json; charset=utf-8\\r\\nPath:speech.config\\r\\n\\r\\n` +\r\n `{\"context\":{\"synthesis\":{\"audio\":{\"metadataoptions\":{\"sentenceBoundaryEnabled\":false,\"wordBoundaryEnabled\":true},\"outputFormat\":\"audio-24khz-48kbitrate-mono-mp3\"}}}}`;\r\n }\r\n\r\n async synthesize(text: string, voice: string = 'en-US-JennyNeural', options: SynthesisOptions = {}): Promise<void> {\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n\r\n return new Promise((resolve, reject) => {\r\n this.audio_stream = [];\r\n const reqId = this.generateUUID();\r\n const url = `${Constants.WSS_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}&ConnectionId=${reqId}`;\r\n \r\n console.log('WebSocket URL:', url);\r\n this.ws = new WebSocket(url);\r\n\r\n const SSML_text = this.getSSML(text, voice, options);\r\n \r\n const timeout = setTimeout(() => {\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n reject(new Error(\"Synthesis timeout\"));\r\n }, 30000);\r\n\r\n this.ws.onopen = () => {\r\n const message = this.buildTTSConfigMessage();\r\n this.ws!.send(message);\r\n const timestamp = this.nowRFC1123();\r\n const speechMessage = `X-RequestId:${reqId}\\r\\nContent-Type:application/ssml+xml\\r\\nX-Timestamp:${timestamp}\\r\\nPath:ssml\\r\\n\\r\\n${SSML_text}`;\r\n this.ws!.send(speechMessage);\r\n };\r\n\r\n this.ws.onmessage = (event) => {\r\n if (typeof event.data === 'string') {\r\n if (event.data.includes('Path:turn.end')) {\r\n this.ws?.close();\r\n }\r\n } else {\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const arrayBuffer = reader.result as ArrayBuffer;\r\n const uint8Array = new Uint8Array(arrayBuffer);\r\n this.processAudioData(uint8Array);\r\n };\r\n reader.readAsArrayBuffer(event.data);\r\n }\r\n };\r\n\r\n this.ws.onerror = (err: any) => {\r\n clearTimeout(timeout);\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n reject(new Error('WebSocket error'));\r\n };\r\n\r\n this.ws.onclose = () => {\r\n clearTimeout(timeout);\r\n resolve();\r\n };\r\n });\r\n }\r\n\r\n async *synthesizeStream(text: string, voice: string = 'en-US-JennyNeural', options: SynthesisOptions = {}): AsyncGenerator<Uint8Array, void, unknown> {\r\n this.audio_stream = [];\r\n\r\n const reqId = this.generateUUID();\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n\r\n const url = `${Constants.WSS_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}&ConnectionId=${reqId}`;\r\n\r\n this.ws = new WebSocket(url);\r\n\r\n const SSML_text = this.getSSML(text, voice, options);\r\n\r\n const queue: Uint8Array[] = [];\r\n let done = false;\r\n let error: Error | null = null;\r\n let notify: (() => void) | null = null;\r\n\r\n const push = (chunk: Uint8Array) => {\r\n queue.push(chunk);\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n const timeout = setTimeout(() => {\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n }, 30000);\r\n\r\n this.ws.onopen = () => {\r\n const message = this.buildTTSConfigMessage();\r\n this.ws!.send(message);\r\n\r\n const timestamp = this.nowRFC1123();\r\n const speechMessage = `X-RequestId:${reqId}\\r\\nContent-Type:application/ssml+xml\\r\\nX-Timestamp:${timestamp}\\r\\nPath:ssml\\r\\n\\r\\n${SSML_text}`;\r\n this.ws!.send(speechMessage);\r\n };\r\n\r\n this.ws.onmessage = (event) => {\r\n if (typeof event.data === 'string') {\r\n if (event.data.includes('Path:turn.end')) {\r\n this.ws?.close();\r\n }\r\n } else {\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const arrayBuffer = reader.result as ArrayBuffer;\r\n const uint8Array = new Uint8Array(arrayBuffer);\r\n \r\n const needle = new TextEncoder().encode(\"Path:audio\\r\\n\");\r\n const audioStartIndex = this.indexOf(uint8Array, needle);\r\n\r\n if (audioStartIndex !== -1) {\r\n const audioChunk = uint8Array.slice(audioStartIndex + needle.length);\r\n this.audio_stream.push(audioChunk);\r\n push(audioChunk);\r\n }\r\n };\r\n reader.readAsArrayBuffer(event.data);\r\n }\r\n };\r\n\r\n this.ws.onerror = (err: any) => {\r\n error = new Error('WebSocket error');\r\n done = true;\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n this.ws.onclose = () => {\r\n clearTimeout(timeout);\r\n done = true;\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n while (!done || queue.length > 0) {\r\n if (queue.length === 0) {\r\n await new Promise<void>(resolve => (notify = resolve));\r\n continue;\r\n }\r\n const chunk = queue.shift();\r\n if (chunk) {\r\n yield chunk;\r\n }\r\n }\r\n\r\n if (error) {\r\n throw error;\r\n }\r\n }\r\n\r\n private processAudioData(buffer: Uint8Array): void {\r\n const needle = new TextEncoder().encode(\"Path:audio\\r\\n\");\r\n const audioStartIndex = this.indexOf(buffer, needle);\r\n\r\n if (audioStartIndex !== -1) {\r\n const audioChunk = buffer.slice(audioStartIndex + needle.length);\r\n this.audio_stream.push(audioChunk);\r\n }\r\n }\r\n\r\n private indexOf(arr: Uint8Array, subarr: Uint8Array): number {\r\n for (let i = 0; i <= arr.length - subarr.length; i++) {\r\n let match = true;\r\n for (let j = 0; j < subarr.length; j++) {\r\n if (arr[i + j] !== subarr[j]) {\r\n match = false;\r\n break;\r\n }\r\n }\r\n if (match) return i;\r\n }\r\n return -1;\r\n }\r\n\r\n private async generateSecMsGec(trustedClientToken: string): Promise<string> {\r\n const now = this.nowRFC1123();\r\n const fixedDate = this.parseRFC1123(now);\r\n const ticks = Math.floor(fixedDate.getTime() / 1000) + 11644473600;\r\n const rounded = ticks - (ticks % 300);\r\n const windowsTicks = rounded * 10_000_000;\r\n\r\n const encoder = new TextEncoder();\r\n const data = encoder.encode(`${windowsTicks}${trustedClientToken}`);\r\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\r\n\r\n return Array.from(new Uint8Array(hashBuffer))\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .toUpperCase();\r\n }\r\n\r\n getAudioData(): Uint8Array {\r\n if (this.audio_stream.length === 0) {\r\n throw new Error(\"No audio data available\");\r\n }\r\n const totalLength = this.audio_stream.reduce((acc, chunk) => acc + chunk.length, 0);\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const chunk of this.audio_stream) {\r\n result.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n return result;\r\n }\r\n}\r\n", "export const Constants = {\r\n TRUSTED_CLIENT_TOKEN: '6A5AA1D4EAFF4E9FB37E23D68491D6F4',\r\n BASE_URL: 'https://api.msedgeservices.com/tts/cognitiveservices',\r\n WSS_URL: 'wss://api.msedgeservices.com/tts/cognitiveservices/websocket/v1',\r\n VOICES_URL: 'https://api.msedgeservices.com/tts/cognitiveservices/voices/list',\r\n \r\n CHROMIUM_FULL_VERSION: '142.0.3595.0',\r\n CHROMIUM_MAJOR_VERSION: '142',\r\n VERSION_MS_GEC: '1-142.0.3595',\r\n \r\n token32() {\r\n const bytes = new Uint8Array(16);\r\n crypto.getRandomValues(bytes);\r\n \r\n return Array.from(bytes)\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .toUpperCase();\r\n },\r\n \r\n getBaseHeaders() {\r\n return {\r\n 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\r\n 'Accept-Encoding': 'gzip, deflate, br, zstd',\r\n 'Accept-Language': 'es,es-ES;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,es-CO;q=0.5,es-MX;q=0.4',\r\n 'Cookie': 'MUID=' + this.token32()\r\n };\r\n },\r\n \r\n WSS_HEADERS: {\r\n 'Pragma': 'no-cache',\r\n 'Cache-Control': 'no-cache',\r\n 'Origin': 'chrome-extension://jdiccldimpdaibmpdkjnbmckianbfold',\r\n 'Sec-WebSocket-Protocol': 'synthesize',\r\n 'Sec-WebSocket-Version': '13',\r\n 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0'\r\n },\r\n \r\n VOICE_HEADERS: {\r\n 'Sec-CH-UA': '\" Not;A Brand\";v=\"99\", \"Microsoft Edge\";v=\"140\", \"Chromium\";v=\"140\"',\r\n 'Sec-CH-UA-Mobile': '?0',\r\n 'Accept': '*/*',\r\n 'Sec-Fetch-Site': 'none',\r\n 'Sec-Fetch-Mode': 'cors',\r\n 'Sec-Fetch-Dest': 'empty'\r\n }\r\n};\r\n"],
5
- "mappings": "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",
6
- "names": ["EdgeTTS_browser_exports", "__export", "EdgeTTS", "Constants", "bytes", "b", "EdgeTTS", "__publicField", "secMsGEC", "Constants", "voice", "locale", "gender", "c", "r", "pitch", "rate", "rateValue", "volume", "volumeValue", "content", "trimmedContent", "errors", "hasSpeakTag", "hasVoiceTag", "text", "options", "inputType", "treatAsSSML", "detection", "ssml", "escapedText", "rfcStr", "resolve", "reject", "reqId", "url", "SSML_text", "timeout", "message", "timestamp", "speechMessage", "event", "reader", "arrayBuffer", "uint8Array", "err", "queue", "done", "error", "notify", "push", "chunk", "needle", "audioStartIndex", "audioChunk", "buffer", "arr", "subarr", "i", "match", "j", "trustedClientToken", "now", "fixedDate", "ticks", "windowsTicks", "data", "hashBuffer", "b", "totalLength", "acc", "result", "offset"]
4
+ "sourcesContent": ["import { Constants } from '../config/constants';\r\n\r\nexport interface Voice {\r\n Name: string;\r\n ShortName: string;\r\n Gender: string;\r\n Locale: string;\r\n FriendlyName: string;\r\n LocalName: string;\r\n}\r\n\r\nexport interface SynthesisOptions {\r\n pitch?: string | number;\r\n rate?: string | number;\r\n volume?: string | number;\r\n inputType?: 'auto' | 'ssml' | 'text';\r\n}\r\n\r\ninterface SSMLValidationResult {\r\n isValid: boolean;\r\n isSSML: boolean;\r\n errors?: string[];\r\n}\r\n\r\nexport class EdgeTTS {\r\n private audio_stream: Uint8Array[] = [];\r\n private ws?: WebSocket;\r\n\r\n async getVoices(): Promise<Voice[]> {\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n \r\n const response = await fetch(\r\n `${Constants.VOICES_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}`,\r\n { headers: Constants.getBaseHeaders() }\r\n );\r\n \r\n const data = await response.json();\r\n return data.map((voice: any) => {\r\n voice.FriendlyName = voice.FriendlyName || voice.LocalName;\r\n delete voice.SampleRateHertz;\r\n delete voice.Status;\r\n return voice;\r\n });\r\n }\r\n\r\n async getVoicesByLanguage(locale: string): Promise<Voice[]> {\r\n const voices = await this.getVoices();\r\n return voices.filter(voice => voice.Locale.startsWith(locale));\r\n }\r\n\r\n async getVoicesByGender(gender: 'Male' | 'Female'): Promise<Voice[]> {\r\n const voices = await this.getVoices();\r\n return voices.filter(voice => voice.Gender === gender);\r\n }\r\n\r\n private generateUUID(): string {\r\n return 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\r\n const r = Math.random() * 16 | 0;\r\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\r\n return v.toString(16);\r\n });\r\n }\r\n\r\n private validatePitch(pitch: string | number): string {\r\n if (typeof pitch === 'number') {\r\n return (pitch >= 0 ? `+${pitch}Hz` : `${pitch}Hz`);\r\n }\r\n return pitch;\r\n }\r\n\r\n private validateRate(rate: string | number): string {\r\n let rateValue: number;\r\n if (typeof rate === 'string') {\r\n rateValue = parseFloat(rate.replace('%', ''));\r\n } else {\r\n rateValue = rate;\r\n }\r\n return rateValue >= 0 ? `+${rateValue}%` : `${rateValue}%`;\r\n }\r\n\r\n private validateVolume(volume: string | number): string {\r\n let volumeValue: number;\r\n if (typeof volume === 'string') {\r\n volumeValue = parseInt(volume.replace('%', ''), 10);\r\n } else {\r\n volumeValue = volume;\r\n }\r\n return `${volumeValue}%`;\r\n }\r\n\r\n private detectSSML(content: string): SSMLValidationResult {\r\n const trimmedContent = content.trim();\r\n const looksLikeSSML = /^<\\?xml|^<speak/i.test(trimmedContent);\r\n\r\n if (!looksLikeSSML) {\r\n return { isValid: true, isSSML: false };\r\n }\r\n\r\n const errors: string[] = [];\r\n const hasSpeakTag = /<speak\\b[^>]*>[\\s\\S]*<\\/speak>/i.test(trimmedContent);\r\n const hasVoiceTag = /<voice\\b[^>]*>[\\s\\S]*<\\/voice>/i.test(trimmedContent);\r\n\r\n if (!hasSpeakTag) {\r\n throw new Error('Invalid SSML: Missing <speak> tag');\r\n }\r\n\r\n if (!hasVoiceTag) {\r\n throw new Error('Invalid SSML: Missing <voice> tag');\r\n }\r\n\r\n const hasCorrectNamespace = /xmlns=\"http:\\/\\/www\\.w3\\.org\\/2001\\/10\\/synthesis\"/i.test(trimmedContent);\r\n if (!hasCorrectNamespace && hasSpeakTag) {\r\n throw new Error('Invalid SSML: Missing or incorrect namespace declaration');\r\n }\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n isSSML: hasSpeakTag || hasVoiceTag,\r\n errors: errors.length > 0 ? errors : undefined\r\n };\r\n }\r\n\r\n private escapeXML(text: string): string {\r\n return text\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&apos;');\r\n }\r\n\r\n private getSSML(content: string, voice: string, options: SynthesisOptions = {}): string {\r\n const inputType = options.inputType || 'auto';\r\n let treatAsSSML = false;\r\n\r\n if (inputType === 'ssml') {\r\n treatAsSSML = true;\r\n } else if (inputType === 'text') {\r\n treatAsSSML = false;\r\n } else { // 'auto'\r\n const detection = this.detectSSML(content);\r\n treatAsSSML = detection.isSSML;\r\n\r\n if (detection.isSSML) {\r\n console.log('\u2192 Detected SSML input');\r\n if (!detection.isValid) {\r\n console.warn('\u26A0 SSML validation warnings:', detection.errors);\r\n }\r\n } else {\r\n console.log('\u2192 Detected plain text input');\r\n }\r\n }\r\n\r\n if (treatAsSSML) {\r\n let ssml = content.trim();\r\n\r\n if (!ssml.includes('xmlns=')) {\r\n ssml = ssml.replace(\r\n /<speak([^>]*)>/i,\r\n '<speak$1 xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"https://www.w3.org/2001/mstts\">'\r\n );\r\n }\r\n\r\n if (!/<voice\\b[^>]*>/i.test(ssml) && voice) {\r\n ssml = ssml.replace(\r\n /(<speak[^>]*>)([\\s\\S]*?)(<\\/speak>)/i,\r\n `$1<voice name=\"${voice}\">$2</voice>$3`\r\n );\r\n }\r\n\r\n return ssml;\r\n }\r\n\r\n const pitch = this.validatePitch(options.pitch ?? 0);\r\n const rate = this.validateRate(options.rate ?? 0);\r\n const volume = this.validateVolume(options.volume ?? 0);\r\n const escapedText = this.escapeXML(content);\r\n\r\n return `<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"https://www.w3.org/2001/mstts\" xml:lang=\"en-US\">\r\n <voice name=\"${voice}\">\r\n <prosody pitch=\"${pitch}\" rate=\"${rate}\" volume=\"${volume}\">\r\n ${escapedText}\r\n </prosody>\r\n </voice>\r\n </speak>`;\r\n }\r\n\r\n private nowRFC1123(): string {\r\n return new Date().toUTCString();\r\n }\r\n\r\n private parseRFC1123(rfcStr: string): Date {\r\n return new Date(rfcStr);\r\n }\r\n\r\n private buildTTSConfigMessage(): string {\r\n const timestamp = this.nowRFC1123();\r\n return `X-Timestamp:${timestamp}\\r\\nContent-Type:application/json; charset=utf-8\\r\\nPath:speech.config\\r\\n\\r\\n` +\r\n `{\"context\":{\"synthesis\":{\"audio\":{\"metadataoptions\":{\"sentenceBoundaryEnabled\":false,\"wordBoundaryEnabled\":true},\"outputFormat\":\"audio-24khz-48kbitrate-mono-mp3\"}}}}`;\r\n }\r\n\r\n async synthesize(text: string, voice: string = 'en-US-JennyNeural', options: SynthesisOptions = {}): Promise<void> {\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n\r\n return new Promise((resolve, reject) => {\r\n this.audio_stream = [];\r\n const reqId = this.generateUUID();\r\n const url = `${Constants.WSS_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}&ConnectionId=${reqId}`;\r\n \r\n console.log('WebSocket URL:', url);\r\n this.ws = new WebSocket(url);\r\n\r\n const SSML_text = this.getSSML(text, voice, options);\r\n \r\n let timedOut = false;\r\n let inactivityTimeout: number;\r\n \r\n const resetInactivityTimeout = () => {\r\n clearTimeout(inactivityTimeout);\r\n inactivityTimeout = window.setTimeout(() => {\r\n timedOut = true;\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n reject(new Error(\"WebSocket inactivity timeout - no response from server\"));\r\n }, 30000); // 30 seconds of inactivity\r\n };\r\n\r\n this.ws.onopen = () => {\r\n resetInactivityTimeout(); // start the inactivity timeout\r\n const message = this.buildTTSConfigMessage();\r\n this.ws!.send(message);\r\n const timestamp = this.nowRFC1123();\r\n const speechMessage = `X-RequestId:${reqId}\\r\\nContent-Type:application/ssml+xml\\r\\nX-Timestamp:${timestamp}\\r\\nPath:ssml\\r\\n\\r\\n${SSML_text}`;\r\n this.ws!.send(speechMessage);\r\n };\r\n\r\n this.ws.onmessage = (event) => {\r\n resetInactivityTimeout(); // restart inactivity timeout \r\n if (typeof event.data === 'string') {\r\n if (event.data.includes('Path:turn.end')) {\r\n this.ws?.close();\r\n }\r\n } else {\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const arrayBuffer = reader.result as ArrayBuffer;\r\n const uint8Array = new Uint8Array(arrayBuffer);\r\n this.processAudioData(uint8Array);\r\n };\r\n reader.readAsArrayBuffer(event.data);\r\n }\r\n };\r\n\r\n this.ws.onerror = (err: any) => {\r\n clearTimeout(inactivityTimeout);\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n reject(new Error('WebSocket error'));\r\n };\r\n\r\n this.ws.onclose = () => {\r\n clearTimeout(inactivityTimeout);\r\n if (!timedOut) {\r\n resolve();\r\n }\r\n };\r\n });\r\n }\r\n\r\n async *synthesizeStream(text: string, voice: string = 'en-US-JennyNeural', options: SynthesisOptions = {}): AsyncGenerator<Uint8Array, void, unknown> {\r\n this.audio_stream = [];\r\n\r\n const reqId = this.generateUUID();\r\n const secMsGEC = await this.generateSecMsGec(Constants.TRUSTED_CLIENT_TOKEN);\r\n\r\n const url = `${Constants.WSS_URL}?Ocp-Apim-Subscription-Key=${Constants.TRUSTED_CLIENT_TOKEN}&Sec-MS-GEC=${secMsGEC}&Sec-MS-GEC-Version=${Constants.VERSION_MS_GEC}&ConnectionId=${reqId}`;\r\n\r\n this.ws = new WebSocket(url);\r\n\r\n const SSML_text = this.getSSML(text, voice, options);\r\n\r\n const queue: Uint8Array[] = [];\r\n let done = false;\r\n let error: Error | null = null;\r\n let notify: (() => void) | null = null;\r\n\r\n const push = (chunk: Uint8Array) => {\r\n queue.push(chunk);\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n let timedOut = false;\r\n let inactivityTimeout: number;\r\n \r\n const resetInactivityTimeout = () => {\r\n clearTimeout(inactivityTimeout);\r\n inactivityTimeout = window.setTimeout(() => {\r\n timedOut = true;\r\n error = new Error(\"WebSocket inactivity timeout - no response from server\");\r\n done = true;\r\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\r\n this.ws.close();\r\n }\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n }, 30000); // 30 seconds of inactivity\r\n };\r\n\r\n this.ws.onopen = () => {\r\n resetInactivityTimeout(); // start the inactivity timeout\r\n const message = this.buildTTSConfigMessage();\r\n this.ws!.send(message);\r\n\r\n const timestamp = this.nowRFC1123();\r\n const speechMessage = `X-RequestId:${reqId}\\r\\nContent-Type:application/ssml+xml\\r\\nX-Timestamp:${timestamp}\\r\\nPath:ssml\\r\\n\\r\\n${SSML_text}`;\r\n this.ws!.send(speechMessage);\r\n };\r\n\r\n this.ws.onmessage = (event) => {\r\n resetInactivityTimeout(); // restart inactivity timeout\r\n if (typeof event.data === 'string') {\r\n if (event.data.includes('Path:turn.end')) {\r\n this.ws?.close();\r\n }\r\n } else {\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const arrayBuffer = reader.result as ArrayBuffer;\r\n const uint8Array = new Uint8Array(arrayBuffer);\r\n \r\n const needle = new TextEncoder().encode(\"Path:audio\\r\\n\");\r\n const audioStartIndex = this.indexOf(uint8Array, needle);\r\n\r\n if (audioStartIndex !== -1) {\r\n const audioChunk = uint8Array.slice(audioStartIndex + needle.length);\r\n this.audio_stream.push(audioChunk);\r\n push(audioChunk);\r\n }\r\n };\r\n reader.readAsArrayBuffer(event.data);\r\n }\r\n };\r\n\r\n this.ws.onerror = (err: any) => {\r\n clearTimeout(inactivityTimeout);\r\n error = new Error('WebSocket error');\r\n done = true;\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n this.ws.onclose = () => {\r\n clearTimeout(inactivityTimeout);\r\n done = true;\r\n if (notify) {\r\n notify();\r\n notify = null;\r\n }\r\n };\r\n\r\n while (!done || queue.length > 0) {\r\n if (queue.length === 0) {\r\n await new Promise<void>(resolve => (notify = resolve));\r\n continue;\r\n }\r\n const chunk = queue.shift();\r\n if (chunk) {\r\n yield chunk;\r\n }\r\n }\r\n\r\n if (error) {\r\n throw error;\r\n }\r\n }\r\n\r\n private processAudioData(buffer: Uint8Array): void {\r\n const needle = new TextEncoder().encode(\"Path:audio\\r\\n\");\r\n const audioStartIndex = this.indexOf(buffer, needle);\r\n\r\n if (audioStartIndex !== -1) {\r\n const audioChunk = buffer.slice(audioStartIndex + needle.length);\r\n this.audio_stream.push(audioChunk);\r\n }\r\n }\r\n\r\n private indexOf(arr: Uint8Array, subarr: Uint8Array): number {\r\n for (let i = 0; i <= arr.length - subarr.length; i++) {\r\n let match = true;\r\n for (let j = 0; j < subarr.length; j++) {\r\n if (arr[i + j] !== subarr[j]) {\r\n match = false;\r\n break;\r\n }\r\n }\r\n if (match) return i;\r\n }\r\n return -1;\r\n }\r\n\r\n private async generateSecMsGec(trustedClientToken: string): Promise<string> {\r\n const now = this.nowRFC1123();\r\n const fixedDate = this.parseRFC1123(now);\r\n const ticks = Math.floor(fixedDate.getTime() / 1000) + 11644473600;\r\n const rounded = ticks - (ticks % 300);\r\n const windowsTicks = rounded * 10_000_000;\r\n\r\n const encoder = new TextEncoder();\r\n const data = encoder.encode(`${windowsTicks}${trustedClientToken}`);\r\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\r\n\r\n return Array.from(new Uint8Array(hashBuffer))\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .toUpperCase();\r\n }\r\n\r\n getAudioData(): Uint8Array {\r\n if (this.audio_stream.length === 0) {\r\n throw new Error(\"No audio data available\");\r\n }\r\n const totalLength = this.audio_stream.reduce((acc, chunk) => acc + chunk.length, 0);\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const chunk of this.audio_stream) {\r\n result.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n return result;\r\n }\r\n}\r\n", "export const Constants = {\r\n TRUSTED_CLIENT_TOKEN: '6A5AA1D4EAFF4E9FB37E23D68491D6F4',\r\n BASE_URL: 'https://api.msedgeservices.com/tts/cognitiveservices',\r\n WSS_URL: 'wss://api.msedgeservices.com/tts/cognitiveservices/websocket/v1',\r\n VOICES_URL: 'https://api.msedgeservices.com/tts/cognitiveservices/voices/list',\r\n\r\n CHROMIUM_FULL_VERSION: '142.0.3595.0',\r\n CHROMIUM_MAJOR_VERSION: '142',\r\n VERSION_MS_GEC: '1-142.0.3595',\r\n\r\n token32() {\r\n const bytes = new Uint8Array(16);\r\n crypto.getRandomValues(bytes);\r\n\r\n return Array.from(bytes)\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .toUpperCase();\r\n },\r\n\r\n getBaseHeaders() {\r\n return {\r\n 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\r\n 'Accept-Encoding': 'gzip, deflate, br, zstd',\r\n 'Accept-Language': 'es,es-ES;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,es-CO;q=0.5,es-MX;q=0.4',\r\n 'Cookie': 'MUID=' + this.token32()\r\n };\r\n },\r\n\r\n WSS_HEADERS: {\r\n 'Pragma': 'no-cache',\r\n 'Cache-Control': 'no-cache',\r\n 'Origin': 'chrome-extension://jdiccldimpdaibmpdkjnbmckianbfold',\r\n 'Sec-WebSocket-Protocol': 'synthesize',\r\n 'Sec-WebSocket-Version': '13',\r\n 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0'\r\n },\r\n\r\n VOICE_HEADERS: {\r\n 'Sec-CH-UA': '\" Not;A Brand\";v=\"99\", \"Microsoft Edge\";v=\"140\", \"Chromium\";v=\"140\"',\r\n 'Sec-CH-UA-Mobile': '?0',\r\n 'Accept': '*/*',\r\n 'Sec-Fetch-Site': 'none',\r\n 'Sec-Fetch-Mode': 'cors',\r\n 'Sec-Fetch-Dest': 'empty'\r\n },\r\n \r\n // https://learn.microsoft.com/en-us/azure/ai-services/speech-service/rest-text-to-speech?tabs=nonstreaming\r\n OUTPUT_FORMAT: {\r\n // Streaming \r\n AMR_WB_16000HZ: 'amr-wb-16000hz',\r\n AUDIO_16KHZ_16BIT_32KBPS_MONO_OPUS: 'audio-16khz-16bit-32kbps-mono-opus',\r\n AUDIO_16KHZ_32KBITRATE_MONO_MP3: 'audio-16khz-32kbitrate-mono-mp3',\r\n AUDIO_16KHZ_64KBITRATE_MONO_MP3: 'audio-16khz-64kbitrate-mono-mp3',\r\n AUDIO_16KHZ_128KBITRATE_MONO_MP3: 'audio-16khz-128kbitrate-mono-mp3',\r\n AUDIO_24KHZ_16BIT_24KBPS_MONO_OPUS: 'audio-24khz-16bit-24kbps-mono-opus',\r\n AUDIO_24KHZ_16BIT_48KBPS_MONO_OPUS: 'audio-24khz-16bit-48kbps-mono-opus',\r\n AUDIO_24KHZ_48KBITRATE_MONO_MP3: 'audio-24khz-48kbitrate-mono-mp3',\r\n AUDIO_24KHZ_96KBITRATE_MONO_MP3: 'audio-24khz-96kbitrate-mono-mp3',\r\n AUDIO_24KHZ_160KBITRATE_MONO_MP3: 'audio-24khz-160kbitrate-mono-mp3',\r\n AUDIO_48KHZ_96KBITRATE_MONO_MP3: 'audio-48khz-96kbitrate-mono-mp3',\r\n AUDIO_48KHZ_192KBITRATE_MONO_MP3: 'audio-48khz-192kbitrate-mono-mp3',\r\n G722_16KHZ_64KBPS: 'g722-16khz-64kbps',\r\n OGG_16KHZ_16BIT_MONO_OPUS: 'ogg-16khz-16bit-mono-opus',\r\n OGG_24KHZ_16BIT_MONO_OPUS: 'ogg-24khz-16bit-mono-opus',\r\n OGG_48KHZ_16BIT_MONO_OPUS: 'ogg-48khz-16bit-mono-opus',\r\n RAW_8KHZ_8BIT_MONO_ALAW: 'raw-8khz-8bit-mono-alaw',\r\n RAW_8KHZ_8BIT_MONO_MULAW: 'raw-8khz-8bit-mono-mulaw',\r\n RAW_8KHZ_16BIT_MONO_PCM: 'raw-8khz-16bit-mono-pcm',\r\n RAW_16KHZ_16BIT_MONO_PCM: 'raw-16khz-16bit-mono-pcm',\r\n RAW_16KHZ_16BIT_MONO_TRUESILK: 'raw-16khz-16bit-mono-truesilk',\r\n RAW_22050HZ_16BIT_MONO_PCM: 'raw-22050hz-16bit-mono-pcm',\r\n RAW_24KHZ_16BIT_MONO_PCM: 'raw-24khz-16bit-mono-pcm',\r\n RAW_24KHZ_16BIT_MONO_TRUESILK: 'raw-24khz-16bit-mono-truesilk',\r\n RAW_44100HZ_16BIT_MONO_PCM: 'raw-44100hz-16bit-mono-pcm',\r\n RAW_48KHZ_16BIT_MONO_PCM: 'raw-48khz-16bit-mono-pcm',\r\n WEBM_16KHZ_16BIT_MONO_OPUS: 'webm-16khz-16bit-mono-opus',\r\n WEBM_24KHZ_16BIT_24KBPS_MONO_OPUS: 'webm-24khz-16bit-24kbps-mono-opus',\r\n WEBM_24KHZ_16BIT_MONO_OPUS: 'webm-24khz-16bit-mono-opus',\r\n // NonStreaming \r\n RIFF_8KHZ_8BIT_MONO_ALAW: 'riff-8khz-8bit-mono-alaw',\r\n RIFF_8KHZ_8BIT_MONO_MULAW: 'riff-8khz-8bit-mono-mulaw',\r\n RIFF_8KHZ_16BIT_MONO_PCM: 'riff-8khz-16bit-mono-pcm',\r\n RIFF_22050HZ_16BIT_MONO_PCM: 'riff-22050hz-16bit-mono-pcm',\r\n RIFF_24KHZ_16BIT_MONO_PCM: 'riff-24khz-16bit-mono-pcm',\r\n RIFF_44100HZ_16BIT_MONO_PCM: 'riff-44100hz-16bit-mono-pcm',\r\n RIFF_48KHZ_16BIT_MONO_PCM: 'riff-48khz-16bit-mono-pcm'\r\n }\r\n\r\n\r\n};\r\n"],
5
+ "mappings": "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",
6
+ "names": ["EdgeTTS_browser_exports", "__export", "EdgeTTS", "Constants", "bytes", "b", "EdgeTTS", "__publicField", "secMsGEC", "Constants", "voice", "locale", "gender", "c", "r", "pitch", "rate", "rateValue", "volume", "volumeValue", "content", "trimmedContent", "errors", "hasSpeakTag", "hasVoiceTag", "text", "options", "inputType", "treatAsSSML", "detection", "ssml", "escapedText", "rfcStr", "resolve", "reject", "reqId", "url", "SSML_text", "timedOut", "inactivityTimeout", "resetInactivityTimeout", "message", "timestamp", "speechMessage", "event", "reader", "arrayBuffer", "uint8Array", "err", "queue", "done", "error", "notify", "push", "chunk", "needle", "audioStartIndex", "audioChunk", "buffer", "arr", "subarr", "match", "j", "trustedClientToken", "now", "fixedDate", "ticks", "windowsTicks", "data", "hashBuffer", "b", "totalLength", "acc", "result", "offset"]
7
7
  }
@@ -6,7 +6,7 @@ const VoiceListCommand_1 = require("../commands/VoiceListCommand");
6
6
  const commander_1 = require("commander");
7
7
  const program = new commander_1.Command();
8
8
  program
9
- .version('1.6.1')
9
+ .version('1.7.0')
10
10
  .addCommand(SynthesizeCommand_1.SynthesizeCommand)
11
11
  .addCommand(VoiceListCommand_1.VoiceListCommand);
12
12
  try {
@@ -29,4 +29,42 @@ export declare const Constants: {
29
29
  'Sec-Fetch-Mode': string;
30
30
  'Sec-Fetch-Dest': string;
31
31
  };
32
+ OUTPUT_FORMAT: {
33
+ AMR_WB_16000HZ: string;
34
+ AUDIO_16KHZ_16BIT_32KBPS_MONO_OPUS: string;
35
+ AUDIO_16KHZ_32KBITRATE_MONO_MP3: string;
36
+ AUDIO_16KHZ_64KBITRATE_MONO_MP3: string;
37
+ AUDIO_16KHZ_128KBITRATE_MONO_MP3: string;
38
+ AUDIO_24KHZ_16BIT_24KBPS_MONO_OPUS: string;
39
+ AUDIO_24KHZ_16BIT_48KBPS_MONO_OPUS: string;
40
+ AUDIO_24KHZ_48KBITRATE_MONO_MP3: string;
41
+ AUDIO_24KHZ_96KBITRATE_MONO_MP3: string;
42
+ AUDIO_24KHZ_160KBITRATE_MONO_MP3: string;
43
+ AUDIO_48KHZ_96KBITRATE_MONO_MP3: string;
44
+ AUDIO_48KHZ_192KBITRATE_MONO_MP3: string;
45
+ G722_16KHZ_64KBPS: string;
46
+ OGG_16KHZ_16BIT_MONO_OPUS: string;
47
+ OGG_24KHZ_16BIT_MONO_OPUS: string;
48
+ OGG_48KHZ_16BIT_MONO_OPUS: string;
49
+ RAW_8KHZ_8BIT_MONO_ALAW: string;
50
+ RAW_8KHZ_8BIT_MONO_MULAW: string;
51
+ RAW_8KHZ_16BIT_MONO_PCM: string;
52
+ RAW_16KHZ_16BIT_MONO_PCM: string;
53
+ RAW_16KHZ_16BIT_MONO_TRUESILK: string;
54
+ RAW_22050HZ_16BIT_MONO_PCM: string;
55
+ RAW_24KHZ_16BIT_MONO_PCM: string;
56
+ RAW_24KHZ_16BIT_MONO_TRUESILK: string;
57
+ RAW_44100HZ_16BIT_MONO_PCM: string;
58
+ RAW_48KHZ_16BIT_MONO_PCM: string;
59
+ WEBM_16KHZ_16BIT_MONO_OPUS: string;
60
+ WEBM_24KHZ_16BIT_24KBPS_MONO_OPUS: string;
61
+ WEBM_24KHZ_16BIT_MONO_OPUS: string;
62
+ RIFF_8KHZ_8BIT_MONO_ALAW: string;
63
+ RIFF_8KHZ_8BIT_MONO_MULAW: string;
64
+ RIFF_8KHZ_16BIT_MONO_PCM: string;
65
+ RIFF_22050HZ_16BIT_MONO_PCM: string;
66
+ RIFF_24KHZ_16BIT_MONO_PCM: string;
67
+ RIFF_44100HZ_16BIT_MONO_PCM: string;
68
+ RIFF_48KHZ_16BIT_MONO_PCM: string;
69
+ };
32
70
  };