ssml-builder-js 2.16.0 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -2
- package/dist/{chunk-NKLZGITR.mjs → chunk-2SYLELUT.mjs} +4 -2
- package/dist/{chunk-NKLZGITR.mjs.map → chunk-2SYLELUT.mjs.map} +1 -1
- package/dist/{chunk-HI74FTKY.mjs → chunk-5AZWURHW.mjs} +4 -2
- package/dist/{chunk-HI74FTKY.mjs.map → chunk-5AZWURHW.mjs.map} +1 -1
- package/dist/{chunk-F2EMU3HM.mjs → chunk-SLZ7PE6W.mjs} +2 -2
- package/dist/core.d.mts +4 -0
- package/dist/core.d.ts +4 -0
- package/dist/core.js +3 -1
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +1 -1
- package/dist/elements.js +3 -1
- package/dist/elements.js.map +1 -1
- package/dist/elements.mjs +2 -2
- package/dist/{index.d-DR5Qz43p.d.mts → index.d-tpKoP1jl.d.mts} +12 -1
- package/dist/{index.d-DR5Qz43p.d.ts → index.d-tpKoP1jl.d.ts} +12 -1
- package/dist/index.d.mts +78 -11
- package/dist/index.d.ts +78 -11
- package/dist/index.js +336 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +330 -72
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +5 -2
- package/dist/react.d.ts +5 -2
- package/dist/react.js +111 -25
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +110 -26
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
- /package/dist/{chunk-F2EMU3HM.mjs.map → chunk-SLZ7PE6W.mjs.map} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -18,12 +18,12 @@ import {
|
|
|
18
18
|
validateAzureSsmlChunks,
|
|
19
19
|
validateSsml,
|
|
20
20
|
validateSsmlStructureIntegrity
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-2SYLELUT.mjs";
|
|
22
22
|
import {
|
|
23
23
|
createAzureUrlValidatorRunner as createAzureUrlValidatorRunner2,
|
|
24
24
|
getSsmlSourceMap as getSsmlSourceMap2,
|
|
25
25
|
validateAzureSsml as validateAzureSsml2
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-5AZWURHW.mjs";
|
|
27
27
|
import {
|
|
28
28
|
__privateAdd,
|
|
29
29
|
__privateGet,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
|
|
33
33
|
// packages/azure-tts-client/src/errors.ts
|
|
34
34
|
var AzureTtsError = class extends Error {
|
|
35
|
-
constructor(status, statusText, responseBody, requestId) {
|
|
35
|
+
constructor(status, statusText, responseBody, requestId, responseHeaders) {
|
|
36
36
|
super(`Azure TTS request failed: ${status} ${statusText}`);
|
|
37
37
|
this.kind = "azure-api-error";
|
|
38
38
|
this.name = "AzureTtsError";
|
|
@@ -40,8 +40,37 @@ var AzureTtsError = class extends Error {
|
|
|
40
40
|
this.statusText = statusText;
|
|
41
41
|
this.responseBody = responseBody;
|
|
42
42
|
this.requestId = requestId;
|
|
43
|
+
const value = responseHeaders instanceof Headers ? responseHeaders.get("retry-after") : responseHeaders?.["retry-after"] ?? responseHeaders?.["Retry-After"];
|
|
44
|
+
const seconds = value ? Number(value.trim()) : NaN;
|
|
45
|
+
const date = value ? Date.parse(value) : NaN;
|
|
46
|
+
if (Number.isFinite(seconds) && seconds >= 0) this.retryAfterMs = seconds * 1e3;
|
|
47
|
+
else if (Number.isFinite(date)) this.retryAfterMs = Math.max(0, date - Date.now());
|
|
43
48
|
}
|
|
44
49
|
};
|
|
50
|
+
function getRetryAfterDelayMs(error) {
|
|
51
|
+
if (error instanceof AzureTtsError && error.retryAfterMs !== void 0) return error.retryAfterMs;
|
|
52
|
+
if (!error || typeof error !== "object") return void 0;
|
|
53
|
+
const candidate = error;
|
|
54
|
+
if (typeof candidate.retryAfterMs === "number" && candidate.retryAfterMs >= 0) return candidate.retryAfterMs;
|
|
55
|
+
const headers = candidate.headers ?? candidate.response?.headers;
|
|
56
|
+
if (headers instanceof Headers) {
|
|
57
|
+
const value = headers.get("retry-after");
|
|
58
|
+
if (!value) return void 0;
|
|
59
|
+
const seconds = Number(value.trim());
|
|
60
|
+
if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
|
|
61
|
+
const date = Date.parse(value);
|
|
62
|
+
return Number.isFinite(date) ? Math.max(0, date - Date.now()) : void 0;
|
|
63
|
+
}
|
|
64
|
+
if (headers && typeof headers === "object") {
|
|
65
|
+
const value = headers["retry-after"] ?? headers["Retry-After"];
|
|
66
|
+
if (typeof value !== "string") return void 0;
|
|
67
|
+
const seconds = Number(value.trim());
|
|
68
|
+
if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
|
|
69
|
+
const date = Date.parse(value);
|
|
70
|
+
return Number.isFinite(date) ? Math.max(0, date - Date.now()) : void 0;
|
|
71
|
+
}
|
|
72
|
+
return void 0;
|
|
73
|
+
}
|
|
45
74
|
var AzureTtsSdkError = class extends AzureTtsError {
|
|
46
75
|
constructor(errorDetails) {
|
|
47
76
|
super(0, "Speech SDK", errorDetails, null);
|
|
@@ -233,6 +262,8 @@ function formatAudioSpecification(format) {
|
|
|
233
262
|
const bitrateMatch = /(\d+)(?:kbitrate|kbps|kbits?)/i.exec(format);
|
|
234
263
|
const bitrate = bitrateMatch?.[1] ? Number(bitrateMatch[1]) * 1e3 : void 0;
|
|
235
264
|
const codec = /mp3|mpeg/i.test(format) ? "mp3" : /opus/i.test(format) ? "opus" : /silk/i.test(format) ? "silk" : /pcm|mulaw|alaw|siren/i.test(format) ? "pcm" : "unknown";
|
|
265
|
+
const bitDepthMatch = /(\d+)bit/i.exec(format);
|
|
266
|
+
const container = /(?:wav|wave|riff)/i.test(format) ? "riff-wave" : /mp3|mpeg/i.test(format) ? "mp3-raw" : /ogg/i.test(format) ? "ogg" : /webm/i.test(format) ? "webm" : /raw/i.test(format) ? "raw" : void 0;
|
|
236
267
|
return {
|
|
237
268
|
format,
|
|
238
269
|
mimeType: resolveMimeType(format),
|
|
@@ -240,6 +271,9 @@ function formatAudioSpecification(format) {
|
|
|
240
271
|
sampleRate,
|
|
241
272
|
channels,
|
|
242
273
|
...bitrate ? { bitrate } : {},
|
|
274
|
+
...bitDepthMatch?.[1] ? { bitDepth: Number(bitDepthMatch[1]) } : {},
|
|
275
|
+
...container ? { container } : {},
|
|
276
|
+
isVbr: /vbr/i.test(format),
|
|
243
277
|
isCompressed: codec === "mp3" || codec === "opus" || codec === "silk"
|
|
244
278
|
};
|
|
245
279
|
}
|
|
@@ -275,6 +309,8 @@ function parseMp3Specification(buffer, format) {
|
|
|
275
309
|
sampleRate,
|
|
276
310
|
channels: (bytes[index + 3] ?? 0) >> 6 === 3 ? 1 : 2,
|
|
277
311
|
bitrate: bitrateKbps * 1e3,
|
|
312
|
+
container: "mp3-raw",
|
|
313
|
+
isVbr: false,
|
|
278
314
|
isCompressed: true
|
|
279
315
|
};
|
|
280
316
|
}
|
|
@@ -296,6 +332,9 @@ function inspectAudioSpecification(buffer, format) {
|
|
|
296
332
|
sampleRate,
|
|
297
333
|
channels,
|
|
298
334
|
...sampleRate && channels && bitsPerSample ? { bitrate: sampleRate * channels * bitsPerSample } : {},
|
|
335
|
+
bitDepth: bitsPerSample,
|
|
336
|
+
container: "riff-wave",
|
|
337
|
+
isVbr: false,
|
|
299
338
|
isCompressed: formatCode !== 1
|
|
300
339
|
};
|
|
301
340
|
}
|
|
@@ -306,7 +345,7 @@ function validateAudioSpecifications(specs) {
|
|
|
306
345
|
const first = specs[0];
|
|
307
346
|
if (!first) return;
|
|
308
347
|
const mismatch = specs.find(
|
|
309
|
-
(spec) => spec.sampleRate !== first.sampleRate || spec.channels !== first.channels || first.bitrate !== void 0 && spec.bitrate !== void 0 && spec.bitrate !== first.bitrate
|
|
348
|
+
(spec) => spec.sampleRate !== first.sampleRate || spec.channels !== first.channels || first.bitrate !== void 0 && spec.bitrate !== void 0 && spec.bitrate !== first.bitrate || first.bitDepth !== void 0 && spec.bitDepth !== void 0 && spec.bitDepth !== first.bitDepth || first.container !== void 0 && spec.container !== void 0 && spec.container !== first.container || first.isVbr !== void 0 && spec.isVbr !== void 0 && spec.isVbr !== first.isVbr
|
|
310
349
|
);
|
|
311
350
|
if (mismatch)
|
|
312
351
|
throw new AudioFormatMismatchError(
|
|
@@ -509,9 +548,7 @@ async function synthesizeSsml(ssml, config) {
|
|
|
509
548
|
};
|
|
510
549
|
}
|
|
511
550
|
if (sourceSegments.length === 0 && !config.sourceTextRange && !config.sourceNodePath) {
|
|
512
|
-
|
|
513
|
-
Object.defineProperty(unmapped, "mappingStatus", { value: "unmapped", enumerable: false });
|
|
514
|
-
return unmapped;
|
|
551
|
+
return { mappingStatus: "unmapped" };
|
|
515
552
|
}
|
|
516
553
|
const value = text ?? "";
|
|
517
554
|
let localStart = Number.isFinite(offsetHint) && (offsetHint ?? 0) >= 0 ? offsetHint : -1;
|
|
@@ -593,8 +630,13 @@ async function synthesizeSsml(ssml, config) {
|
|
|
593
630
|
...config.sourceNodePath ? { sourceNodePath: [...config.sourceNodePath] } : {},
|
|
594
631
|
...requestId ? { requestId } : {}
|
|
595
632
|
};
|
|
596
|
-
if (event.mappingStatus === "unmapped")
|
|
633
|
+
if (event.mappingStatus === "unmapped") {
|
|
597
634
|
Object.defineProperty(mapped, "mappingStatus", { value: "unmapped", enumerable: false });
|
|
635
|
+
Object.defineProperty(mapped, "toJSON", {
|
|
636
|
+
value: () => ({ ...mapped, mappingStatus: "unmapped" }),
|
|
637
|
+
enumerable: false
|
|
638
|
+
});
|
|
639
|
+
}
|
|
598
640
|
return mapped;
|
|
599
641
|
};
|
|
600
642
|
const sourceBoundaries = boundaries.map((boundary) => addSourceMetadata(boundary));
|
|
@@ -617,10 +659,11 @@ async function synthesizeSsml(ssml, config) {
|
|
|
617
659
|
abortHandler = () => rejectWithError(new SynthesisCancelledError());
|
|
618
660
|
config.signal.addEventListener("abort", abortHandler, { once: true });
|
|
619
661
|
}
|
|
620
|
-
|
|
662
|
+
const timeoutMs = config.timeouts?.perChunkMs ?? config.timeoutMs;
|
|
663
|
+
if (timeoutMs !== void 0 && timeoutMs > 0) {
|
|
621
664
|
timeout = setTimeout(
|
|
622
|
-
() => rejectWithError(new SynthesisTimeoutError(`Speech synthesis timed out after ${
|
|
623
|
-
|
|
665
|
+
() => rejectWithError(new SynthesisTimeoutError(`Speech synthesis timed out after ${timeoutMs} ms.`)),
|
|
666
|
+
timeoutMs
|
|
624
667
|
);
|
|
625
668
|
}
|
|
626
669
|
synthesizer.speakSsmlAsync(ssml, cb, rejectWithError);
|
|
@@ -639,7 +682,9 @@ function isRetryableSynthesisError(error) {
|
|
|
639
682
|
if (typeof status === "number") return status === 429 || status >= 500 && status < 600;
|
|
640
683
|
return /network|connection|connect|socket|fetch failed|econn|etimedout|temporar|transient|unavailable/i.test(message);
|
|
641
684
|
}
|
|
642
|
-
function retryDelay(options, retryAttempt) {
|
|
685
|
+
function retryDelay(options, retryAttempt, error) {
|
|
686
|
+
const retryAfterMs = getRetryAfterDelayMs(error);
|
|
687
|
+
if (retryAfterMs !== void 0) return retryAfterMs;
|
|
643
688
|
const base = Math.min(options.maxDelayMs, options.initialDelayMs * 2 ** Math.max(0, retryAttempt - 1));
|
|
644
689
|
return Math.floor(Math.random() * (base + 1));
|
|
645
690
|
}
|
|
@@ -671,7 +716,8 @@ async function synthesizeWithRetry(ssml, config, retryOptions, onRetry) {
|
|
|
671
716
|
const options = retryOptions ? {
|
|
672
717
|
maxRetries: Math.max(0, Math.floor(retryOptions.maxRetries)),
|
|
673
718
|
initialDelayMs: Math.max(0, retryOptions.initialDelayMs),
|
|
674
|
-
maxDelayMs: Math.max(0, retryOptions.maxDelayMs)
|
|
719
|
+
maxDelayMs: Math.max(0, retryOptions.maxDelayMs),
|
|
720
|
+
shouldRetry: retryOptions.shouldRetry
|
|
675
721
|
} : void 0;
|
|
676
722
|
let attempt = 0;
|
|
677
723
|
while (true) {
|
|
@@ -679,17 +725,56 @@ async function synthesizeWithRetry(ssml, config, retryOptions, onRetry) {
|
|
|
679
725
|
try {
|
|
680
726
|
return await synthesizeSsml(ssml, config);
|
|
681
727
|
} catch (error) {
|
|
682
|
-
if (!options || attempt >= options.maxRetries || !
|
|
728
|
+
if (!options || attempt >= options.maxRetries || !(options.shouldRetry?.(error, attempt + 1) ?? isRetryableSynthesisError(error)))
|
|
729
|
+
throw error;
|
|
683
730
|
attempt += 1;
|
|
684
|
-
const delayMs = retryDelay(options, attempt);
|
|
731
|
+
const delayMs = retryDelay(options, attempt, error);
|
|
685
732
|
onRetry(attempt, delayMs);
|
|
686
733
|
await waitForRetry(delayMs, config.signal);
|
|
687
734
|
}
|
|
688
735
|
}
|
|
689
736
|
}
|
|
737
|
+
function createAbortScope(parent, timeoutMs) {
|
|
738
|
+
const controller = new AbortController();
|
|
739
|
+
let didTimeout = false;
|
|
740
|
+
const onAbort = () => controller.abort();
|
|
741
|
+
if (parent?.aborted) controller.abort();
|
|
742
|
+
parent?.addEventListener("abort", onAbort, { once: true });
|
|
743
|
+
const timer = timeoutMs !== void 0 && timeoutMs > 0 ? setTimeout(() => {
|
|
744
|
+
didTimeout = true;
|
|
745
|
+
controller.abort();
|
|
746
|
+
}, timeoutMs) : void 0;
|
|
747
|
+
return {
|
|
748
|
+
signal: controller.signal,
|
|
749
|
+
timedOut: () => didTimeout,
|
|
750
|
+
dispose: () => {
|
|
751
|
+
if (timer) clearTimeout(timer);
|
|
752
|
+
parent?.removeEventListener("abort", onAbort);
|
|
753
|
+
},
|
|
754
|
+
abort: () => controller.abort()
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
async function synthesizeChunkWithTimeout(ssml, config, retryOptions, timeoutMs, onRetry) {
|
|
758
|
+
const scope = createAbortScope(config.signal, timeoutMs);
|
|
759
|
+
try {
|
|
760
|
+
return await synthesizeWithRetry(ssml, { ...config, signal: scope.signal }, retryOptions, onRetry);
|
|
761
|
+
} catch (error) {
|
|
762
|
+
if (scope.timedOut()) throw new SynthesisTimeoutError(`Speech synthesis timed out after ${timeoutMs} ms.`);
|
|
763
|
+
throw error;
|
|
764
|
+
} finally {
|
|
765
|
+
scope.dispose();
|
|
766
|
+
}
|
|
767
|
+
}
|
|
690
768
|
async function synthesizeSsmlChunks(chunks, config) {
|
|
691
769
|
const results = new Array(chunks.length);
|
|
692
770
|
const totalChunks = chunks.length;
|
|
771
|
+
const cachedChunks = new Map((config.resumeChunks ?? []).map((chunk) => [chunk.chunkIndex, chunk]));
|
|
772
|
+
for (const [index, cached] of cachedChunks) {
|
|
773
|
+
if (index >= 0 && index < totalChunks) results[index] = cached;
|
|
774
|
+
}
|
|
775
|
+
const requestedIndices = config.resumeChunkIndices ? new Set(config.resumeChunkIndices.filter((index) => index >= 0 && index < totalChunks)) : void 0;
|
|
776
|
+
const shouldSynthesize = (index) => !cachedChunks.has(index) && (requestedIndices === void 0 || requestedIndices.has(index));
|
|
777
|
+
const scope = createAbortScope(config.signal, config.timeouts?.totalJobMs);
|
|
693
778
|
const report = (event) => config.onProgress?.(event);
|
|
694
779
|
for (const [index, chunk] of chunks.entries()) {
|
|
695
780
|
const input = typeof chunk === "string" ? { ssml: chunk } : chunk;
|
|
@@ -703,13 +788,17 @@ async function synthesizeSsmlChunks(chunks, config) {
|
|
|
703
788
|
durationMs: 0
|
|
704
789
|
});
|
|
705
790
|
}
|
|
706
|
-
let completed = 0;
|
|
791
|
+
let completed = [...results].filter((result) => result !== void 0).length;
|
|
707
792
|
let nextIndex = 0;
|
|
708
793
|
const concurrency = resolveConcurrency(config.concurrency, chunks.length);
|
|
794
|
+
let firstError;
|
|
795
|
+
const failedIndices = /* @__PURE__ */ new Set();
|
|
709
796
|
const worker = async () => {
|
|
710
797
|
while (true) {
|
|
711
798
|
const index = nextIndex++;
|
|
712
799
|
if (index >= chunks.length) return;
|
|
800
|
+
if (!shouldSynthesize(index)) continue;
|
|
801
|
+
if (firstError && config.cancelOnFailure !== false) return;
|
|
713
802
|
const chunk = chunks[index];
|
|
714
803
|
const input = typeof chunk === "string" ? { ssml: chunk } : chunk;
|
|
715
804
|
report({
|
|
@@ -723,10 +812,11 @@ async function synthesizeSsmlChunks(chunks, config) {
|
|
|
723
812
|
});
|
|
724
813
|
const startedAt = Date.now();
|
|
725
814
|
try {
|
|
726
|
-
const result = await
|
|
815
|
+
const result = await synthesizeChunkWithTimeout(
|
|
727
816
|
input.ssml,
|
|
728
817
|
{
|
|
729
818
|
...config,
|
|
819
|
+
signal: scope.signal,
|
|
730
820
|
...input.originalTextRange ? { sourceTextRange: input.originalTextRange } : {},
|
|
731
821
|
...input.sourceNodePath ?? config.sourceNodePath ? { sourceNodePath: [...input.sourceNodePath ?? config.sourceNodePath ?? []] } : {},
|
|
732
822
|
...input.sourceTextSegments ? { sourceTextSegments: input.sourceTextSegments } : {},
|
|
@@ -735,6 +825,7 @@ async function synthesizeSsmlChunks(chunks, config) {
|
|
|
735
825
|
onProgress: void 0
|
|
736
826
|
},
|
|
737
827
|
config.retryOptions,
|
|
828
|
+
config.timeouts?.chunkWithRetriesMs ?? config.timeouts?.perChunkMs ?? config.timeoutMs,
|
|
738
829
|
(retryAttempt, nextRetryDelayMs) => report({
|
|
739
830
|
currentChunk: completed,
|
|
740
831
|
totalChunks,
|
|
@@ -760,6 +851,7 @@ async function synthesizeSsmlChunks(chunks, config) {
|
|
|
760
851
|
durationMs: Date.now() - startedAt
|
|
761
852
|
});
|
|
762
853
|
} catch (error) {
|
|
854
|
+
failedIndices.add(index);
|
|
763
855
|
report({
|
|
764
856
|
currentChunk: completed,
|
|
765
857
|
totalChunks,
|
|
@@ -770,16 +862,36 @@ async function synthesizeSsmlChunks(chunks, config) {
|
|
|
770
862
|
durationMs: Date.now() - startedAt,
|
|
771
863
|
error
|
|
772
864
|
});
|
|
773
|
-
|
|
865
|
+
firstError ?? (firstError = scope.timedOut() ? new SynthesisTimeoutError(`Speech synthesis timed out after ${config.timeouts?.totalJobMs} ms.`) : error);
|
|
866
|
+
if (config.cancelOnFailure !== false) scope.abort();
|
|
867
|
+
return;
|
|
774
868
|
}
|
|
775
869
|
}
|
|
776
870
|
};
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
871
|
+
try {
|
|
872
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, chunks.length) }, () => worker()));
|
|
873
|
+
if (firstError) throw firstError;
|
|
874
|
+
const orderedResults = results.filter((result) => result !== void 0);
|
|
875
|
+
return await mergeSynthesisResults(orderedResults, {
|
|
876
|
+
format: config.outputFormat ?? DEFAULT_OUTPUT_FORMAT,
|
|
877
|
+
signal: scope.signal,
|
|
878
|
+
customMerger: config.customMerger,
|
|
879
|
+
outputMimeType: config.outputMimeType,
|
|
880
|
+
postMergeValidator: config.postMergeValidator
|
|
881
|
+
});
|
|
882
|
+
} catch (error) {
|
|
883
|
+
const partial = {
|
|
884
|
+
synthesizedChunks: results.flatMap((result, chunkIndex) => result ? [{ ...result, chunkIndex }] : []),
|
|
885
|
+
completedChunks: results.flatMap((result, chunkIndex) => result ? [{ ...result, chunkIndex }] : []),
|
|
886
|
+
pendingChunkIndices: chunks.flatMap((_chunk, chunkIndex) => results[chunkIndex] ? [] : [chunkIndex]),
|
|
887
|
+
failedChunkIndices: [...failedIndices],
|
|
888
|
+
totalChunks
|
|
889
|
+
};
|
|
890
|
+
if (error && typeof error === "object") error.partialResult = partial;
|
|
891
|
+
throw error;
|
|
892
|
+
} finally {
|
|
893
|
+
scope.dispose();
|
|
894
|
+
}
|
|
783
895
|
}
|
|
784
896
|
function createMergedResult(results, audioData, format, audioSpec, outputMimeType) {
|
|
785
897
|
const boundaries = [];
|
|
@@ -873,13 +985,24 @@ function mergeSynthesisResults(results, options) {
|
|
|
873
985
|
if (!(merged instanceof ArrayBuffer) || buffers.some((buffer) => buffer.byteLength > 0) && merged.byteLength === 0)
|
|
874
986
|
throw new MergeError("The custom audio merger returned an invalid audio buffer.");
|
|
875
987
|
if (signal.aborted) throw new SynthesisCancelledError();
|
|
876
|
-
|
|
988
|
+
const result = createMergedResult(
|
|
877
989
|
results,
|
|
878
990
|
merged,
|
|
879
991
|
format,
|
|
880
992
|
inspectAudioSpecification(merged, format),
|
|
881
993
|
resolvedOptions.outputMimeType
|
|
882
994
|
);
|
|
995
|
+
return Promise.resolve(
|
|
996
|
+
resolvedOptions.postMergeValidator?.(result, {
|
|
997
|
+
format,
|
|
998
|
+
outputMimeType: resolvedOptions.outputMimeType ?? resolveMimeType(format),
|
|
999
|
+
inputSpecs,
|
|
1000
|
+
signal
|
|
1001
|
+
})
|
|
1002
|
+
).then((valid) => {
|
|
1003
|
+
if (valid === false) throw new MergeError("The post-merge validator rejected the merged audio.");
|
|
1004
|
+
return result;
|
|
1005
|
+
});
|
|
883
1006
|
}).catch((error) => {
|
|
884
1007
|
if (error instanceof UnsupportedMergeFormatError || isAudioFormatMismatch(error) || error instanceof MergeError)
|
|
885
1008
|
throw error;
|
|
@@ -887,13 +1010,28 @@ function mergeSynthesisResults(results, options) {
|
|
|
887
1010
|
});
|
|
888
1011
|
}
|
|
889
1012
|
try {
|
|
890
|
-
|
|
1013
|
+
const result = createMergedResult(
|
|
891
1014
|
results,
|
|
892
1015
|
mergeAudioBuffers(buffers, { format }),
|
|
893
1016
|
format,
|
|
894
1017
|
inputSpecs[0],
|
|
895
1018
|
resolvedOptions.outputMimeType
|
|
896
1019
|
);
|
|
1020
|
+
if (resolvedOptions.postMergeValidator) {
|
|
1021
|
+
const validation = resolvedOptions.postMergeValidator(result, {
|
|
1022
|
+
format,
|
|
1023
|
+
outputMimeType: resolvedOptions.outputMimeType ?? resolveMimeType(format),
|
|
1024
|
+
inputSpecs,
|
|
1025
|
+
signal
|
|
1026
|
+
});
|
|
1027
|
+
if (validation instanceof Promise)
|
|
1028
|
+
return validation.then((valid) => {
|
|
1029
|
+
if (valid === false) throw new MergeError("The post-merge validator rejected the merged audio.");
|
|
1030
|
+
return result;
|
|
1031
|
+
});
|
|
1032
|
+
if (validation === false) throw new MergeError("The post-merge validator rejected the merged audio.");
|
|
1033
|
+
}
|
|
1034
|
+
return result;
|
|
897
1035
|
} catch (error) {
|
|
898
1036
|
if (error instanceof UnsupportedMergeFormatError || isAudioFormatMismatch(error) || error instanceof MergeError)
|
|
899
1037
|
throw error;
|
|
@@ -914,8 +1052,52 @@ var ChunkValidationError = class extends Error {
|
|
|
914
1052
|
this.diagnostics = diagnostics;
|
|
915
1053
|
}
|
|
916
1054
|
};
|
|
917
|
-
|
|
918
|
-
|
|
1055
|
+
var BatchChunkValidationError = class extends ChunkValidationError {
|
|
1056
|
+
constructor(chunkDiagnostics) {
|
|
1057
|
+
const first = chunkDiagnostics[0];
|
|
1058
|
+
super(first?.chunkIndex ?? -1, first?.diagnostics ?? []);
|
|
1059
|
+
this.name = "BatchChunkValidationError";
|
|
1060
|
+
this.message = `SSML validation failed for ${chunkDiagnostics.length} chunk(s); the Azure Speech API was not called.`;
|
|
1061
|
+
this.chunkDiagnostics = chunkDiagnostics;
|
|
1062
|
+
this.totalErrorCount = chunkDiagnostics.reduce((total, chunk) => total + chunk.diagnostics.length, 0);
|
|
1063
|
+
this.errorCount = this.totalErrorCount;
|
|
1064
|
+
this.totalErrors = this.totalErrorCount;
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
function failure(error, partialResult) {
|
|
1068
|
+
return {
|
|
1069
|
+
ok: false,
|
|
1070
|
+
success: false,
|
|
1071
|
+
status: error.kind,
|
|
1072
|
+
error,
|
|
1073
|
+
...partialResult ? { partialResult } : {}
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
function partialResultFrom(error) {
|
|
1077
|
+
if (!error || typeof error !== "object") return void 0;
|
|
1078
|
+
const partial = error.partialResult;
|
|
1079
|
+
if (!partial || typeof partial !== "object") return void 0;
|
|
1080
|
+
return partial;
|
|
1081
|
+
}
|
|
1082
|
+
function createSafeAbortScope(parent, timeoutMs) {
|
|
1083
|
+
const controller = new AbortController();
|
|
1084
|
+
let didTimeout = false;
|
|
1085
|
+
const onAbort = () => controller.abort();
|
|
1086
|
+
if (parent?.aborted) controller.abort();
|
|
1087
|
+
parent?.addEventListener("abort", onAbort, { once: true });
|
|
1088
|
+
const timer = timeoutMs !== void 0 && timeoutMs > 0 ? setTimeout(() => {
|
|
1089
|
+
didTimeout = true;
|
|
1090
|
+
controller.abort();
|
|
1091
|
+
}, timeoutMs) : void 0;
|
|
1092
|
+
return {
|
|
1093
|
+
signal: controller.signal,
|
|
1094
|
+
timedOut: () => didTimeout,
|
|
1095
|
+
dispose: () => {
|
|
1096
|
+
if (timer) clearTimeout(timer);
|
|
1097
|
+
parent?.removeEventListener("abort", onAbort);
|
|
1098
|
+
},
|
|
1099
|
+
abort: () => controller.abort()
|
|
1100
|
+
};
|
|
919
1101
|
}
|
|
920
1102
|
function isRetryable(error) {
|
|
921
1103
|
if (error instanceof Error && /cancel|abort|tim(?:e|ed) ?out/i.test(error.message)) return false;
|
|
@@ -930,6 +1112,9 @@ function delayForRetry(options, attempt) {
|
|
|
930
1112
|
const base = Math.min(maxDelay, Math.max(0, options.initialDelayMs) * 2 ** Math.max(0, attempt - 1));
|
|
931
1113
|
return Math.floor(Math.random() * (base + 1));
|
|
932
1114
|
}
|
|
1115
|
+
function retryDelayForError(options, attempt, error) {
|
|
1116
|
+
return getRetryAfterDelayMs(error) ?? delayForRetry(options, attempt);
|
|
1117
|
+
}
|
|
933
1118
|
function resolveConcurrency2(value, total) {
|
|
934
1119
|
if (value === void 0) return 1;
|
|
935
1120
|
if (value === Infinity) return Math.max(1, total);
|
|
@@ -939,7 +1124,8 @@ async function retryableSynthesis(synthesize, options, signal, onRetry) {
|
|
|
939
1124
|
const retry = options ? {
|
|
940
1125
|
maxRetries: Math.max(0, Math.floor(options.maxRetries)),
|
|
941
1126
|
initialDelayMs: options.initialDelayMs,
|
|
942
|
-
maxDelayMs: options.maxDelayMs
|
|
1127
|
+
maxDelayMs: options.maxDelayMs,
|
|
1128
|
+
shouldRetry: options.shouldRetry
|
|
943
1129
|
} : void 0;
|
|
944
1130
|
let attempt = 0;
|
|
945
1131
|
while (true) {
|
|
@@ -947,9 +1133,10 @@ async function retryableSynthesis(synthesize, options, signal, onRetry) {
|
|
|
947
1133
|
try {
|
|
948
1134
|
return await synthesize();
|
|
949
1135
|
} catch (error) {
|
|
950
|
-
if (!retry || attempt >= retry.maxRetries || !
|
|
1136
|
+
if (!retry || attempt >= retry.maxRetries || !(retry.shouldRetry?.(error, attempt + 1) ?? isRetryable(error)))
|
|
1137
|
+
throw error;
|
|
951
1138
|
attempt += 1;
|
|
952
|
-
const delayMs =
|
|
1139
|
+
const delayMs = retryDelayForError(retry, attempt, error);
|
|
953
1140
|
onRetry(attempt, delayMs);
|
|
954
1141
|
if (delayMs > 0)
|
|
955
1142
|
await new Promise((resolve, reject) => {
|
|
@@ -973,7 +1160,7 @@ function sharedValidationOptions(options, signal) {
|
|
|
973
1160
|
const runner = createAzureUrlValidatorRunner2(validator, {
|
|
974
1161
|
...options.urlValidation ?? {},
|
|
975
1162
|
...options.urlValidatorConcurrency !== void 0 ? { concurrency: options.urlValidatorConcurrency } : {},
|
|
976
|
-
...options.urlValidatorTimeoutMs !== void 0 ? { timeoutMs: options.urlValidatorTimeoutMs } : {},
|
|
1163
|
+
...options.timeouts?.urlValidationMs !== void 0 ? { timeoutMs: options.timeouts.urlValidationMs } : options.urlValidatorTimeoutMs !== void 0 ? { timeoutMs: options.urlValidatorTimeoutMs } : {},
|
|
977
1164
|
...signal ? { signal } : {},
|
|
978
1165
|
...options.urlValidatorCache ? { cache: options.urlValidatorCache } : {}
|
|
979
1166
|
});
|
|
@@ -1002,7 +1189,11 @@ async function synthesizeSsmlSafe(client, ssml, options = {}) {
|
|
|
1002
1189
|
ok: true,
|
|
1003
1190
|
success: true,
|
|
1004
1191
|
status: "success",
|
|
1005
|
-
value: await client.synthesizeSsml(ssml, {
|
|
1192
|
+
value: await client.synthesizeSsml(ssml, {
|
|
1193
|
+
signal: options.signal,
|
|
1194
|
+
timeoutMs: options.timeouts?.perChunkMs,
|
|
1195
|
+
timeouts: options.timeouts
|
|
1196
|
+
})
|
|
1006
1197
|
};
|
|
1007
1198
|
} catch (error) {
|
|
1008
1199
|
const synthesisError = toSynthesisError(error);
|
|
@@ -1010,7 +1201,10 @@ async function synthesizeSsmlSafe(client, ssml, options = {}) {
|
|
|
1010
1201
|
}
|
|
1011
1202
|
}
|
|
1012
1203
|
async function synthesizeSsmlChunksSafe(client, chunks, options = {}) {
|
|
1013
|
-
const validationOptions = sharedValidationOptions(
|
|
1204
|
+
const validationOptions = sharedValidationOptions(
|
|
1205
|
+
{ ...options.validation ?? options, timeouts: options.timeouts },
|
|
1206
|
+
options.signal
|
|
1207
|
+
);
|
|
1014
1208
|
if (options.signal?.aborted) {
|
|
1015
1209
|
const error = toSynthesisError(new Error("Speech synthesis was cancelled."));
|
|
1016
1210
|
return failure(error);
|
|
@@ -1044,16 +1238,17 @@ async function synthesizeSsmlChunksSafe(client, chunks, options = {}) {
|
|
|
1044
1238
|
return diagnostics.filter((diagnostic) => diagnostic.severity === "error");
|
|
1045
1239
|
})
|
|
1046
1240
|
);
|
|
1047
|
-
const firstInvalidIndex = validations.findIndex((diagnostics) => diagnostics.length > 0);
|
|
1048
1241
|
if (options.signal?.aborted) {
|
|
1049
1242
|
const error = toSynthesisError(new Error("Speech synthesis was cancelled."));
|
|
1050
1243
|
return failure(error);
|
|
1051
1244
|
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1245
|
+
const chunkDiagnostics = validations.map((diagnostics, chunkIndex) => ({ chunkIndex, diagnostics })).filter((entry) => entry.diagnostics.length > 0);
|
|
1246
|
+
if (chunkDiagnostics.length > 0) {
|
|
1247
|
+
const error = new BatchChunkValidationError(chunkDiagnostics);
|
|
1248
|
+
for (const entry of chunkDiagnostics) pending(entry.chunkIndex, "failed", error);
|
|
1055
1249
|
return failure(error);
|
|
1056
1250
|
}
|
|
1251
|
+
let fallbackJobScope;
|
|
1057
1252
|
try {
|
|
1058
1253
|
if (client.synthesizeChunks) {
|
|
1059
1254
|
const normalizedChunks = chunks.map((chunk) => {
|
|
@@ -1065,20 +1260,39 @@ async function synthesizeSsmlChunksSafe(client, chunks, options = {}) {
|
|
|
1065
1260
|
outputFormat: options.outputFormat,
|
|
1066
1261
|
signal: options.signal,
|
|
1067
1262
|
timeoutMs: options.timeoutMs,
|
|
1263
|
+
timeouts: options.timeouts,
|
|
1068
1264
|
sourceNodePath: options.sourceNodePath,
|
|
1069
1265
|
concurrency: options.concurrency,
|
|
1070
|
-
retryOptions: options.retryOptions
|
|
1266
|
+
retryOptions: options.retryOptions,
|
|
1267
|
+
cancelOnFailure: options.cancelOnFailure,
|
|
1268
|
+
resumeChunks: options.resumeChunks,
|
|
1269
|
+
resumeChunkIndices: options.resumeChunkIndices,
|
|
1270
|
+
customMerger: options.customMerger,
|
|
1271
|
+
outputMimeType: options.outputMimeType,
|
|
1272
|
+
postMergeValidator: options.postMergeValidator
|
|
1071
1273
|
});
|
|
1072
1274
|
return { ok: true, success: true, status: "success", value };
|
|
1073
1275
|
}
|
|
1074
1276
|
const results = new Array(chunks.length);
|
|
1075
|
-
|
|
1277
|
+
const cachedChunks = new Map((options.resumeChunks ?? []).map((chunk) => [chunk.chunkIndex, chunk]));
|
|
1278
|
+
for (const [index, cached] of cachedChunks) {
|
|
1279
|
+
if (index >= 0 && index < chunks.length) results[index] = cached;
|
|
1280
|
+
}
|
|
1281
|
+
const requestedIndices = options.resumeChunkIndices ? new Set(options.resumeChunkIndices.filter((index) => index >= 0 && index < chunks.length)) : void 0;
|
|
1282
|
+
const shouldSynthesize = (index) => !cachedChunks.has(index) && (requestedIndices === void 0 || requestedIndices.has(index));
|
|
1283
|
+
const jobScope = chunks.length > 1 || options.timeouts?.totalJobMs !== void 0 ? createSafeAbortScope(options.signal, options.timeouts?.totalJobMs) : void 0;
|
|
1284
|
+
fallbackJobScope = jobScope;
|
|
1285
|
+
const failedIndices = /* @__PURE__ */ new Set();
|
|
1286
|
+
let firstError;
|
|
1287
|
+
let completed = [...results].filter((result) => result !== void 0).length;
|
|
1076
1288
|
let nextIndex = 0;
|
|
1077
1289
|
const concurrency = resolveConcurrency2(options.concurrency, chunks.length);
|
|
1078
1290
|
const worker = async () => {
|
|
1079
1291
|
while (true) {
|
|
1080
1292
|
const index = nextIndex++;
|
|
1081
1293
|
if (index >= chunks.length) return;
|
|
1294
|
+
if (!shouldSynthesize(index)) continue;
|
|
1295
|
+
if (failedIndices.size > 0 && options.cancelOnFailure !== false) return;
|
|
1082
1296
|
const chunk = chunks[index];
|
|
1083
1297
|
const input = typeof chunk === "string" ? { ssml: chunk } : chunk;
|
|
1084
1298
|
const sourceNodePath = input.sourceNodePath;
|
|
@@ -1086,28 +1300,40 @@ async function synthesizeSsmlChunksSafe(client, chunks, options = {}) {
|
|
|
1086
1300
|
pending(index, "synthesizing");
|
|
1087
1301
|
const startedAt = Date.now();
|
|
1088
1302
|
try {
|
|
1089
|
-
const
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1303
|
+
const chunkTimeout = options.timeouts?.chunkWithRetriesMs ?? options.timeouts?.perChunkMs;
|
|
1304
|
+
const chunkScope = chunkTimeout !== void 0 || jobScope ? createSafeAbortScope(jobScope?.signal ?? options.signal, chunkTimeout ?? options.timeoutMs) : void 0;
|
|
1305
|
+
const chunkSignal = chunkScope?.signal ?? options.signal;
|
|
1306
|
+
let result;
|
|
1307
|
+
try {
|
|
1308
|
+
result = await retryableSynthesis(
|
|
1309
|
+
() => client.synthesizeSsml(input.ssml, {
|
|
1310
|
+
outputFormat: options.outputFormat,
|
|
1311
|
+
signal: chunkSignal,
|
|
1312
|
+
timeoutMs: options.timeouts?.perChunkMs ?? options.timeoutMs,
|
|
1313
|
+
sourceNodePath: input.sourceNodePath ?? options.sourceNodePath
|
|
1314
|
+
}),
|
|
1315
|
+
options.retryOptions,
|
|
1316
|
+
chunkSignal,
|
|
1317
|
+
(retryAttempt, nextRetryDelayMs) => options.onProgress?.({
|
|
1318
|
+
currentChunk: completed,
|
|
1319
|
+
totalChunks: chunks.length,
|
|
1320
|
+
percent: chunks.length === 0 ? 100 : Math.round(completed / chunks.length * 100),
|
|
1321
|
+
chunkIndex: index,
|
|
1322
|
+
originalTextRange: input.originalTextRange,
|
|
1323
|
+
status: "synthesizing",
|
|
1324
|
+
durationMs: Date.now() - startedAt,
|
|
1325
|
+
retryAttempt,
|
|
1326
|
+
nextRetryDelayMs,
|
|
1327
|
+
isRetrying: true
|
|
1328
|
+
})
|
|
1329
|
+
);
|
|
1330
|
+
} catch (error) {
|
|
1331
|
+
if (chunkScope?.timedOut())
|
|
1332
|
+
throw new Error(`Speech synthesis timed out after ${chunkTimeout ?? options.timeoutMs} ms.`);
|
|
1333
|
+
throw error;
|
|
1334
|
+
} finally {
|
|
1335
|
+
chunkScope?.dispose();
|
|
1336
|
+
}
|
|
1111
1337
|
results[index] = {
|
|
1112
1338
|
...result,
|
|
1113
1339
|
...input.originalTextRange ? { textRange: { ...input.originalTextRange } } : {},
|
|
@@ -1162,6 +1388,7 @@ async function synthesizeSsmlChunksSafe(client, chunks, options = {}) {
|
|
|
1162
1388
|
durationMs: Date.now() - startedAt
|
|
1163
1389
|
});
|
|
1164
1390
|
} catch (error) {
|
|
1391
|
+
failedIndices.add(index);
|
|
1165
1392
|
options.onProgress?.({
|
|
1166
1393
|
currentChunk: completed,
|
|
1167
1394
|
totalChunks: chunks.length,
|
|
@@ -1172,24 +1399,42 @@ async function synthesizeSsmlChunksSafe(client, chunks, options = {}) {
|
|
|
1172
1399
|
durationMs: Date.now() - startedAt,
|
|
1173
1400
|
error
|
|
1174
1401
|
});
|
|
1175
|
-
|
|
1402
|
+
if (options.cancelOnFailure !== false) jobScope?.abort();
|
|
1403
|
+
firstError ?? (firstError = error);
|
|
1404
|
+
return;
|
|
1176
1405
|
}
|
|
1177
1406
|
}
|
|
1178
1407
|
};
|
|
1179
1408
|
await Promise.all(Array.from({ length: Math.min(concurrency, chunks.length) }, () => worker()));
|
|
1409
|
+
if (failedIndices.size > 0) {
|
|
1410
|
+
const error = firstError ?? new Error("One or more SSML chunks failed to synthesize.");
|
|
1411
|
+
error.partialResult = {
|
|
1412
|
+
synthesizedChunks: results.flatMap((result, chunkIndex) => result ? [{ ...result, chunkIndex }] : []),
|
|
1413
|
+
completedChunks: results.flatMap((result, chunkIndex) => result ? [{ ...result, chunkIndex }] : []),
|
|
1414
|
+
pendingChunkIndices: chunks.flatMap((_chunk, chunkIndex) => results[chunkIndex] ? [] : [chunkIndex]),
|
|
1415
|
+
failedChunkIndices: [...failedIndices],
|
|
1416
|
+
totalChunks: chunks.length
|
|
1417
|
+
};
|
|
1418
|
+
throw error;
|
|
1419
|
+
}
|
|
1180
1420
|
const orderedResults = results.filter((result) => result !== void 0);
|
|
1181
1421
|
return {
|
|
1182
1422
|
ok: true,
|
|
1183
1423
|
success: true,
|
|
1184
1424
|
status: "success",
|
|
1185
|
-
value: mergeSynthesisResults(orderedResults, {
|
|
1425
|
+
value: await mergeSynthesisResults(orderedResults, {
|
|
1186
1426
|
format: options.outputFormat ?? "audio-16khz-128kbitrate-mono-mp3",
|
|
1187
|
-
signal: options.signal
|
|
1427
|
+
signal: jobScope?.signal ?? options.signal,
|
|
1428
|
+
customMerger: options.customMerger,
|
|
1429
|
+
outputMimeType: options.outputMimeType,
|
|
1430
|
+
postMergeValidator: options.postMergeValidator
|
|
1188
1431
|
})
|
|
1189
1432
|
};
|
|
1190
1433
|
} catch (error) {
|
|
1191
1434
|
const synthesisError = toSynthesisError(error);
|
|
1192
|
-
return failure(synthesisError);
|
|
1435
|
+
return failure(synthesisError, partialResultFrom(error));
|
|
1436
|
+
} finally {
|
|
1437
|
+
fallbackJobScope?.dispose();
|
|
1193
1438
|
}
|
|
1194
1439
|
}
|
|
1195
1440
|
function withValidationSignal(options, signal) {
|
|
@@ -1210,14 +1455,14 @@ var AzureTtsClient = class {
|
|
|
1210
1455
|
__privateSet(this, _options, options);
|
|
1211
1456
|
}
|
|
1212
1457
|
async synthesize(ssml) {
|
|
1213
|
-
const { region, subscriptionKey, outputFormat, signal, timeoutMs } = __privateGet(this, _options);
|
|
1458
|
+
const { region, subscriptionKey, outputFormat, signal, timeoutMs, timeouts } = __privateGet(this, _options);
|
|
1214
1459
|
const endpoint = __privateGet(this, _options).endpoint?.trim() || ENDPOINT_TEMPLATE.replace("{region}", region);
|
|
1215
1460
|
__privateGet(this, _options).logger?.debug?.("Using Azure TTS endpoint:", endpoint);
|
|
1216
|
-
const config = { endpoint, region, subscriptionKey, outputFormat, signal, timeoutMs };
|
|
1461
|
+
const config = { endpoint, region, subscriptionKey, outputFormat, signal, timeoutMs, timeouts };
|
|
1217
1462
|
return synthesizeSpeech(ssml, config);
|
|
1218
1463
|
}
|
|
1219
1464
|
async synthesizeSsml(ssml, options = {}) {
|
|
1220
|
-
const { region, subscriptionKey, outputFormat, signal, timeoutMs } = __privateGet(this, _options);
|
|
1465
|
+
const { region, subscriptionKey, outputFormat, signal, timeoutMs, timeouts } = __privateGet(this, _options);
|
|
1221
1466
|
const endpoint = __privateGet(this, _options).endpoint?.trim() || ENDPOINT_TEMPLATE.replace("{region}", region);
|
|
1222
1467
|
__privateGet(this, _options).logger?.debug?.("Using Azure TTS endpoint:", endpoint);
|
|
1223
1468
|
return synthesizeSsml(ssml, {
|
|
@@ -1227,13 +1472,14 @@ var AzureTtsClient = class {
|
|
|
1227
1472
|
outputFormat: options.outputFormat ?? outputFormat,
|
|
1228
1473
|
signal: options.signal ?? signal,
|
|
1229
1474
|
timeoutMs: options.timeoutMs ?? timeoutMs,
|
|
1475
|
+
timeouts: options.timeouts ?? timeouts,
|
|
1230
1476
|
sourceNodePath: options.sourceNodePath,
|
|
1231
1477
|
sourceTextSegments: options.sourceTextSegments,
|
|
1232
1478
|
sourceMarkers: options.sourceMarkers
|
|
1233
1479
|
});
|
|
1234
1480
|
}
|
|
1235
1481
|
async synthesizeChunks(chunks, options = {}) {
|
|
1236
|
-
const { region, subscriptionKey, outputFormat, signal, timeoutMs } = __privateGet(this, _options);
|
|
1482
|
+
const { region, subscriptionKey, outputFormat, signal, timeoutMs, timeouts } = __privateGet(this, _options);
|
|
1237
1483
|
const endpoint = __privateGet(this, _options).endpoint?.trim() || ENDPOINT_TEMPLATE.replace("{region}", region);
|
|
1238
1484
|
return synthesizeSsmlChunks(chunks, {
|
|
1239
1485
|
endpoint,
|
|
@@ -1242,10 +1488,17 @@ var AzureTtsClient = class {
|
|
|
1242
1488
|
outputFormat: options.outputFormat ?? outputFormat,
|
|
1243
1489
|
signal: options.signal ?? signal,
|
|
1244
1490
|
timeoutMs: options.timeoutMs ?? timeoutMs,
|
|
1491
|
+
timeouts: options.timeouts ?? timeouts,
|
|
1245
1492
|
sourceNodePath: options.sourceNodePath,
|
|
1246
1493
|
onProgress: options.onProgress ?? __privateGet(this, _options).onProgress,
|
|
1247
1494
|
concurrency: options.concurrency ?? __privateGet(this, _options).concurrency,
|
|
1248
|
-
retryOptions: options.retryOptions ?? __privateGet(this, _options).retryOptions
|
|
1495
|
+
retryOptions: options.retryOptions ?? __privateGet(this, _options).retryOptions,
|
|
1496
|
+
cancelOnFailure: options.cancelOnFailure,
|
|
1497
|
+
resumeChunks: options.resumeChunks,
|
|
1498
|
+
resumeChunkIndices: options.resumeChunkIndices,
|
|
1499
|
+
customMerger: options.customMerger,
|
|
1500
|
+
outputMimeType: options.outputMimeType,
|
|
1501
|
+
postMergeValidator: options.postMergeValidator
|
|
1249
1502
|
});
|
|
1250
1503
|
}
|
|
1251
1504
|
async synthesizeSsmlSafe(ssml, options = {}) {
|
|
@@ -1257,6 +1510,7 @@ var AzureTtsClient = class {
|
|
|
1257
1510
|
outputFormat: options.outputFormat ?? __privateGet(this, _options).outputFormat,
|
|
1258
1511
|
signal: options.signal ?? __privateGet(this, _options).signal,
|
|
1259
1512
|
timeoutMs: options.timeoutMs ?? __privateGet(this, _options).timeoutMs,
|
|
1513
|
+
timeouts: options.timeouts ?? __privateGet(this, _options).timeouts,
|
|
1260
1514
|
onProgress: options.onProgress ?? __privateGet(this, _options).onProgress,
|
|
1261
1515
|
concurrency: options.concurrency ?? __privateGet(this, _options).concurrency,
|
|
1262
1516
|
retryOptions: options.retryOptions ?? __privateGet(this, _options).retryOptions
|
|
@@ -1350,7 +1604,9 @@ async function fetchAzureVoiceCatalog(options) {
|
|
|
1350
1604
|
voiceCount: sortedVoices.length,
|
|
1351
1605
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1352
1606
|
apiVersion: AZURE_VOICE_API_VERSION,
|
|
1353
|
-
regions
|
|
1607
|
+
regions,
|
|
1608
|
+
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
1609
|
+
regionDiffs: {}
|
|
1354
1610
|
}
|
|
1355
1611
|
};
|
|
1356
1612
|
}
|
|
@@ -1359,6 +1615,7 @@ export {
|
|
|
1359
1615
|
AzureTtsClient,
|
|
1360
1616
|
AzureTtsError,
|
|
1361
1617
|
AzureTtsSdkError,
|
|
1618
|
+
BatchChunkValidationError,
|
|
1362
1619
|
ChunkValidationError,
|
|
1363
1620
|
DEFAULT_OUTPUT_FORMAT,
|
|
1364
1621
|
MergeError,
|
|
@@ -1376,6 +1633,7 @@ export {
|
|
|
1376
1633
|
fromPlainTextToSsml,
|
|
1377
1634
|
getAzureVoiceCatalogMetadata,
|
|
1378
1635
|
getBuiltInVoiceCatalogMetadata,
|
|
1636
|
+
getRetryAfterDelayMs,
|
|
1379
1637
|
getSsmlSourceMap,
|
|
1380
1638
|
inspectAudioSpecification,
|
|
1381
1639
|
isValidAzureAudioDuration,
|