dsh-liuying-voice 1.3.2 → 1.5.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/lib/client.js +94 -0
- package/package.json +1 -1
- package/scripts/install-gpt-sovits.ps1 +30 -12
package/lib/client.js
CHANGED
|
@@ -7,6 +7,7 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
factory: (require) => {
|
|
8
8
|
const React = require("react");
|
|
9
9
|
const h = React.createElement;
|
|
10
|
+
const { createPortal } = require("react-dom");
|
|
10
11
|
|
|
11
12
|
const FIELD_DEFS = [
|
|
12
13
|
{ key: "enabled", label: "启用", type: "boolean" },
|
|
@@ -616,6 +617,85 @@ window.__ModuleLoader__.load({
|
|
|
616
617
|
);
|
|
617
618
|
}
|
|
618
619
|
|
|
620
|
+
// 侧边栏底部按钮:点开弹窗显示独立设置页(不跳浏览器)
|
|
621
|
+
function SidebarButton() {
|
|
622
|
+
const [open, setOpen] = React.useState(false);
|
|
623
|
+
const overlay = open
|
|
624
|
+
? h(
|
|
625
|
+
"div",
|
|
626
|
+
{
|
|
627
|
+
onClick: () => setOpen(false),
|
|
628
|
+
style: {
|
|
629
|
+
position: "fixed",
|
|
630
|
+
inset: 0,
|
|
631
|
+
zIndex: 9999,
|
|
632
|
+
background: "rgba(0,0,0,0.55)",
|
|
633
|
+
display: "flex",
|
|
634
|
+
alignItems: "center",
|
|
635
|
+
justifyContent: "center",
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
h(
|
|
639
|
+
"div",
|
|
640
|
+
{
|
|
641
|
+
onClick: (e) => e.stopPropagation(),
|
|
642
|
+
style: {
|
|
643
|
+
width: "min(900px, 92vw)",
|
|
644
|
+
height: "min(680px, 88vh)",
|
|
645
|
+
background: "#0f1417",
|
|
646
|
+
borderRadius: 12,
|
|
647
|
+
overflow: "hidden",
|
|
648
|
+
boxShadow: "0 24px 70px rgba(0,0,0,0.55)",
|
|
649
|
+
display: "flex",
|
|
650
|
+
flexDirection: "column",
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
h(
|
|
654
|
+
"div",
|
|
655
|
+
{ style: { display: "flex", alignItems: "center", gap: 8, padding: "8px 12px", borderBottom: "1px solid #243036" } },
|
|
656
|
+
h("span", { style: { fontSize: 13, color: "#8fd8c8", flex: 1 } }, "流萤语音"),
|
|
657
|
+
h(
|
|
658
|
+
"button",
|
|
659
|
+
{
|
|
660
|
+
type: "button",
|
|
661
|
+
onClick: () => setOpen(false),
|
|
662
|
+
style: { border: "1px solid #2a383f", background: "#1c262b", color: "#cfe3e6", borderRadius: 6, padding: "4px 12px", cursor: "pointer" },
|
|
663
|
+
},
|
|
664
|
+
"关闭",
|
|
665
|
+
),
|
|
666
|
+
),
|
|
667
|
+
h("iframe", { src: "/liuying-voice", title: "liuying-voice", style: { flex: 1, border: 0, width: "100%", background: "#0f1417" } }),
|
|
668
|
+
),
|
|
669
|
+
)
|
|
670
|
+
: null;
|
|
671
|
+
return h(
|
|
672
|
+
React.Fragment,
|
|
673
|
+
null,
|
|
674
|
+
h(
|
|
675
|
+
"button",
|
|
676
|
+
{
|
|
677
|
+
type: "button",
|
|
678
|
+
onClick: () => setOpen(true),
|
|
679
|
+
title: "流萤语音设置",
|
|
680
|
+
style: {
|
|
681
|
+
display: "flex",
|
|
682
|
+
alignItems: "center",
|
|
683
|
+
gap: 6,
|
|
684
|
+
padding: "4px 10px",
|
|
685
|
+
borderRadius: 6,
|
|
686
|
+
border: "1px solid var(--dsh-border, #555)",
|
|
687
|
+
background: "transparent",
|
|
688
|
+
color: "inherit",
|
|
689
|
+
cursor: "pointer",
|
|
690
|
+
fontSize: 12,
|
|
691
|
+
},
|
|
692
|
+
},
|
|
693
|
+
"🔊 流萤",
|
|
694
|
+
),
|
|
695
|
+
open && typeof document !== "undefined" ? createPortal(overlay, document.body) : null,
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
|
|
619
699
|
function apply(ctx) {
|
|
620
700
|
const mount = () => {
|
|
621
701
|
if (!ctx.slots?.register) return;
|
|
@@ -639,6 +719,20 @@ window.__ModuleLoader__.load({
|
|
|
639
719
|
};
|
|
640
720
|
});
|
|
641
721
|
|
|
722
|
+
ctx.slots.inject("sidebar.footer.action", () => {
|
|
723
|
+
if (!ctx.slots?.register) return () => {};
|
|
724
|
+
return ctx.slots.register(
|
|
725
|
+
{
|
|
726
|
+
name: "sidebar.footer.action",
|
|
727
|
+
id: "liuying-voice-footer",
|
|
728
|
+
order: 100,
|
|
729
|
+
label: () => "流萤语音",
|
|
730
|
+
inject: () => ({}),
|
|
731
|
+
},
|
|
732
|
+
SidebarButton,
|
|
733
|
+
);
|
|
734
|
+
});
|
|
735
|
+
|
|
642
736
|
ctx.slots.inject("conversation.chat.assistant-actions", () => {
|
|
643
737
|
if (!ctx.slots?.register) return () => {};
|
|
644
738
|
return ctx.slots.register(
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ============================================================
|
|
1
|
+
# ============================================================
|
|
2
2
|
# GPT-SoVITS 简易环境安装脚本(CPU 推理,配合 dsh-liuying-voice 使用)
|
|
3
3
|
#
|
|
4
4
|
# 做什么:
|
|
@@ -26,11 +26,29 @@ New-Item -ItemType Directory -Path $root -Force | Out-Null
|
|
|
26
26
|
|
|
27
27
|
# 1. Python
|
|
28
28
|
$python = $null
|
|
29
|
-
foreach ($cand in @('python3.11', 'python3.10'
|
|
29
|
+
foreach ($cand in @('python3.11', 'python3.10')) {
|
|
30
30
|
$cmd = Get-Command $cand -ErrorAction SilentlyContinue
|
|
31
31
|
if ($cmd) { $python = $cmd.Source; break }
|
|
32
32
|
}
|
|
33
|
-
if (-not $python) {
|
|
33
|
+
if (-not $python) {
|
|
34
|
+
$pyDir = Join-Path $root 'python'
|
|
35
|
+
$pyExe = Join-Path $pyDir 'python.exe'
|
|
36
|
+
if (-not (Test-Path $pyExe)) {
|
|
37
|
+
Step '未找到 Python 3.10/3.11,下载便携版 3.11(约 10 MB)'
|
|
38
|
+
$zipFile = Join-Path $root 'python311-embed.zip'
|
|
39
|
+
Invoke-WebRequest -Uri 'https://www.python.org/ftp/python/3.11.9/python-3.11.9-embed-amd64.zip' -OutFile $zipFile -TimeoutSec 600
|
|
40
|
+
Expand-Archive -Path $zipFile -DestinationPath $pyDir -Force
|
|
41
|
+
$pth = Join-Path $pyDir 'python311._pth'
|
|
42
|
+
if (Test-Path $pth) {
|
|
43
|
+
$lines = Get-Content $pth | ForEach-Object { if ($_ -match '^#\s*import site') { 'import site' } else { $_ } }
|
|
44
|
+
[System.IO.File]::WriteAllLines($pth, $lines, (New-Object System.Text.UTF8Encoding($false)))
|
|
45
|
+
}
|
|
46
|
+
$gp = Join-Path $pyDir 'get-pip.py'
|
|
47
|
+
Invoke-WebRequest -Uri 'https://bootstrap.pypa.io/get-pip.py' -OutFile $gp -TimeoutSec 300
|
|
48
|
+
& $pyExe $gp --no-warn-script-location
|
|
49
|
+
}
|
|
50
|
+
$python = $pyExe
|
|
51
|
+
}
|
|
34
52
|
Write-Host "Python: $python"
|
|
35
53
|
|
|
36
54
|
# 2. 源码
|
|
@@ -41,18 +59,18 @@ if (-not (Test-Path (Join-Path $repo 'api_v2.py'))) {
|
|
|
41
59
|
}
|
|
42
60
|
if (-not (Test-Path (Join-Path $repo 'api_v2.py'))) { throw "源码下载失败,请检查网络或代理" }
|
|
43
61
|
|
|
44
|
-
# 3.
|
|
45
|
-
$
|
|
46
|
-
if (-not (Test-Path (Join-Path $venv 'Scripts\python.exe'))) {
|
|
47
|
-
Step '创建虚拟环境'
|
|
48
|
-
& $python -m venv $venv
|
|
49
|
-
}
|
|
50
|
-
$py = Join-Path $venv 'Scripts\python.exe'
|
|
62
|
+
# 3. 依赖(直接装到检测到的 Python,便携版也不需要 venv)
|
|
63
|
+
$py = $python
|
|
51
64
|
& $py -m pip install -U pip -i $pipIndex
|
|
65
|
+
# 先装 numpy:pyopenjtalk 等包构建时需要
|
|
66
|
+
& $py -m pip install numpy -i $pipIndex
|
|
52
67
|
|
|
53
|
-
Step '
|
|
68
|
+
Step '安装推理依赖(阿里镜像;pyopenjtalk 若编译失败需要 VS Build Tools,会跳过继续)'
|
|
54
69
|
& $py -m pip install -r (Join-Path $repo 'requirements.txt') -i $pipIndex
|
|
55
|
-
|
|
70
|
+
if ($LASTEXITCODE -ne 0) {
|
|
71
|
+
Write-Warning '部分依赖安装失败(pyopenjtalk 需要 C++ 构建工具),继续安装 torch,缺失的可稍后补'
|
|
72
|
+
}
|
|
73
|
+
& $py -m pip install torch==2.7.1 torchaudio==2.7.1 --index-url https://download.pytorch.org/whl/cpu
|
|
56
74
|
|
|
57
75
|
# 4. 预训练
|
|
58
76
|
$pretrained = Join-Path $repo 'GPT_SoVITS\pretrained_models'
|