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