@creativeorange/azure-text-to-speech 3.0.0 → 3.0.1
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 +99 -140
- package/dist/SpeechToText.d.ts +27 -0
- package/dist/TextToSpeech.d.ts +79 -0
- package/dist/authentication.d.ts +44 -0
- package/dist/co-azure-tts.es.js +438 -234
- package/dist/co-azure-tts.umd.js +8 -8
- package/dist/main.d.ts +4 -0
- package/package.json +11 -7
- package/src/SpeechToText.ts +0 -172
- package/src/TextToSpeech.ts +0 -846
- package/src/authentication.ts +0 -228
- package/src/main.ts +0 -9
package/dist/co-azure-tts.es.js
CHANGED
|
@@ -4,6 +4,193 @@ var __publicField = (obj, key, value) => {
|
|
|
4
4
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
return value;
|
|
6
6
|
};
|
|
7
|
+
const DEFAULT_TOKEN_LIFETIME_MS = 8 * 60 * 1e3;
|
|
8
|
+
function createSpeechAuthorizationProvider(options) {
|
|
9
|
+
var _a;
|
|
10
|
+
const hasTokenEndpoint = typeof options.tokenEndpoint === "string" && options.tokenEndpoint.trim() !== "";
|
|
11
|
+
const hasProvider = typeof options.getAuthorizationToken === "function";
|
|
12
|
+
if (hasTokenEndpoint && hasProvider) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
"Provide either tokenEndpoint or getAuthorizationToken, not both."
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
if (!hasTokenEndpoint && !hasProvider) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
"A tokenEndpoint or getAuthorizationToken provider is required."
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (hasProvider) {
|
|
23
|
+
return options.getAuthorizationToken;
|
|
24
|
+
}
|
|
25
|
+
const tokenEndpoint = options.tokenEndpoint.trim();
|
|
26
|
+
const requestOptions = (_a = options.tokenRequestOptions) != null ? _a : {};
|
|
27
|
+
return async () => {
|
|
28
|
+
var _a2, _b, _c;
|
|
29
|
+
let response;
|
|
30
|
+
try {
|
|
31
|
+
response = await fetch(tokenEndpoint, {
|
|
32
|
+
method: "GET",
|
|
33
|
+
cache: (_a2 = requestOptions.cache) != null ? _a2 : "no-store",
|
|
34
|
+
credentials: (_b = requestOptions.credentials) != null ? _b : "same-origin",
|
|
35
|
+
headers: {
|
|
36
|
+
Accept: "application/json",
|
|
37
|
+
...(_c = requestOptions.headers) != null ? _c : {}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
} catch {
|
|
41
|
+
throw createSafeError(
|
|
42
|
+
"Could not reach the speech token endpoint.",
|
|
43
|
+
"TOKEN_ENDPOINT_UNREACHABLE"
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw createSafeError(
|
|
48
|
+
`Speech token endpoint returned HTTP ${response.status}.`,
|
|
49
|
+
"TOKEN_ENDPOINT_HTTP_ERROR"
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
let payload;
|
|
53
|
+
try {
|
|
54
|
+
payload = await response.json();
|
|
55
|
+
} catch {
|
|
56
|
+
throw createSafeError(
|
|
57
|
+
"Speech token endpoint returned invalid JSON.",
|
|
58
|
+
"TOKEN_ENDPOINT_INVALID_JSON"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return validateSpeechAuthorization(payload);
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function validateSpeechAuthorization(value) {
|
|
65
|
+
if (!value || typeof value !== "object") {
|
|
66
|
+
throw createSafeError(
|
|
67
|
+
"Speech authorization response must be an object.",
|
|
68
|
+
"TOKEN_INVALID_RESPONSE"
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
const candidate = value;
|
|
72
|
+
const token = typeof candidate.token === "string" ? candidate.token.trim() : "";
|
|
73
|
+
const region = typeof candidate.region === "string" ? candidate.region.trim() : "";
|
|
74
|
+
if (token === "") {
|
|
75
|
+
throw createSafeError(
|
|
76
|
+
"Speech authorization token is missing or empty.",
|
|
77
|
+
"TOKEN_EMPTY"
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
if (region === "") {
|
|
81
|
+
throw createSafeError(
|
|
82
|
+
"Speech authorization region is missing or empty.",
|
|
83
|
+
"TOKEN_REGION_MISSING"
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
return { token, region };
|
|
87
|
+
}
|
|
88
|
+
function createSafeError(message, code) {
|
|
89
|
+
const error = new Error(sanitizeErrorText(message));
|
|
90
|
+
error.message = sanitizeErrorText(message);
|
|
91
|
+
if (code) {
|
|
92
|
+
error.code = code;
|
|
93
|
+
}
|
|
94
|
+
return error;
|
|
95
|
+
}
|
|
96
|
+
function toSafeErrorDetail(error) {
|
|
97
|
+
if (typeof error === "string") {
|
|
98
|
+
const message = error.trim() !== "" ? sanitizeErrorText(error) : "An unexpected speech error occurred.";
|
|
99
|
+
return { message };
|
|
100
|
+
}
|
|
101
|
+
if (error && typeof error === "object") {
|
|
102
|
+
const candidate = error;
|
|
103
|
+
const rawMessage = [
|
|
104
|
+
typeof candidate.message === "string" ? candidate.message : "",
|
|
105
|
+
typeof candidate.errorDetails === "string" ? candidate.errorDetails : "",
|
|
106
|
+
typeof candidate.reason === "string" ? candidate.reason : ""
|
|
107
|
+
].filter((part) => part.trim() !== "").join(" ");
|
|
108
|
+
const message = rawMessage !== "" ? sanitizeErrorText(rawMessage) : "An unexpected speech error occurred.";
|
|
109
|
+
const detail = { message };
|
|
110
|
+
if (typeof candidate.code === "string" && candidate.code.trim() !== "") {
|
|
111
|
+
detail.code = candidate.code;
|
|
112
|
+
} else if (typeof candidate.code === "number") {
|
|
113
|
+
detail.code = String(candidate.code);
|
|
114
|
+
}
|
|
115
|
+
return detail;
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
message: "An unexpected speech error occurred."
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function sanitizeErrorText(message) {
|
|
122
|
+
return message.replace(/Authorization\s*:\s*Bearer\s+\S+/gi, "Authorization: Bearer [redacted]").replace(/Bearer\s+\S+/gi, "Bearer [redacted]").replace(
|
|
123
|
+
/authorization[_-]?token["']?\s*[:=]\s*["']?[^"',\s}]+/gi,
|
|
124
|
+
"authorizationToken=[redacted]"
|
|
125
|
+
).replace(
|
|
126
|
+
/access[_-]?token["']?\s*[:=]\s*["']?[^"',\s}]+/gi,
|
|
127
|
+
"accessToken=[redacted]"
|
|
128
|
+
).replace(
|
|
129
|
+
/["']token["']\s*:\s*["'][^"']+["']/gi,
|
|
130
|
+
'"token":"[redacted]"'
|
|
131
|
+
).replace(
|
|
132
|
+
/token["']?\s*[:=]\s*["']?[^"',\s}]+/gi,
|
|
133
|
+
"token=[redacted]"
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
function isLikelyAuthorizationError(error) {
|
|
137
|
+
var _a;
|
|
138
|
+
const detail = toSafeErrorDetail(error);
|
|
139
|
+
const haystack = `${detail.message} ${(_a = detail.code) != null ? _a : ""}`.toLowerCase();
|
|
140
|
+
return haystack.includes("unauthorized") || haystack.includes("authentication") || haystack.includes("authorization") || haystack.includes("invalid token") || haystack.includes("token expired") || haystack.includes("expired token") || haystack.includes("403") || haystack.includes("401") || detail.code === "TOKEN_REFRESH_ERROR";
|
|
141
|
+
}
|
|
142
|
+
class SpeechAuthorizationManager {
|
|
143
|
+
constructor(options) {
|
|
144
|
+
__publicField(this, "authorization");
|
|
145
|
+
__publicField(this, "authorizationExpiresAt", 0);
|
|
146
|
+
__publicField(this, "authorizationRequest");
|
|
147
|
+
__publicField(this, "provider");
|
|
148
|
+
__publicField(this, "tokenLifetimeMs");
|
|
149
|
+
this.provider = createSpeechAuthorizationProvider(options);
|
|
150
|
+
this.tokenLifetimeMs = options.tokenLifetimeMs && options.tokenLifetimeMs > 0 ? options.tokenLifetimeMs : DEFAULT_TOKEN_LIFETIME_MS;
|
|
151
|
+
}
|
|
152
|
+
getTokenLifetimeMs() {
|
|
153
|
+
return this.tokenLifetimeMs;
|
|
154
|
+
}
|
|
155
|
+
async getAuthorization() {
|
|
156
|
+
if (this.authorization && Date.now() < this.authorizationExpiresAt) {
|
|
157
|
+
return this.authorization;
|
|
158
|
+
}
|
|
159
|
+
if (this.authorizationRequest) {
|
|
160
|
+
return this.authorizationRequest;
|
|
161
|
+
}
|
|
162
|
+
this.authorizationRequest = this.fetchAuthorization().then((authorization) => {
|
|
163
|
+
this.authorization = authorization;
|
|
164
|
+
this.authorizationExpiresAt = Date.now() + this.tokenLifetimeMs;
|
|
165
|
+
return authorization;
|
|
166
|
+
}).finally(() => {
|
|
167
|
+
this.authorizationRequest = void 0;
|
|
168
|
+
});
|
|
169
|
+
return this.authorizationRequest;
|
|
170
|
+
}
|
|
171
|
+
async refreshAuthorization() {
|
|
172
|
+
this.authorization = void 0;
|
|
173
|
+
this.authorizationExpiresAt = 0;
|
|
174
|
+
if (this.authorizationRequest) {
|
|
175
|
+
return this.authorizationRequest;
|
|
176
|
+
}
|
|
177
|
+
return this.getAuthorization();
|
|
178
|
+
}
|
|
179
|
+
clearAuthorization() {
|
|
180
|
+
this.authorization = void 0;
|
|
181
|
+
this.authorizationExpiresAt = 0;
|
|
182
|
+
}
|
|
183
|
+
async fetchAuthorization() {
|
|
184
|
+
try {
|
|
185
|
+
const authorization = await this.provider();
|
|
186
|
+
return validateSpeechAuthorization(authorization);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
this.clearAuthorization();
|
|
189
|
+
const detail = toSafeErrorDetail(error);
|
|
190
|
+
throw createSafeError(detail.message, detail.code);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
7
194
|
var ws = {};
|
|
8
195
|
var getRandomValues;
|
|
9
196
|
var rnds8 = new Uint8Array(16);
|
|
@@ -1079,7 +1266,7 @@ class Timeout {
|
|
|
1079
1266
|
throw new Error(message);
|
|
1080
1267
|
}
|
|
1081
1268
|
});
|
|
1082
|
-
const
|
|
1269
|
+
const clearTimeout2 = (timerId) => {
|
|
1083
1270
|
const id = Math.random();
|
|
1084
1271
|
unhandledRequests.set(id, timerId);
|
|
1085
1272
|
scheduledTimeoutFunctions.set(timerId, id);
|
|
@@ -1104,7 +1291,7 @@ class Timeout {
|
|
|
1104
1291
|
return timerId;
|
|
1105
1292
|
};
|
|
1106
1293
|
return {
|
|
1107
|
-
clearTimeout,
|
|
1294
|
+
clearTimeout: clearTimeout2,
|
|
1108
1295
|
setTimeout: setTimeout2
|
|
1109
1296
|
};
|
|
1110
1297
|
}
|
|
@@ -8350,170 +8537,24 @@ class RestMessageAdapter {
|
|
|
8350
8537
|
return Object.keys(params).map((k) => encodeURIComponent(k) + "=" + encodeURIComponent(params[k])).join("&");
|
|
8351
8538
|
}
|
|
8352
8539
|
}
|
|
8353
|
-
const DEFAULT_TOKEN_LIFETIME_MS = 8 * 60 * 1e3;
|
|
8354
|
-
function createSpeechAuthorizationProvider(options) {
|
|
8355
|
-
var _a;
|
|
8356
|
-
const hasTokenEndpoint = typeof options.tokenEndpoint === "string" && options.tokenEndpoint.trim() !== "";
|
|
8357
|
-
const hasProvider = typeof options.getAuthorizationToken === "function";
|
|
8358
|
-
if (hasTokenEndpoint && hasProvider) {
|
|
8359
|
-
throw new Error(
|
|
8360
|
-
"Provide either tokenEndpoint or getAuthorizationToken, not both."
|
|
8361
|
-
);
|
|
8362
|
-
}
|
|
8363
|
-
if (!hasTokenEndpoint && !hasProvider) {
|
|
8364
|
-
throw new Error(
|
|
8365
|
-
"A tokenEndpoint or getAuthorizationToken provider is required."
|
|
8366
|
-
);
|
|
8367
|
-
}
|
|
8368
|
-
if (hasProvider) {
|
|
8369
|
-
return options.getAuthorizationToken;
|
|
8370
|
-
}
|
|
8371
|
-
const tokenEndpoint = options.tokenEndpoint.trim();
|
|
8372
|
-
const requestOptions = (_a = options.tokenRequestOptions) != null ? _a : {};
|
|
8373
|
-
return async () => {
|
|
8374
|
-
var _a2, _b;
|
|
8375
|
-
let response;
|
|
8376
|
-
try {
|
|
8377
|
-
response = await fetch(tokenEndpoint, {
|
|
8378
|
-
method: "GET",
|
|
8379
|
-
credentials: (_a2 = requestOptions.credentials) != null ? _a2 : "same-origin",
|
|
8380
|
-
headers: {
|
|
8381
|
-
Accept: "application/json",
|
|
8382
|
-
...(_b = requestOptions.headers) != null ? _b : {}
|
|
8383
|
-
}
|
|
8384
|
-
});
|
|
8385
|
-
} catch {
|
|
8386
|
-
throw createSafeError(
|
|
8387
|
-
"Could not reach the speech token endpoint.",
|
|
8388
|
-
"TOKEN_ENDPOINT_UNREACHABLE"
|
|
8389
|
-
);
|
|
8390
|
-
}
|
|
8391
|
-
if (!response.ok) {
|
|
8392
|
-
throw createSafeError(
|
|
8393
|
-
`Speech token endpoint returned HTTP ${response.status}.`,
|
|
8394
|
-
"TOKEN_ENDPOINT_HTTP_ERROR"
|
|
8395
|
-
);
|
|
8396
|
-
}
|
|
8397
|
-
let payload;
|
|
8398
|
-
try {
|
|
8399
|
-
payload = await response.json();
|
|
8400
|
-
} catch {
|
|
8401
|
-
throw createSafeError(
|
|
8402
|
-
"Speech token endpoint returned invalid JSON.",
|
|
8403
|
-
"TOKEN_ENDPOINT_INVALID_JSON"
|
|
8404
|
-
);
|
|
8405
|
-
}
|
|
8406
|
-
return validateSpeechAuthorization(payload);
|
|
8407
|
-
};
|
|
8408
|
-
}
|
|
8409
|
-
function validateSpeechAuthorization(value) {
|
|
8410
|
-
if (!value || typeof value !== "object") {
|
|
8411
|
-
throw createSafeError(
|
|
8412
|
-
"Speech authorization response must be an object.",
|
|
8413
|
-
"TOKEN_INVALID_RESPONSE"
|
|
8414
|
-
);
|
|
8415
|
-
}
|
|
8416
|
-
const candidate = value;
|
|
8417
|
-
const token = typeof candidate.token === "string" ? candidate.token.trim() : "";
|
|
8418
|
-
const region = typeof candidate.region === "string" ? candidate.region.trim() : "";
|
|
8419
|
-
if (token === "") {
|
|
8420
|
-
throw createSafeError(
|
|
8421
|
-
"Speech authorization token is missing or empty.",
|
|
8422
|
-
"TOKEN_EMPTY"
|
|
8423
|
-
);
|
|
8424
|
-
}
|
|
8425
|
-
if (region === "") {
|
|
8426
|
-
throw createSafeError(
|
|
8427
|
-
"Speech authorization region is missing or empty.",
|
|
8428
|
-
"TOKEN_REGION_MISSING"
|
|
8429
|
-
);
|
|
8430
|
-
}
|
|
8431
|
-
return { token, region };
|
|
8432
|
-
}
|
|
8433
|
-
function createSafeError(message, code) {
|
|
8434
|
-
const error = new Error(message);
|
|
8435
|
-
error.message = message;
|
|
8436
|
-
if (code) {
|
|
8437
|
-
error.code = code;
|
|
8438
|
-
}
|
|
8439
|
-
return error;
|
|
8440
|
-
}
|
|
8441
|
-
function toSafeErrorDetail(error) {
|
|
8442
|
-
if (error && typeof error === "object") {
|
|
8443
|
-
const candidate = error;
|
|
8444
|
-
const message = typeof candidate.message === "string" && candidate.message.trim() !== "" ? sanitizeErrorText(candidate.message) : "An unexpected speech error occurred.";
|
|
8445
|
-
const detail = { message };
|
|
8446
|
-
if (typeof candidate.code === "string" && candidate.code.trim() !== "") {
|
|
8447
|
-
detail.code = candidate.code;
|
|
8448
|
-
}
|
|
8449
|
-
return detail;
|
|
8450
|
-
}
|
|
8451
|
-
return {
|
|
8452
|
-
message: "An unexpected speech error occurred."
|
|
8453
|
-
};
|
|
8454
|
-
}
|
|
8455
|
-
function sanitizeErrorText(message) {
|
|
8456
|
-
return message.replace(/Bearer\s+\S+/gi, "Bearer [redacted]").replace(/token["']?\s*[:=]\s*["']?[^"',\s}]+/gi, "token=[redacted]");
|
|
8457
|
-
}
|
|
8458
|
-
class SpeechAuthorizationManager {
|
|
8459
|
-
constructor(options) {
|
|
8460
|
-
__publicField(this, "authorization");
|
|
8461
|
-
__publicField(this, "authorizationExpiresAt", 0);
|
|
8462
|
-
__publicField(this, "authorizationRequest");
|
|
8463
|
-
__publicField(this, "provider");
|
|
8464
|
-
__publicField(this, "tokenLifetimeMs");
|
|
8465
|
-
this.provider = createSpeechAuthorizationProvider(options);
|
|
8466
|
-
this.tokenLifetimeMs = options.tokenLifetimeMs && options.tokenLifetimeMs > 0 ? options.tokenLifetimeMs : DEFAULT_TOKEN_LIFETIME_MS;
|
|
8467
|
-
}
|
|
8468
|
-
async getAuthorization() {
|
|
8469
|
-
if (this.authorization && Date.now() < this.authorizationExpiresAt) {
|
|
8470
|
-
return this.authorization;
|
|
8471
|
-
}
|
|
8472
|
-
if (this.authorizationRequest) {
|
|
8473
|
-
return this.authorizationRequest;
|
|
8474
|
-
}
|
|
8475
|
-
this.authorizationRequest = this.fetchAuthorization().then((authorization) => {
|
|
8476
|
-
this.authorization = authorization;
|
|
8477
|
-
this.authorizationExpiresAt = Date.now() + this.tokenLifetimeMs;
|
|
8478
|
-
return authorization;
|
|
8479
|
-
}).finally(() => {
|
|
8480
|
-
this.authorizationRequest = void 0;
|
|
8481
|
-
});
|
|
8482
|
-
return this.authorizationRequest;
|
|
8483
|
-
}
|
|
8484
|
-
clearAuthorization() {
|
|
8485
|
-
this.authorization = void 0;
|
|
8486
|
-
this.authorizationExpiresAt = 0;
|
|
8487
|
-
this.authorizationRequest = void 0;
|
|
8488
|
-
}
|
|
8489
|
-
async fetchAuthorization() {
|
|
8490
|
-
try {
|
|
8491
|
-
const authorization = await this.provider();
|
|
8492
|
-
return validateSpeechAuthorization(authorization);
|
|
8493
|
-
} catch (error) {
|
|
8494
|
-
this.clearAuthorization();
|
|
8495
|
-
throw createSafeError(
|
|
8496
|
-
toSafeErrorDetail(error).message,
|
|
8497
|
-
error == null ? void 0 : error.code
|
|
8498
|
-
);
|
|
8499
|
-
}
|
|
8500
|
-
}
|
|
8501
|
-
}
|
|
8502
8540
|
class SpeechToText {
|
|
8503
8541
|
constructor(options) {
|
|
8504
|
-
__publicField(this, "region");
|
|
8542
|
+
__publicField(this, "region", "");
|
|
8505
8543
|
__publicField(this, "sourceLanguage");
|
|
8506
8544
|
__publicField(this, "targetLanguage");
|
|
8507
8545
|
__publicField(this, "recognizer");
|
|
8508
8546
|
__publicField(this, "authorizationManager");
|
|
8509
|
-
|
|
8547
|
+
__publicField(this, "authorizationRefreshIntervalMs");
|
|
8548
|
+
__publicField(this, "authorizationRefreshTimer");
|
|
8549
|
+
__publicField(this, "stopPromise");
|
|
8550
|
+
var _a;
|
|
8510
8551
|
if (!options || typeof options.sourceLanguage !== "string" || options.sourceLanguage.trim() === "") {
|
|
8511
8552
|
throw new Error("A sourceLanguage is required.");
|
|
8512
8553
|
}
|
|
8513
8554
|
this.authorizationManager = new SpeechAuthorizationManager(options);
|
|
8514
|
-
this.
|
|
8555
|
+
this.authorizationRefreshIntervalMs = options.tokenLifetimeMs && options.tokenLifetimeMs > 0 ? options.tokenLifetimeMs : DEFAULT_TOKEN_LIFETIME_MS;
|
|
8515
8556
|
this.sourceLanguage = options.sourceLanguage;
|
|
8516
|
-
this.targetLanguage = (
|
|
8557
|
+
this.targetLanguage = (_a = options.targetLanguage) != null ? _a : options.sourceLanguage;
|
|
8517
8558
|
}
|
|
8518
8559
|
async start() {
|
|
8519
8560
|
await this.registerBindings(document);
|
|
@@ -8527,9 +8568,15 @@ class SpeechToText {
|
|
|
8527
8568
|
const currentNode = nodes[i];
|
|
8528
8569
|
if (currentNode.attributes) {
|
|
8529
8570
|
if (currentNode.attributes.getNamedItem("co-stt.start")) {
|
|
8530
|
-
await this.handleStartModifier(
|
|
8571
|
+
await this.handleStartModifier(
|
|
8572
|
+
currentNode,
|
|
8573
|
+
currentNode.attributes.getNamedItem("co-stt.start")
|
|
8574
|
+
);
|
|
8531
8575
|
} else if (currentNode.attributes.getNamedItem("co-stt.stop")) {
|
|
8532
|
-
await this.handleStopModifier(
|
|
8576
|
+
await this.handleStopModifier(
|
|
8577
|
+
currentNode,
|
|
8578
|
+
currentNode.attributes.getNamedItem("co-stt.stop")
|
|
8579
|
+
);
|
|
8533
8580
|
}
|
|
8534
8581
|
}
|
|
8535
8582
|
if (currentNode.childNodes.length > 0) {
|
|
@@ -8553,12 +8600,13 @@ class SpeechToText {
|
|
|
8553
8600
|
async handleStartModifier(node, attr) {
|
|
8554
8601
|
node.addEventListener("click", async (_) => {
|
|
8555
8602
|
try {
|
|
8603
|
+
await this.stop();
|
|
8556
8604
|
const speechConfig = await this.createSpeechTranslationConfig();
|
|
8557
8605
|
const audioConfig = AudioConfig.fromDefaultMicrophoneInput();
|
|
8558
8606
|
this.recognizer = new TranslationRecognizer(speechConfig, audioConfig);
|
|
8559
8607
|
document.dispatchEvent(new CustomEvent("COAzureSTTStartedRecording", {}));
|
|
8560
|
-
const prevResults =
|
|
8561
|
-
this.recognizer.recognizing = (
|
|
8608
|
+
const prevResults = {};
|
|
8609
|
+
this.recognizer.recognizing = (_sender, event) => {
|
|
8562
8610
|
const result = event.result;
|
|
8563
8611
|
if (result && result.reason === ResultReason.TranslatingSpeech) {
|
|
8564
8612
|
const translation = result.translations.get(this.targetLanguage);
|
|
@@ -8576,36 +8624,105 @@ class SpeechToText {
|
|
|
8576
8624
|
};
|
|
8577
8625
|
this.recognizer.startContinuousRecognitionAsync(
|
|
8578
8626
|
() => {
|
|
8627
|
+
this.scheduleAuthorizationRefresh();
|
|
8579
8628
|
},
|
|
8580
8629
|
(err) => {
|
|
8630
|
+
if (isLikelyAuthorizationError(err)) {
|
|
8631
|
+
this.authorizationManager.clearAuthorization();
|
|
8632
|
+
}
|
|
8581
8633
|
this.dispatchError(err, "RECOGNITION_ERROR");
|
|
8582
|
-
this.stop();
|
|
8634
|
+
void this.stop();
|
|
8583
8635
|
}
|
|
8584
8636
|
);
|
|
8585
8637
|
} catch (error) {
|
|
8638
|
+
this.clearAuthorizationRefreshTimer();
|
|
8639
|
+
if (isLikelyAuthorizationError(error)) {
|
|
8640
|
+
this.authorizationManager.clearAuthorization();
|
|
8641
|
+
}
|
|
8586
8642
|
this.dispatchError(error);
|
|
8587
8643
|
await this.stop();
|
|
8588
8644
|
}
|
|
8589
8645
|
});
|
|
8590
8646
|
}
|
|
8591
|
-
async handleStopModifier(node,
|
|
8647
|
+
async handleStopModifier(node, _attr) {
|
|
8592
8648
|
node.addEventListener("click", async (_) => {
|
|
8593
8649
|
await this.stop();
|
|
8594
8650
|
});
|
|
8595
8651
|
}
|
|
8596
8652
|
async stop() {
|
|
8597
|
-
if (this.
|
|
8653
|
+
if (this.stopPromise) {
|
|
8654
|
+
return this.stopPromise;
|
|
8655
|
+
}
|
|
8656
|
+
this.clearAuthorizationRefreshTimer();
|
|
8657
|
+
const recognizer = this.recognizer;
|
|
8658
|
+
if (!recognizer) {
|
|
8659
|
+
return;
|
|
8660
|
+
}
|
|
8661
|
+
this.recognizer = void 0;
|
|
8662
|
+
this.stopPromise = this.stopRecognizer(recognizer).finally(() => {
|
|
8663
|
+
this.stopPromise = void 0;
|
|
8664
|
+
document.dispatchEvent(
|
|
8665
|
+
new CustomEvent("COAzureSTTStoppedRecording", {})
|
|
8666
|
+
);
|
|
8667
|
+
});
|
|
8668
|
+
return this.stopPromise;
|
|
8669
|
+
}
|
|
8670
|
+
scheduleAuthorizationRefresh() {
|
|
8671
|
+
this.clearAuthorizationRefreshTimer();
|
|
8672
|
+
this.authorizationRefreshTimer = setTimeout(async () => {
|
|
8673
|
+
if (!this.recognizer) {
|
|
8674
|
+
return;
|
|
8675
|
+
}
|
|
8598
8676
|
try {
|
|
8599
|
-
this.
|
|
8600
|
-
|
|
8677
|
+
const authorization = await this.authorizationManager.refreshAuthorization();
|
|
8678
|
+
if (!this.recognizer) {
|
|
8679
|
+
return;
|
|
8680
|
+
}
|
|
8681
|
+
this.recognizer.authorizationToken = authorization.token;
|
|
8682
|
+
this.region = authorization.region;
|
|
8683
|
+
this.scheduleAuthorizationRefresh();
|
|
8684
|
+
} catch (error) {
|
|
8685
|
+
this.dispatchError(error, "TOKEN_REFRESH_ERROR");
|
|
8686
|
+
await this.stop();
|
|
8601
8687
|
}
|
|
8688
|
+
}, this.authorizationRefreshIntervalMs);
|
|
8689
|
+
}
|
|
8690
|
+
clearAuthorizationRefreshTimer() {
|
|
8691
|
+
if (!this.authorizationRefreshTimer) {
|
|
8692
|
+
return;
|
|
8693
|
+
}
|
|
8694
|
+
clearTimeout(this.authorizationRefreshTimer);
|
|
8695
|
+
this.authorizationRefreshTimer = void 0;
|
|
8696
|
+
}
|
|
8697
|
+
stopRecognizer(recognizer) {
|
|
8698
|
+
return new Promise((resolve) => {
|
|
8699
|
+
let closed = false;
|
|
8700
|
+
const closeOnce = () => {
|
|
8701
|
+
if (closed) {
|
|
8702
|
+
resolve();
|
|
8703
|
+
return;
|
|
8704
|
+
}
|
|
8705
|
+
closed = true;
|
|
8706
|
+
try {
|
|
8707
|
+
recognizer.close();
|
|
8708
|
+
} catch {
|
|
8709
|
+
} finally {
|
|
8710
|
+
resolve();
|
|
8711
|
+
}
|
|
8712
|
+
};
|
|
8602
8713
|
try {
|
|
8603
|
-
|
|
8714
|
+
recognizer.stopContinuousRecognitionAsync(
|
|
8715
|
+
() => {
|
|
8716
|
+
closeOnce();
|
|
8717
|
+
},
|
|
8718
|
+
() => {
|
|
8719
|
+
closeOnce();
|
|
8720
|
+
}
|
|
8721
|
+
);
|
|
8604
8722
|
} catch {
|
|
8723
|
+
closeOnce();
|
|
8605
8724
|
}
|
|
8606
|
-
|
|
8607
|
-
}
|
|
8608
|
-
document.dispatchEvent(new CustomEvent("COAzureSTTStoppedRecording", {}));
|
|
8725
|
+
});
|
|
8609
8726
|
}
|
|
8610
8727
|
dispatchError(error, code) {
|
|
8611
8728
|
const detail = toSafeErrorDetail(error);
|
|
@@ -8623,7 +8740,7 @@ class SpeechToText {
|
|
|
8623
8740
|
}
|
|
8624
8741
|
class TextToSpeech {
|
|
8625
8742
|
constructor(options) {
|
|
8626
|
-
__publicField(this, "region");
|
|
8743
|
+
__publicField(this, "region", "");
|
|
8627
8744
|
__publicField(this, "voice");
|
|
8628
8745
|
__publicField(this, "rate");
|
|
8629
8746
|
__publicField(this, "pitch");
|
|
@@ -8650,16 +8767,16 @@ class TextToSpeech {
|
|
|
8650
8767
|
__publicField(this, "activePrefetchedAudioUrl", "");
|
|
8651
8768
|
__publicField(this, "playbackSegments", []);
|
|
8652
8769
|
__publicField(this, "authorizationManager");
|
|
8653
|
-
|
|
8770
|
+
__publicField(this, "stopPromise");
|
|
8771
|
+
var _a, _b, _c;
|
|
8654
8772
|
if (!options || typeof options.voice !== "string" || options.voice.trim() === "") {
|
|
8655
8773
|
throw new Error("A voice is required.");
|
|
8656
8774
|
}
|
|
8657
8775
|
this.authorizationManager = new SpeechAuthorizationManager(options);
|
|
8658
|
-
this.region = (_b = (_a = options.region) == null ? void 0 : _a.trim()) != null ? _b : "";
|
|
8659
8776
|
this.voice = options.voice;
|
|
8660
|
-
this.rate = (
|
|
8661
|
-
this.pitch = (
|
|
8662
|
-
this.url = (
|
|
8777
|
+
this.rate = (_a = options.rate) != null ? _a : 0;
|
|
8778
|
+
this.pitch = (_b = options.pitch) != null ? _b : 0;
|
|
8779
|
+
this.url = (_c = options.url) != null ? _c : "";
|
|
8663
8780
|
}
|
|
8664
8781
|
async start() {
|
|
8665
8782
|
await this.registerBindings(document);
|
|
@@ -8688,17 +8805,35 @@ class TextToSpeech {
|
|
|
8688
8805
|
const currentNode = nodes[i];
|
|
8689
8806
|
if (currentNode.attributes) {
|
|
8690
8807
|
if (currentNode.attributes.getNamedItem("co-tts.id")) {
|
|
8691
|
-
await this.handleIdModifier(
|
|
8808
|
+
await this.handleIdModifier(
|
|
8809
|
+
currentNode,
|
|
8810
|
+
currentNode.attributes.getNamedItem("co-tts.id")
|
|
8811
|
+
);
|
|
8692
8812
|
} else if (currentNode.attributes.getNamedItem("co-tts.ajax")) {
|
|
8693
|
-
await this.handleAjaxModifier(
|
|
8813
|
+
await this.handleAjaxModifier(
|
|
8814
|
+
currentNode,
|
|
8815
|
+
currentNode.attributes.getNamedItem("co-tts.ajax")
|
|
8816
|
+
);
|
|
8694
8817
|
} else if (currentNode.attributes.getNamedItem("co-tts")) {
|
|
8695
|
-
await this.handleDefault(
|
|
8818
|
+
await this.handleDefault(
|
|
8819
|
+
currentNode,
|
|
8820
|
+
currentNode.attributes.getNamedItem("co-tts")
|
|
8821
|
+
);
|
|
8696
8822
|
} else if (currentNode.attributes.getNamedItem("co-tts.stop")) {
|
|
8697
|
-
await this.handleStopModifier(
|
|
8823
|
+
await this.handleStopModifier(
|
|
8824
|
+
currentNode,
|
|
8825
|
+
currentNode.attributes.getNamedItem("co-tts.stop")
|
|
8826
|
+
);
|
|
8698
8827
|
} else if (currentNode.attributes.getNamedItem("co-tts.resume")) {
|
|
8699
|
-
await this.handleResumeModifier(
|
|
8828
|
+
await this.handleResumeModifier(
|
|
8829
|
+
currentNode,
|
|
8830
|
+
currentNode.attributes.getNamedItem("co-tts.resume")
|
|
8831
|
+
);
|
|
8700
8832
|
} else if (currentNode.attributes.getNamedItem("co-tts.pause")) {
|
|
8701
|
-
await this.handlePauseModifier(
|
|
8833
|
+
await this.handlePauseModifier(
|
|
8834
|
+
currentNode,
|
|
8835
|
+
currentNode.attributes.getNamedItem("co-tts.pause")
|
|
8836
|
+
);
|
|
8702
8837
|
}
|
|
8703
8838
|
}
|
|
8704
8839
|
if (currentNode.childNodes.length > 0) {
|
|
@@ -8708,8 +8843,8 @@ class TextToSpeech {
|
|
|
8708
8843
|
}
|
|
8709
8844
|
async handleIdModifier(node, attr) {
|
|
8710
8845
|
node.addEventListener("click", async (_) => {
|
|
8711
|
-
var _a, _b, _c, _d;
|
|
8712
|
-
this.stopPlayer();
|
|
8846
|
+
var _a, _b, _c, _d, _e, _f;
|
|
8847
|
+
await this.stopPlayer();
|
|
8713
8848
|
await this.createInterval();
|
|
8714
8849
|
const referenceDiv = document.getElementById(attr.value);
|
|
8715
8850
|
this.clickedNode = referenceDiv;
|
|
@@ -8722,10 +8857,11 @@ class TextToSpeech {
|
|
|
8722
8857
|
this.textToRead = (_c = (_b = referenceDiv.innerText) != null ? _b : referenceDiv.textContent) != null ? _c : "";
|
|
8723
8858
|
}
|
|
8724
8859
|
if (referenceDiv.hasAttribute("co-tts.highlight")) {
|
|
8725
|
-
|
|
8726
|
-
|
|
8860
|
+
const highlightTarget = (_e = (_d = referenceDiv.attributes.getNamedItem("co-tts.highlight")) == null ? void 0 : _d.value) != null ? _e : "";
|
|
8861
|
+
if (highlightTarget !== "") {
|
|
8862
|
+
const newReferenceDiv = document.getElementById(highlightTarget);
|
|
8727
8863
|
this.highlightDiv = newReferenceDiv;
|
|
8728
|
-
this.originalHighlightDivInnerHTML = newReferenceDiv.innerHTML;
|
|
8864
|
+
this.originalHighlightDivInnerHTML = (_f = newReferenceDiv == null ? void 0 : newReferenceDiv.innerHTML) != null ? _f : "";
|
|
8729
8865
|
} else {
|
|
8730
8866
|
this.highlightDiv = referenceDiv;
|
|
8731
8867
|
this.originalHighlightDivInnerHTML = referenceDiv.innerHTML;
|
|
@@ -8736,7 +8872,7 @@ class TextToSpeech {
|
|
|
8736
8872
|
}
|
|
8737
8873
|
async handleAjaxModifier(node, attr) {
|
|
8738
8874
|
node.addEventListener("click", async (_) => {
|
|
8739
|
-
this.stopPlayer();
|
|
8875
|
+
await this.stopPlayer();
|
|
8740
8876
|
await this.createInterval();
|
|
8741
8877
|
this.clickedNode = node;
|
|
8742
8878
|
const response = await fetch(attr.value, {
|
|
@@ -8748,22 +8884,23 @@ class TextToSpeech {
|
|
|
8748
8884
|
}
|
|
8749
8885
|
async handleDefault(node, attr) {
|
|
8750
8886
|
node.addEventListener("click", async (_) => {
|
|
8751
|
-
var _a, _b, _c;
|
|
8752
|
-
this.stopPlayer();
|
|
8887
|
+
var _a, _b, _c, _d, _e;
|
|
8888
|
+
await this.stopPlayer();
|
|
8753
8889
|
await this.createInterval();
|
|
8754
8890
|
this.clickedNode = node;
|
|
8755
8891
|
if (node.hasAttribute("co-tts.highlight")) {
|
|
8756
|
-
|
|
8757
|
-
|
|
8892
|
+
const highlightTarget = (_b = (_a = node.attributes.getNamedItem("co-tts.highlight")) == null ? void 0 : _a.value) != null ? _b : "";
|
|
8893
|
+
if (highlightTarget !== "") {
|
|
8894
|
+
const newReferenceDiv = document.getElementById(highlightTarget);
|
|
8758
8895
|
this.highlightDiv = newReferenceDiv;
|
|
8759
|
-
this.originalHighlightDivInnerHTML = newReferenceDiv.innerHTML;
|
|
8896
|
+
this.originalHighlightDivInnerHTML = (_c = newReferenceDiv == null ? void 0 : newReferenceDiv.innerHTML) != null ? _c : "";
|
|
8760
8897
|
} else {
|
|
8761
8898
|
this.highlightDiv = node;
|
|
8762
8899
|
this.originalHighlightDivInnerHTML = node.innerHTML;
|
|
8763
8900
|
}
|
|
8764
8901
|
}
|
|
8765
8902
|
if (attr.value === "") {
|
|
8766
|
-
this.textToRead = (
|
|
8903
|
+
this.textToRead = (_e = (_d = node.innerText) != null ? _d : node.textContent) != null ? _e : "";
|
|
8767
8904
|
} else {
|
|
8768
8905
|
this.textToRead = attr.value;
|
|
8769
8906
|
}
|
|
@@ -8772,12 +8909,14 @@ class TextToSpeech {
|
|
|
8772
8909
|
}
|
|
8773
8910
|
async handleWithoutClick(node, attr) {
|
|
8774
8911
|
var _a, _b, _c;
|
|
8775
|
-
this.stopPlayer();
|
|
8912
|
+
await this.stopPlayer();
|
|
8776
8913
|
await this.createInterval();
|
|
8777
8914
|
this.clickedNode = node;
|
|
8778
8915
|
if (node.hasAttribute("co-tts.highlight")) {
|
|
8779
8916
|
if (((_a = node.attributes.getNamedItem("co-tts.highlight")) == null ? void 0 : _a.value) !== "") {
|
|
8780
|
-
const newReferenceDiv = document.getElementById(
|
|
8917
|
+
const newReferenceDiv = document.getElementById(
|
|
8918
|
+
node.attributes.getNamedItem("co-tts.highlight").value
|
|
8919
|
+
);
|
|
8781
8920
|
this.highlightDiv = newReferenceDiv;
|
|
8782
8921
|
if (newReferenceDiv !== null) {
|
|
8783
8922
|
this.originalHighlightDivInnerHTML = newReferenceDiv.innerHTML;
|
|
@@ -8794,52 +8933,86 @@ class TextToSpeech {
|
|
|
8794
8933
|
}
|
|
8795
8934
|
await this.startSynthesizer(node, attr);
|
|
8796
8935
|
}
|
|
8797
|
-
async handleStopModifier(node,
|
|
8936
|
+
async handleStopModifier(node, _attr) {
|
|
8798
8937
|
node.addEventListener("click", async (_) => {
|
|
8799
8938
|
await this.stopPlayer();
|
|
8800
8939
|
document.dispatchEvent(new CustomEvent("COAzureTTSStoppedPlaying", {}));
|
|
8801
8940
|
});
|
|
8802
8941
|
}
|
|
8803
|
-
async handlePauseModifier(node,
|
|
8942
|
+
async handlePauseModifier(node, _attr) {
|
|
8804
8943
|
node.addEventListener("click", async (_) => {
|
|
8944
|
+
if (!this.player || typeof this.player.pause !== "function") {
|
|
8945
|
+
return;
|
|
8946
|
+
}
|
|
8805
8947
|
await this.clearInterval();
|
|
8806
8948
|
await this.player.pause();
|
|
8807
8949
|
document.dispatchEvent(new CustomEvent("COAzureTTSPausedPlaying", {}));
|
|
8808
8950
|
});
|
|
8809
8951
|
}
|
|
8810
|
-
async handleResumeModifier(node,
|
|
8952
|
+
async handleResumeModifier(node, _attr) {
|
|
8811
8953
|
node.addEventListener("click", async (_) => {
|
|
8954
|
+
if (!this.player) {
|
|
8955
|
+
return;
|
|
8956
|
+
}
|
|
8812
8957
|
await this.createInterval();
|
|
8813
|
-
|
|
8958
|
+
if (typeof this.player.resume === "function") {
|
|
8959
|
+
await this.player.resume();
|
|
8960
|
+
} else if (typeof this.player.play === "function") {
|
|
8961
|
+
await this.player.play();
|
|
8962
|
+
} else {
|
|
8963
|
+
return;
|
|
8964
|
+
}
|
|
8814
8965
|
document.dispatchEvent(new CustomEvent("COAzureTTSResumedPlaying", {}));
|
|
8815
8966
|
});
|
|
8816
8967
|
}
|
|
8817
8968
|
async stopPlayer() {
|
|
8969
|
+
if (this.stopPromise) {
|
|
8970
|
+
return this.stopPromise;
|
|
8971
|
+
}
|
|
8972
|
+
this.stopPromise = this.performStopPlayer().finally(() => {
|
|
8973
|
+
this.stopPromise = void 0;
|
|
8974
|
+
});
|
|
8975
|
+
return this.stopPromise;
|
|
8976
|
+
}
|
|
8977
|
+
async performStopPlayer() {
|
|
8818
8978
|
await this.clearInterval();
|
|
8819
8979
|
if (this.highlightDiv !== void 0) {
|
|
8820
8980
|
this.highlightDiv.innerHTML = this.originalHighlightDivInnerHTML;
|
|
8821
8981
|
}
|
|
8982
|
+
this.resetPlaybackSegments();
|
|
8983
|
+
const player = this.player;
|
|
8984
|
+
const activePrefetchedAudioUrl = this.activePrefetchedAudioUrl;
|
|
8985
|
+
const synthesizer = this.synthesizer;
|
|
8822
8986
|
this.textToRead = "";
|
|
8823
8987
|
this.currentWord = "";
|
|
8824
8988
|
this.originalHighlightDivInnerHTML = "";
|
|
8825
8989
|
this.wordBoundryList = [];
|
|
8826
8990
|
this.wordEncounters = [];
|
|
8827
|
-
this.resetPlaybackSegments();
|
|
8828
8991
|
this.playbackSegments = [];
|
|
8829
|
-
if (this.player !== void 0) {
|
|
8830
|
-
this.player.pause();
|
|
8831
|
-
}
|
|
8832
|
-
if (this.activePrefetchedAudioUrl !== "") {
|
|
8833
|
-
URL.revokeObjectURL(this.activePrefetchedAudioUrl);
|
|
8834
|
-
this.activePrefetchedAudioUrl = "";
|
|
8835
|
-
}
|
|
8836
|
-
this.closeSynthesizer();
|
|
8837
|
-
this.player = void 0;
|
|
8838
|
-
this.audioConfig = void 0;
|
|
8839
|
-
this.speechConfig = void 0;
|
|
8840
8992
|
this.highlightDiv = void 0;
|
|
8841
8993
|
this.prevTextOffset = 0;
|
|
8842
8994
|
this.playbackTextOffsetBase = void 0;
|
|
8995
|
+
this.audioConfig = void 0;
|
|
8996
|
+
this.speechConfig = void 0;
|
|
8997
|
+
if (this.player === player) {
|
|
8998
|
+
this.player = void 0;
|
|
8999
|
+
}
|
|
9000
|
+
if (this.activePrefetchedAudioUrl === activePrefetchedAudioUrl) {
|
|
9001
|
+
this.activePrefetchedAudioUrl = "";
|
|
9002
|
+
}
|
|
9003
|
+
if (this.synthesizer === synthesizer) {
|
|
9004
|
+
this.synthesizer = void 0;
|
|
9005
|
+
}
|
|
9006
|
+
if (player !== void 0 && typeof player.pause === "function") {
|
|
9007
|
+
try {
|
|
9008
|
+
player.pause();
|
|
9009
|
+
} catch {
|
|
9010
|
+
}
|
|
9011
|
+
}
|
|
9012
|
+
if (activePrefetchedAudioUrl !== "") {
|
|
9013
|
+
URL.revokeObjectURL(activePrefetchedAudioUrl);
|
|
9014
|
+
}
|
|
9015
|
+
this.closeResource(synthesizer);
|
|
8843
9016
|
}
|
|
8844
9017
|
async createSpeechConfig() {
|
|
8845
9018
|
const authorization = await this.authorizationManager.getAuthorization();
|
|
@@ -8852,13 +9025,13 @@ class TextToSpeech {
|
|
|
8852
9025
|
this.region = authorization.region;
|
|
8853
9026
|
return speechConfig;
|
|
8854
9027
|
}
|
|
8855
|
-
async startSynthesizer(
|
|
9028
|
+
async startSynthesizer(_node, _attr) {
|
|
8856
9029
|
try {
|
|
8857
9030
|
this.speechConfig = await this.createSpeechConfig();
|
|
8858
9031
|
this.player = new SpeakerAudioDestination();
|
|
8859
9032
|
this.audioConfig = AudioConfig.fromSpeakerOutput(this.player);
|
|
8860
9033
|
this.synthesizer = new SpeechSynthesizer(this.speechConfig, this.audioConfig);
|
|
8861
|
-
this.synthesizer.wordBoundary = (
|
|
9034
|
+
this.synthesizer.wordBoundary = (_s, e) => {
|
|
8862
9035
|
this.wordBoundryList.push(e);
|
|
8863
9036
|
};
|
|
8864
9037
|
const playbackChain = this.collectPlaybackChain(this.clickedNode);
|
|
@@ -8869,19 +9042,23 @@ class TextToSpeech {
|
|
|
8869
9042
|
this.playbackSegments = [];
|
|
8870
9043
|
}
|
|
8871
9044
|
this.player.onAudioEnd = async () => {
|
|
9045
|
+
var _a;
|
|
9046
|
+
const clickedNode = this.clickedNode;
|
|
8872
9047
|
const wasChainedPlayback = this.playbackSegments.length > 0;
|
|
8873
|
-
|
|
9048
|
+
const nextNodeId = ((_a = clickedNode == null ? void 0 : clickedNode.hasAttribute) == null ? void 0 : _a.call(clickedNode, "co-tts.next")) ? clickedNode.getAttribute("co-tts.next") : null;
|
|
9049
|
+
await this.stopPlayer();
|
|
8874
9050
|
if (wasChainedPlayback) {
|
|
8875
9051
|
document.dispatchEvent(new CustomEvent("COAzureTTSFinishedPlaying", {}));
|
|
8876
9052
|
return;
|
|
8877
9053
|
}
|
|
8878
|
-
if (
|
|
8879
|
-
const nextNode = document.getElementById(
|
|
9054
|
+
if (nextNodeId) {
|
|
9055
|
+
const nextNode = document.getElementById(nextNodeId);
|
|
8880
9056
|
if (nextNode && await this.playPrefetchedNode(nextNode)) {
|
|
8881
9057
|
return;
|
|
8882
9058
|
}
|
|
8883
|
-
|
|
8884
|
-
|
|
9059
|
+
const nextTextAttr = nextNode == null ? void 0 : nextNode.attributes.getNamedItem("co-tts.text");
|
|
9060
|
+
if (nextNode && nextTextAttr) {
|
|
9061
|
+
await this.handleWithoutClick(nextNode, nextTextAttr);
|
|
8885
9062
|
} else if (nextNode) {
|
|
8886
9063
|
nextNode.dispatchEvent(new Event("click"));
|
|
8887
9064
|
}
|
|
@@ -8893,7 +9070,7 @@ class TextToSpeech {
|
|
|
8893
9070
|
document.dispatchEvent(new CustomEvent("COAzureTTSStartedPlaying", {}));
|
|
8894
9071
|
};
|
|
8895
9072
|
if (!isChainedPlayback) {
|
|
8896
|
-
this.prefetchNextNode(this.clickedNode);
|
|
9073
|
+
void this.prefetchNextNode(this.clickedNode);
|
|
8897
9074
|
}
|
|
8898
9075
|
this.synthesizer.speakSsmlAsync(
|
|
8899
9076
|
this.buildSSML(this.textToRead),
|
|
@@ -8901,12 +9078,18 @@ class TextToSpeech {
|
|
|
8901
9078
|
this.closeSynthesizer();
|
|
8902
9079
|
},
|
|
8903
9080
|
(error) => {
|
|
9081
|
+
if (isLikelyAuthorizationError(error)) {
|
|
9082
|
+
this.authorizationManager.clearAuthorization();
|
|
9083
|
+
}
|
|
8904
9084
|
this.dispatchError(error, "SYNTHESIS_ERROR");
|
|
8905
9085
|
this.closeSynthesizer();
|
|
8906
|
-
this.stopPlayer();
|
|
9086
|
+
void this.stopPlayer();
|
|
8907
9087
|
}
|
|
8908
9088
|
);
|
|
8909
9089
|
} catch (error) {
|
|
9090
|
+
if (isLikelyAuthorizationError(error)) {
|
|
9091
|
+
this.authorizationManager.clearAuthorization();
|
|
9092
|
+
}
|
|
8910
9093
|
this.dispatchError(error);
|
|
8911
9094
|
await this.stopPlayer();
|
|
8912
9095
|
}
|
|
@@ -8960,7 +9143,9 @@ class TextToSpeech {
|
|
|
8960
9143
|
return void 0;
|
|
8961
9144
|
}
|
|
8962
9145
|
if (((_a = node.attributes.getNamedItem("co-tts.highlight")) == null ? void 0 : _a.value) !== "") {
|
|
8963
|
-
return document.getElementById(
|
|
9146
|
+
return document.getElementById(
|
|
9147
|
+
node.attributes.getNamedItem("co-tts.highlight").value
|
|
9148
|
+
);
|
|
8964
9149
|
}
|
|
8965
9150
|
return node;
|
|
8966
9151
|
}
|
|
@@ -8972,7 +9157,7 @@ class TextToSpeech {
|
|
|
8972
9157
|
});
|
|
8973
9158
|
}
|
|
8974
9159
|
updateChainedHighlight(wordBoundary) {
|
|
8975
|
-
var _a;
|
|
9160
|
+
var _a, _b;
|
|
8976
9161
|
if (~[".", ",", "!", "?", "*", "(", ")", "&", "\\", "/", "^", "[", "]", "<", ">", ":"].indexOf(wordBoundary.text)) {
|
|
8977
9162
|
wordBoundary = (_a = this.previousWordBoundary) != null ? _a : void 0;
|
|
8978
9163
|
}
|
|
@@ -8983,7 +9168,10 @@ class TextToSpeech {
|
|
|
8983
9168
|
if (this.playbackTextOffsetBase === void 0) {
|
|
8984
9169
|
this.playbackTextOffsetBase = wordBoundary.textOffset;
|
|
8985
9170
|
}
|
|
8986
|
-
const normalizedTextOffset = Math.max(
|
|
9171
|
+
const normalizedTextOffset = Math.max(
|
|
9172
|
+
0,
|
|
9173
|
+
wordBoundary.textOffset - ((_b = this.playbackTextOffsetBase) != null ? _b : 0)
|
|
9174
|
+
);
|
|
8987
9175
|
const segment = this.playbackSegments.find((candidate) => normalizedTextOffset >= candidate.start && normalizedTextOffset < candidate.end);
|
|
8988
9176
|
this.resetPlaybackSegments();
|
|
8989
9177
|
if (!(segment == null ? void 0 : segment.highlightDiv)) {
|
|
@@ -8991,7 +9179,11 @@ class TextToSpeech {
|
|
|
8991
9179
|
return;
|
|
8992
9180
|
}
|
|
8993
9181
|
const relativeTextOffset = normalizedTextOffset - segment.start;
|
|
8994
|
-
const currentOffset = this.getPosition(
|
|
9182
|
+
const currentOffset = this.getPosition(
|
|
9183
|
+
segment.originalHighlightDivInnerHTML,
|
|
9184
|
+
wordBoundary.text,
|
|
9185
|
+
relativeTextOffset
|
|
9186
|
+
);
|
|
8995
9187
|
if (currentOffset === Number.MAX_SAFE_INTEGER) {
|
|
8996
9188
|
this.previousWordBoundary = wordBoundary;
|
|
8997
9189
|
return;
|
|
@@ -9055,9 +9247,9 @@ class TextToSpeech {
|
|
|
9055
9247
|
const prefetchPromise = (async () => {
|
|
9056
9248
|
try {
|
|
9057
9249
|
const speechConfig = await this.createSpeechConfig();
|
|
9058
|
-
synthesizer = new SpeechSynthesizer(speechConfig,
|
|
9250
|
+
synthesizer = new SpeechSynthesizer(speechConfig, void 0);
|
|
9059
9251
|
const wordBoundryList = [];
|
|
9060
|
-
synthesizer.wordBoundary = (
|
|
9252
|
+
synthesizer.wordBoundary = (_s, e) => {
|
|
9061
9253
|
wordBoundryList.push(e);
|
|
9062
9254
|
};
|
|
9063
9255
|
return await new Promise((resolve) => {
|
|
@@ -9085,6 +9277,9 @@ class TextToSpeech {
|
|
|
9085
9277
|
(error) => {
|
|
9086
9278
|
this.closeResource(synthesizer);
|
|
9087
9279
|
synthesizer = void 0;
|
|
9280
|
+
if (isLikelyAuthorizationError(error)) {
|
|
9281
|
+
this.authorizationManager.clearAuthorization();
|
|
9282
|
+
}
|
|
9088
9283
|
this.dispatchError(error, "PREFETCH_ERROR");
|
|
9089
9284
|
resolve(null);
|
|
9090
9285
|
}
|
|
@@ -9093,6 +9288,9 @@ class TextToSpeech {
|
|
|
9093
9288
|
} catch (error) {
|
|
9094
9289
|
this.closeResource(synthesizer);
|
|
9095
9290
|
synthesizer = void 0;
|
|
9291
|
+
if (isLikelyAuthorizationError(error)) {
|
|
9292
|
+
this.authorizationManager.clearAuthorization();
|
|
9293
|
+
}
|
|
9096
9294
|
this.dispatchError(error);
|
|
9097
9295
|
return null;
|
|
9098
9296
|
}
|
|
@@ -9122,7 +9320,9 @@ class TextToSpeech {
|
|
|
9122
9320
|
this.wordBoundaryOffset = 0;
|
|
9123
9321
|
if (node.hasAttribute("co-tts.highlight")) {
|
|
9124
9322
|
if (((_c = node.attributes.getNamedItem("co-tts.highlight")) == null ? void 0 : _c.value) !== "") {
|
|
9125
|
-
const newReferenceDiv = document.getElementById(
|
|
9323
|
+
const newReferenceDiv = document.getElementById(
|
|
9324
|
+
node.attributes.getNamedItem("co-tts.highlight").value
|
|
9325
|
+
);
|
|
9126
9326
|
this.highlightDiv = newReferenceDiv;
|
|
9127
9327
|
if (newReferenceDiv !== null) {
|
|
9128
9328
|
this.originalHighlightDivInnerHTML = newReferenceDiv.innerHTML;
|
|
@@ -9141,14 +9341,18 @@ class TextToSpeech {
|
|
|
9141
9341
|
document.dispatchEvent(new CustomEvent("COAzureTTSStartedPlaying", {}));
|
|
9142
9342
|
}, { once: true });
|
|
9143
9343
|
audio.addEventListener("ended", async () => {
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9344
|
+
var _a2;
|
|
9345
|
+
const clickedNode = this.clickedNode;
|
|
9346
|
+
const nextNodeId = ((_a2 = clickedNode == null ? void 0 : clickedNode.hasAttribute) == null ? void 0 : _a2.call(clickedNode, "co-tts.next")) ? clickedNode.getAttribute("co-tts.next") : null;
|
|
9347
|
+
await this.stopPlayer();
|
|
9348
|
+
if (nextNodeId) {
|
|
9349
|
+
const nextNode = document.getElementById(nextNodeId);
|
|
9147
9350
|
if (nextNode && await this.playPrefetchedNode(nextNode)) {
|
|
9148
9351
|
return;
|
|
9149
9352
|
}
|
|
9150
|
-
|
|
9151
|
-
|
|
9353
|
+
const nextTextAttr = nextNode == null ? void 0 : nextNode.attributes.getNamedItem("co-tts.text");
|
|
9354
|
+
if (nextNode && nextTextAttr) {
|
|
9355
|
+
await this.handleWithoutClick(nextNode, nextTextAttr);
|
|
9152
9356
|
} else if (nextNode) {
|
|
9153
9357
|
nextNode.dispatchEvent(new Event("click"));
|
|
9154
9358
|
}
|
|
@@ -9161,9 +9365,9 @@ class TextToSpeech {
|
|
|
9161
9365
|
new Error("Prefetched audio resource closed unexpectedly."),
|
|
9162
9366
|
"AUDIO_RESOURCE_ERROR"
|
|
9163
9367
|
);
|
|
9164
|
-
this.stopPlayer();
|
|
9368
|
+
void this.stopPlayer();
|
|
9165
9369
|
}, { once: true });
|
|
9166
|
-
this.prefetchNextNode(node);
|
|
9370
|
+
void this.prefetchNextNode(node);
|
|
9167
9371
|
await audio.play();
|
|
9168
9372
|
return true;
|
|
9169
9373
|
} catch (error) {
|
|
@@ -9300,4 +9504,4 @@ class TextToSpeech {
|
|
|
9300
9504
|
);
|
|
9301
9505
|
}
|
|
9302
9506
|
}
|
|
9303
|
-
export { SpeechToText, TextToSpeech };
|
|
9507
|
+
export { DEFAULT_TOKEN_LIFETIME_MS, SpeechAuthorizationManager, SpeechToText, TextToSpeech, createSpeechAuthorizationProvider, isLikelyAuthorizationError, sanitizeErrorText, toSafeErrorDetail, validateSpeechAuthorization };
|