@creativeorange/azure-text-to-speech 2.2.0 → 2.2.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/dist/co-azure-tts.es.js +110 -1
- package/dist/co-azure-tts.umd.js +8 -6
- package/package.json +1 -1
- package/src/TextToSpeech.ts +142 -1
package/dist/co-azure-tts.es.js
CHANGED
|
@@ -8460,6 +8460,7 @@ class TextToSpeech {
|
|
|
8460
8460
|
__publicField(this, "prefetchedAudio", /* @__PURE__ */ new Map());
|
|
8461
8461
|
__publicField(this, "prefetchPromises", /* @__PURE__ */ new Map());
|
|
8462
8462
|
__publicField(this, "activePrefetchedAudioUrl", "");
|
|
8463
|
+
__publicField(this, "playbackSegments", []);
|
|
8463
8464
|
this.key = key;
|
|
8464
8465
|
this.region = region;
|
|
8465
8466
|
this.voice = voice;
|
|
@@ -8630,6 +8631,8 @@ class TextToSpeech {
|
|
|
8630
8631
|
this.originalHighlightDivInnerHTML = "";
|
|
8631
8632
|
this.wordBoundryList = [];
|
|
8632
8633
|
this.wordEncounters = [];
|
|
8634
|
+
this.resetPlaybackSegments();
|
|
8635
|
+
this.playbackSegments = [];
|
|
8633
8636
|
if (this.player !== void 0) {
|
|
8634
8637
|
this.player.pause();
|
|
8635
8638
|
}
|
|
@@ -8651,8 +8654,20 @@ class TextToSpeech {
|
|
|
8651
8654
|
this.synthesizer.wordBoundary = (s, e) => {
|
|
8652
8655
|
this.wordBoundryList.push(e);
|
|
8653
8656
|
};
|
|
8657
|
+
const playbackChain = this.collectPlaybackChain(this.clickedNode);
|
|
8658
|
+
const isChainedPlayback = playbackChain.length > 1;
|
|
8659
|
+
if (isChainedPlayback) {
|
|
8660
|
+
this.preparePlaybackChain(playbackChain);
|
|
8661
|
+
} else {
|
|
8662
|
+
this.playbackSegments = [];
|
|
8663
|
+
}
|
|
8654
8664
|
this.player.onAudioEnd = async () => {
|
|
8665
|
+
const wasChainedPlayback = this.playbackSegments.length > 0;
|
|
8655
8666
|
this.stopPlayer();
|
|
8667
|
+
if (wasChainedPlayback) {
|
|
8668
|
+
document.dispatchEvent(new CustomEvent("COAzureTTSFinishedPlaying", {}));
|
|
8669
|
+
return;
|
|
8670
|
+
}
|
|
8656
8671
|
if (this.clickedNode.hasAttribute("co-tts.next")) {
|
|
8657
8672
|
const nextNode = document.getElementById(this.clickedNode.getAttribute("co-tts.next"));
|
|
8658
8673
|
if (nextNode && await this.playPrefetchedNode(nextNode)) {
|
|
@@ -8670,7 +8685,9 @@ class TextToSpeech {
|
|
|
8670
8685
|
this.player.onAudioStart = async () => {
|
|
8671
8686
|
document.dispatchEvent(new CustomEvent("COAzureTTSStartedPlaying", {}));
|
|
8672
8687
|
};
|
|
8673
|
-
|
|
8688
|
+
if (!isChainedPlayback) {
|
|
8689
|
+
this.prefetchNextNode(this.clickedNode);
|
|
8690
|
+
}
|
|
8674
8691
|
this.synthesizer.speakSsmlAsync(
|
|
8675
8692
|
this.buildSSML(this.textToRead),
|
|
8676
8693
|
() => {
|
|
@@ -8683,6 +8700,94 @@ class TextToSpeech {
|
|
|
8683
8700
|
}
|
|
8684
8701
|
);
|
|
8685
8702
|
}
|
|
8703
|
+
collectPlaybackChain(node) {
|
|
8704
|
+
var _a, _b;
|
|
8705
|
+
const chain = [];
|
|
8706
|
+
const seenNodeIds = /* @__PURE__ */ new Set();
|
|
8707
|
+
let currentNode = node;
|
|
8708
|
+
let offset = 0;
|
|
8709
|
+
while (currentNode && !seenNodeIds.has(currentNode.id)) {
|
|
8710
|
+
seenNodeIds.add(currentNode.id);
|
|
8711
|
+
const attr = (_a = currentNode.attributes.getNamedItem("co-tts.text")) != null ? _a : currentNode.attributes.getNamedItem("co-tts");
|
|
8712
|
+
const text = this.getNodeText(currentNode, attr);
|
|
8713
|
+
if (text === "") {
|
|
8714
|
+
break;
|
|
8715
|
+
}
|
|
8716
|
+
const highlightDiv = this.getHighlightDivForNode(currentNode);
|
|
8717
|
+
chain.push({
|
|
8718
|
+
node: currentNode,
|
|
8719
|
+
text,
|
|
8720
|
+
start: offset,
|
|
8721
|
+
end: offset + text.length,
|
|
8722
|
+
highlightDiv,
|
|
8723
|
+
originalHighlightDivInnerHTML: (_b = highlightDiv == null ? void 0 : highlightDiv.innerHTML) != null ? _b : ""
|
|
8724
|
+
});
|
|
8725
|
+
offset += text.length + 2;
|
|
8726
|
+
if (!currentNode.hasAttribute("co-tts.next")) {
|
|
8727
|
+
break;
|
|
8728
|
+
}
|
|
8729
|
+
currentNode = document.getElementById(currentNode.getAttribute("co-tts.next"));
|
|
8730
|
+
}
|
|
8731
|
+
return chain;
|
|
8732
|
+
}
|
|
8733
|
+
preparePlaybackChain(chain) {
|
|
8734
|
+
this.playbackSegments = chain;
|
|
8735
|
+
this.textToRead = chain.map((segment) => segment.text).join(". ");
|
|
8736
|
+
this.highlightDiv = void 0;
|
|
8737
|
+
this.originalHighlightDivInnerHTML = "";
|
|
8738
|
+
this.wordEncounters = [];
|
|
8739
|
+
this.previousWordBoundary = void 0;
|
|
8740
|
+
this.prevTextOffset = 0;
|
|
8741
|
+
this.currentWord = "";
|
|
8742
|
+
this.currentOffset = 0;
|
|
8743
|
+
this.wordBoundaryOffset = 0;
|
|
8744
|
+
}
|
|
8745
|
+
getHighlightDivForNode(node) {
|
|
8746
|
+
var _a;
|
|
8747
|
+
if (!node.hasAttribute("co-tts.highlight")) {
|
|
8748
|
+
return void 0;
|
|
8749
|
+
}
|
|
8750
|
+
if (((_a = node.attributes.getNamedItem("co-tts.highlight")) == null ? void 0 : _a.value) !== "") {
|
|
8751
|
+
return document.getElementById(node.attributes.getNamedItem("co-tts.highlight").value);
|
|
8752
|
+
}
|
|
8753
|
+
return node;
|
|
8754
|
+
}
|
|
8755
|
+
resetPlaybackSegments() {
|
|
8756
|
+
this.playbackSegments.forEach((segment) => {
|
|
8757
|
+
if (segment.highlightDiv) {
|
|
8758
|
+
segment.highlightDiv.innerHTML = segment.originalHighlightDivInnerHTML;
|
|
8759
|
+
}
|
|
8760
|
+
});
|
|
8761
|
+
}
|
|
8762
|
+
updateChainedHighlight(wordBoundary) {
|
|
8763
|
+
var _a;
|
|
8764
|
+
if (~[".", ",", "!", "?", "*", "(", ")", "&", "\\", "/", "^", "[", "]", "<", ">", ":"].indexOf(wordBoundary.text)) {
|
|
8765
|
+
wordBoundary = (_a = this.previousWordBoundary) != null ? _a : void 0;
|
|
8766
|
+
}
|
|
8767
|
+
if (!wordBoundary) {
|
|
8768
|
+
this.resetPlaybackSegments();
|
|
8769
|
+
return;
|
|
8770
|
+
}
|
|
8771
|
+
const segment = this.playbackSegments.find((candidate) => wordBoundary.textOffset >= candidate.start && wordBoundary.textOffset < candidate.end);
|
|
8772
|
+
this.resetPlaybackSegments();
|
|
8773
|
+
if (!(segment == null ? void 0 : segment.highlightDiv)) {
|
|
8774
|
+
this.previousWordBoundary = wordBoundary;
|
|
8775
|
+
return;
|
|
8776
|
+
}
|
|
8777
|
+
const relativeTextOffset = wordBoundary.textOffset - segment.start;
|
|
8778
|
+
const currentOffset = this.getPosition(segment.originalHighlightDivInnerHTML, wordBoundary.text, relativeTextOffset);
|
|
8779
|
+
if (currentOffset === Number.MAX_SAFE_INTEGER) {
|
|
8780
|
+
this.previousWordBoundary = wordBoundary;
|
|
8781
|
+
return;
|
|
8782
|
+
}
|
|
8783
|
+
const startOfString = segment.originalHighlightDivInnerHTML.substring(0, currentOffset);
|
|
8784
|
+
const endOffset = currentOffset + wordBoundary.wordLength;
|
|
8785
|
+
const endOfString = segment.originalHighlightDivInnerHTML.substring(endOffset);
|
|
8786
|
+
segment.highlightDiv.innerHTML = `
|
|
8787
|
+
${startOfString}<mark class='co-tts-highlight'>${wordBoundary.text}</mark>${endOfString}
|
|
8788
|
+
`;
|
|
8789
|
+
this.previousWordBoundary = wordBoundary;
|
|
8790
|
+
}
|
|
8686
8791
|
getNodeText(node, attr) {
|
|
8687
8792
|
var _a;
|
|
8688
8793
|
if (attr && attr.value !== "") {
|
|
@@ -8844,6 +8949,10 @@ class TextToSpeech {
|
|
|
8844
8949
|
}
|
|
8845
8950
|
}
|
|
8846
8951
|
if (wordBoundary !== void 0) {
|
|
8952
|
+
if (this.playbackSegments.length > 0) {
|
|
8953
|
+
this.updateChainedHighlight(wordBoundary);
|
|
8954
|
+
return;
|
|
8955
|
+
}
|
|
8847
8956
|
if (~[".", ",", "!", "?", "*", "(", ")", "&", "\\", "/", "^", "[", "]", "<", ">", ":"].indexOf(wordBoundary.text)) {
|
|
8848
8957
|
wordBoundary = (_a = this.previousWordBoundary) != null ? _a : void 0;
|
|
8849
8958
|
}
|