ruiyun-human 1.0.5 → 1.0.6
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/ruiyun-human.cjs.js +57 -11
- package/dist/ruiyun-human.es.js +57 -11
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/ruiyun-human.cjs.js
CHANGED
|
@@ -554,6 +554,7 @@ const _sfc_main = {
|
|
|
554
554
|
runAnimation("speak");
|
|
555
555
|
};
|
|
556
556
|
const stopSpeaking = () => {
|
|
557
|
+
abortTTS();
|
|
557
558
|
if (animationState.value === "speak" || animationState.value === "speakLoop") {
|
|
558
559
|
runAnimation("speakEnd");
|
|
559
560
|
} else {
|
|
@@ -629,13 +630,44 @@ const _sfc_main = {
|
|
|
629
630
|
};
|
|
630
631
|
const currentAudio = vue.ref(null);
|
|
631
632
|
const currentTtsRequestId = vue.ref(null);
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
633
|
+
let ttsAbortController = null;
|
|
634
|
+
function abortTTS() {
|
|
635
|
+
currentTtsRequestId.value = null;
|
|
636
|
+
if (ttsAbortController) {
|
|
637
|
+
try {
|
|
638
|
+
ttsAbortController.abort();
|
|
639
|
+
} catch {
|
|
640
|
+
}
|
|
641
|
+
ttsAbortController = null;
|
|
642
|
+
}
|
|
635
643
|
if (currentAudio.value) {
|
|
636
|
-
|
|
644
|
+
try {
|
|
645
|
+
currentAudio.value.pause();
|
|
646
|
+
} catch {
|
|
647
|
+
}
|
|
637
648
|
currentAudio.value = null;
|
|
638
649
|
}
|
|
650
|
+
}
|
|
651
|
+
function waitWithSignal(ms, signal) {
|
|
652
|
+
return new Promise((resolve, reject) => {
|
|
653
|
+
if (signal == null ? void 0 : signal.aborted) {
|
|
654
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
const timer = setTimeout(resolve, ms);
|
|
658
|
+
const onAbort = () => {
|
|
659
|
+
clearTimeout(timer);
|
|
660
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
661
|
+
};
|
|
662
|
+
signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
const playTTS = async (text) => {
|
|
666
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
667
|
+
if (!text || !((_a = currentHuman.value) == null ? void 0 : _a.isMuted)) return;
|
|
668
|
+
abortTTS();
|
|
669
|
+
ttsAbortController = new AbortController();
|
|
670
|
+
const { signal } = ttsAbortController;
|
|
639
671
|
currentTtsRequestId.value = Date.now();
|
|
640
672
|
const requestId = currentTtsRequestId.value;
|
|
641
673
|
try {
|
|
@@ -651,7 +683,8 @@ const _sfc_main = {
|
|
|
651
683
|
const joinRes = await fetch(`${baseUrl}/gradio_api/queue/join`, {
|
|
652
684
|
method: "POST",
|
|
653
685
|
headers: { "Content-Type": "application/json" },
|
|
654
|
-
body: JSON.stringify({ data, session_hash: sessionHash, fn_index: 1, trigger_id: 50 })
|
|
686
|
+
body: JSON.stringify({ data, session_hash: sessionHash, fn_index: 1, trigger_id: 50 }),
|
|
687
|
+
signal
|
|
655
688
|
});
|
|
656
689
|
const joinData = await joinRes.json();
|
|
657
690
|
console.log("[OmniVoice] Step1 响应:", joinData);
|
|
@@ -660,10 +693,13 @@ const _sfc_main = {
|
|
|
660
693
|
let maxPolls = 60;
|
|
661
694
|
let pollInterval = 1e3;
|
|
662
695
|
while (!audioUrl && maxPolls > 0) {
|
|
663
|
-
|
|
696
|
+
if (signal.aborted || currentTtsRequestId.value !== requestId) return;
|
|
697
|
+
await waitWithSignal(pollInterval, signal);
|
|
664
698
|
maxPolls--;
|
|
665
699
|
try {
|
|
666
|
-
const pollRes = await fetch(`${baseUrl}/gradio_api/queue/data?session_hash=${sessionHash}
|
|
700
|
+
const pollRes = await fetch(`${baseUrl}/gradio_api/queue/data?session_hash=${sessionHash}`, {
|
|
701
|
+
signal
|
|
702
|
+
});
|
|
667
703
|
const pollText = await pollRes.text();
|
|
668
704
|
const lines = pollText.split("\n");
|
|
669
705
|
for (const line of lines) {
|
|
@@ -690,7 +726,7 @@ const _sfc_main = {
|
|
|
690
726
|
}
|
|
691
727
|
const wavBlob = createWavBlob(audioBuffer, samplingRate, 1, 16);
|
|
692
728
|
const audioObjectUrl = URL.createObjectURL(wavBlob);
|
|
693
|
-
if (currentTtsRequestId.value !== requestId) {
|
|
729
|
+
if (signal.aborted || currentTtsRequestId.value !== requestId) {
|
|
694
730
|
URL.revokeObjectURL(audioObjectUrl);
|
|
695
731
|
return;
|
|
696
732
|
}
|
|
@@ -726,16 +762,21 @@ const _sfc_main = {
|
|
|
726
762
|
}
|
|
727
763
|
}
|
|
728
764
|
} catch (e) {
|
|
765
|
+
if ((e == null ? void 0 : e.name) === "AbortError") throw e;
|
|
729
766
|
console.warn("[OmniVoice] 轮询失败:", e.message);
|
|
730
767
|
}
|
|
731
768
|
}
|
|
732
769
|
if (audioUrl) {
|
|
733
770
|
if (audioUrl.startsWith("/")) audioUrl = baseUrl + audioUrl;
|
|
734
771
|
console.log("[OmniVoice] 下载音频:", audioUrl);
|
|
735
|
-
if (currentTtsRequestId.value !== requestId) return;
|
|
736
|
-
const audioRes = await fetch(audioUrl);
|
|
772
|
+
if (signal.aborted || currentTtsRequestId.value !== requestId) return;
|
|
773
|
+
const audioRes = await fetch(audioUrl, { signal });
|
|
737
774
|
const audioBlob = await audioRes.blob();
|
|
738
775
|
const audioObjectUrl = URL.createObjectURL(audioBlob);
|
|
776
|
+
if (signal.aborted || currentTtsRequestId.value !== requestId) {
|
|
777
|
+
URL.revokeObjectURL(audioObjectUrl);
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
739
780
|
currentAudio.value = new Audio(audioObjectUrl);
|
|
740
781
|
currentAudio.value.onplaying = () => {
|
|
741
782
|
console.log("[OmniVoice] 音频开始播放");
|
|
@@ -759,6 +800,10 @@ const _sfc_main = {
|
|
|
759
800
|
standby();
|
|
760
801
|
}
|
|
761
802
|
} catch (e) {
|
|
803
|
+
if ((e == null ? void 0 : e.name) === "AbortError") {
|
|
804
|
+
console.log("[OmniVoice] TTS已取消");
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
762
807
|
console.error("[OmniVoice] TTS失败:", e);
|
|
763
808
|
standby();
|
|
764
809
|
}
|
|
@@ -870,6 +915,7 @@ const _sfc_main = {
|
|
|
870
915
|
init();
|
|
871
916
|
});
|
|
872
917
|
vue.onUnmounted(() => {
|
|
918
|
+
abortTTS();
|
|
873
919
|
stop();
|
|
874
920
|
if (recorder2.value) {
|
|
875
921
|
recorder2.value.stop();
|
|
@@ -889,7 +935,7 @@ const _sfc_main = {
|
|
|
889
935
|
};
|
|
890
936
|
}
|
|
891
937
|
};
|
|
892
|
-
const DigitalHuman = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
938
|
+
const DigitalHuman = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-90fb7a29"]]);
|
|
893
939
|
DigitalHuman.install = (app) => app.component("DigitalHuman", DigitalHuman);
|
|
894
940
|
const components = [DemoButton, DemoInput, DigitalHuman];
|
|
895
941
|
const install = (app) => {
|
package/dist/ruiyun-human.es.js
CHANGED
|
@@ -552,6 +552,7 @@ const _sfc_main = {
|
|
|
552
552
|
runAnimation("speak");
|
|
553
553
|
};
|
|
554
554
|
const stopSpeaking = () => {
|
|
555
|
+
abortTTS();
|
|
555
556
|
if (animationState.value === "speak" || animationState.value === "speakLoop") {
|
|
556
557
|
runAnimation("speakEnd");
|
|
557
558
|
} else {
|
|
@@ -627,13 +628,44 @@ const _sfc_main = {
|
|
|
627
628
|
};
|
|
628
629
|
const currentAudio = ref(null);
|
|
629
630
|
const currentTtsRequestId = ref(null);
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
631
|
+
let ttsAbortController = null;
|
|
632
|
+
function abortTTS() {
|
|
633
|
+
currentTtsRequestId.value = null;
|
|
634
|
+
if (ttsAbortController) {
|
|
635
|
+
try {
|
|
636
|
+
ttsAbortController.abort();
|
|
637
|
+
} catch {
|
|
638
|
+
}
|
|
639
|
+
ttsAbortController = null;
|
|
640
|
+
}
|
|
633
641
|
if (currentAudio.value) {
|
|
634
|
-
|
|
642
|
+
try {
|
|
643
|
+
currentAudio.value.pause();
|
|
644
|
+
} catch {
|
|
645
|
+
}
|
|
635
646
|
currentAudio.value = null;
|
|
636
647
|
}
|
|
648
|
+
}
|
|
649
|
+
function waitWithSignal(ms, signal) {
|
|
650
|
+
return new Promise((resolve, reject) => {
|
|
651
|
+
if (signal == null ? void 0 : signal.aborted) {
|
|
652
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
const timer = setTimeout(resolve, ms);
|
|
656
|
+
const onAbort = () => {
|
|
657
|
+
clearTimeout(timer);
|
|
658
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
659
|
+
};
|
|
660
|
+
signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
const playTTS = async (text) => {
|
|
664
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
665
|
+
if (!text || !((_a = currentHuman.value) == null ? void 0 : _a.isMuted)) return;
|
|
666
|
+
abortTTS();
|
|
667
|
+
ttsAbortController = new AbortController();
|
|
668
|
+
const { signal } = ttsAbortController;
|
|
637
669
|
currentTtsRequestId.value = Date.now();
|
|
638
670
|
const requestId = currentTtsRequestId.value;
|
|
639
671
|
try {
|
|
@@ -649,7 +681,8 @@ const _sfc_main = {
|
|
|
649
681
|
const joinRes = await fetch(`${baseUrl}/gradio_api/queue/join`, {
|
|
650
682
|
method: "POST",
|
|
651
683
|
headers: { "Content-Type": "application/json" },
|
|
652
|
-
body: JSON.stringify({ data, session_hash: sessionHash, fn_index: 1, trigger_id: 50 })
|
|
684
|
+
body: JSON.stringify({ data, session_hash: sessionHash, fn_index: 1, trigger_id: 50 }),
|
|
685
|
+
signal
|
|
653
686
|
});
|
|
654
687
|
const joinData = await joinRes.json();
|
|
655
688
|
console.log("[OmniVoice] Step1 响应:", joinData);
|
|
@@ -658,10 +691,13 @@ const _sfc_main = {
|
|
|
658
691
|
let maxPolls = 60;
|
|
659
692
|
let pollInterval = 1e3;
|
|
660
693
|
while (!audioUrl && maxPolls > 0) {
|
|
661
|
-
|
|
694
|
+
if (signal.aborted || currentTtsRequestId.value !== requestId) return;
|
|
695
|
+
await waitWithSignal(pollInterval, signal);
|
|
662
696
|
maxPolls--;
|
|
663
697
|
try {
|
|
664
|
-
const pollRes = await fetch(`${baseUrl}/gradio_api/queue/data?session_hash=${sessionHash}
|
|
698
|
+
const pollRes = await fetch(`${baseUrl}/gradio_api/queue/data?session_hash=${sessionHash}`, {
|
|
699
|
+
signal
|
|
700
|
+
});
|
|
665
701
|
const pollText = await pollRes.text();
|
|
666
702
|
const lines = pollText.split("\n");
|
|
667
703
|
for (const line of lines) {
|
|
@@ -688,7 +724,7 @@ const _sfc_main = {
|
|
|
688
724
|
}
|
|
689
725
|
const wavBlob = createWavBlob(audioBuffer, samplingRate, 1, 16);
|
|
690
726
|
const audioObjectUrl = URL.createObjectURL(wavBlob);
|
|
691
|
-
if (currentTtsRequestId.value !== requestId) {
|
|
727
|
+
if (signal.aborted || currentTtsRequestId.value !== requestId) {
|
|
692
728
|
URL.revokeObjectURL(audioObjectUrl);
|
|
693
729
|
return;
|
|
694
730
|
}
|
|
@@ -724,16 +760,21 @@ const _sfc_main = {
|
|
|
724
760
|
}
|
|
725
761
|
}
|
|
726
762
|
} catch (e) {
|
|
763
|
+
if ((e == null ? void 0 : e.name) === "AbortError") throw e;
|
|
727
764
|
console.warn("[OmniVoice] 轮询失败:", e.message);
|
|
728
765
|
}
|
|
729
766
|
}
|
|
730
767
|
if (audioUrl) {
|
|
731
768
|
if (audioUrl.startsWith("/")) audioUrl = baseUrl + audioUrl;
|
|
732
769
|
console.log("[OmniVoice] 下载音频:", audioUrl);
|
|
733
|
-
if (currentTtsRequestId.value !== requestId) return;
|
|
734
|
-
const audioRes = await fetch(audioUrl);
|
|
770
|
+
if (signal.aborted || currentTtsRequestId.value !== requestId) return;
|
|
771
|
+
const audioRes = await fetch(audioUrl, { signal });
|
|
735
772
|
const audioBlob = await audioRes.blob();
|
|
736
773
|
const audioObjectUrl = URL.createObjectURL(audioBlob);
|
|
774
|
+
if (signal.aborted || currentTtsRequestId.value !== requestId) {
|
|
775
|
+
URL.revokeObjectURL(audioObjectUrl);
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
737
778
|
currentAudio.value = new Audio(audioObjectUrl);
|
|
738
779
|
currentAudio.value.onplaying = () => {
|
|
739
780
|
console.log("[OmniVoice] 音频开始播放");
|
|
@@ -757,6 +798,10 @@ const _sfc_main = {
|
|
|
757
798
|
standby();
|
|
758
799
|
}
|
|
759
800
|
} catch (e) {
|
|
801
|
+
if ((e == null ? void 0 : e.name) === "AbortError") {
|
|
802
|
+
console.log("[OmniVoice] TTS已取消");
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
760
805
|
console.error("[OmniVoice] TTS失败:", e);
|
|
761
806
|
standby();
|
|
762
807
|
}
|
|
@@ -868,6 +913,7 @@ const _sfc_main = {
|
|
|
868
913
|
init();
|
|
869
914
|
});
|
|
870
915
|
onUnmounted(() => {
|
|
916
|
+
abortTTS();
|
|
871
917
|
stop();
|
|
872
918
|
if (recorder2.value) {
|
|
873
919
|
recorder2.value.stop();
|
|
@@ -887,7 +933,7 @@ const _sfc_main = {
|
|
|
887
933
|
};
|
|
888
934
|
}
|
|
889
935
|
};
|
|
890
|
-
const DigitalHuman = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
936
|
+
const DigitalHuman = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-90fb7a29"]]);
|
|
891
937
|
DigitalHuman.install = (app) => app.component("DigitalHuman", DigitalHuman);
|
|
892
938
|
const components = [DemoButton, DemoInput, DigitalHuman];
|
|
893
939
|
const install = (app) => {
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.demo-btn[data-v-9a48516a]{padding:6px 14px;border-radius:4px;border:none;cursor:pointer;font-size:14px}.primary[data-v-9a48516a]{background:#409eff;color:#fff}.success[data-v-9a48516a]{background:#67c23a;color:#fff}.warning[data-v-9a48516a]{background:#e6a23c;color:#fff}.demo-input-wrap[data-v-28a3493c]{display:inline-flex;align-items:center;border:1px solid #dcdcdc;border-radius:4px;padding:0 10px}.demo-input-wrap[data-v-28a3493c]:focus-within{border-color:#409eff}.demo-input[data-v-28a3493c]{border:none;outline:none;padding:8px 6px;flex:1}.prefix[data-v-28a3493c],.suffix[data-v-28a3493c]{color:#909399}.digital-human[data-v-
|
|
1
|
+
.demo-btn[data-v-9a48516a]{padding:6px 14px;border-radius:4px;border:none;cursor:pointer;font-size:14px}.primary[data-v-9a48516a]{background:#409eff;color:#fff}.success[data-v-9a48516a]{background:#67c23a;color:#fff}.warning[data-v-9a48516a]{background:#e6a23c;color:#fff}.demo-input-wrap[data-v-28a3493c]{display:inline-flex;align-items:center;border:1px solid #dcdcdc;border-radius:4px;padding:0 10px}.demo-input-wrap[data-v-28a3493c]:focus-within{border-color:#409eff}.demo-input[data-v-28a3493c]{border:none;outline:none;padding:8px 6px;flex:1}.prefix[data-v-28a3493c],.suffix[data-v-28a3493c]{color:#909399}.digital-human[data-v-90fb7a29]{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.digital-human canvas[data-v-90fb7a29]{max-width:100%;max-height:100%}
|