speakdrill 0.2.6 → 0.2.11

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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Rust 實作,含 CLI、TUI 與原生 GUI(egui,不是 Electron / Tauri webview)。
6
6
 
7
- > 目前只支援 **Windows x64**(相依 VoiceMeeter)。
7
+ > 目前只支援 **Windows x64**。可選用 **VB-CABLE**(零設定、自動安裝)或 **VoiceMeeter**(Banana/Potato)。
8
8
 
9
9
  ## 安裝
10
10
 
@@ -28,10 +28,11 @@ speakdrill doctor
28
28
  ## 快速開始
29
29
 
30
30
  ```bash
31
- speakdrill init # 偵測裝置、寫設定、設 VoiceMeeter 路由、拉音量
31
+ speakdrill init # 偵測裝置、寫設定、自動安裝 VB-CABLE 或設 VoiceMeeter 路由、拉音量
32
+ speakdrill setup # 自動完成 per-app 麥克風綁定(原本需手動在 ms-settings:apps-volume 設定)
32
33
  speakdrill doctor # 檢查環境
33
- speakdrill # 終端機介面(預設)
34
- speakdrill list # 列出課程
34
+ speakdrill # 終端機介面(預設)
35
+ speakdrill list # 列出課程
35
36
  speakdrill-gui # 原生 GUI
36
37
  speakdrill run --lesson <ID> --course <ID>
37
38
  speakdrill batch --code <CODE> --limit 5
@@ -40,12 +41,12 @@ speakdrill reset # 還原音訊路由
40
41
 
41
42
  ## 前置需求
42
43
 
43
- 1. **VoiceMeeter**(Banana 或 Potato)
44
+ 1. **VB-CABLE**(推薦,零設定)或 **VoiceMeeter**(Banana / Potato)
45
+ - `speakdrill init --install-driver` 會自動下載並安裝 VB-CABLE(需管理員權限)
46
+ - 已安裝 VoiceMeeter 者可直接使用,`init` 會偵測並設定路由
44
47
  2. **不需要額外裝 TTS**:`speakdrill init` 自動下載 Piper
45
- 3. 目標 App 需開啟 debug port:
46
- `--remote-debugging-port=9222 --remote-allow-origins=*`
47
- 4. 在 `ms-settings:apps-volume` 把目標 App 的**輸入裝置**設成 `Voicemeeter Out B1`
48
- (這步只能用介面做,Windows 會產生綁定 GUID)
48
+ 3. **MyET 的 debug port**:TUI 啟動時會自動檢查 port 9222,沒連上就自動啟動 MyET(帶 `--remote-debugging-port=9222 --remote-allow-origins=*`);也可以在 TUI 裡按 `m` 手動啟動
49
+ 4. **per-app 麥克風綁定**:`speakdrill setup` 會自動完成(原本需手動在 `ms-settings:apps-volume` 設定),VB-CABLE 時會綁定 `CABLE Output (VB-Audio Virtual Cable)`,VoiceMeeter 時綁定 `Voicemeeter Out B1`
49
50
 
50
51
  ## 文件
51
52
 
@@ -53,4 +54,4 @@ speakdrill reset # 還原音訊路由
53
54
 
54
55
  ## 授權
55
56
 
56
- MIT
57
+ MIT
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "speakdrill",
3
- "version": "0.2.6",
4
- "description": "口說課程自動化練習:TTS 產生示範語音、逐句驅動課程演練、輸出分數報告(Rust,含 TUI / 原生 GUI)",
3
+ "version": "0.2.11",
4
+ "description": "\u53e3\u8aaa\u8ab2\u7a0b\u81ea\u52d5\u5316\u7df4\u7fd2\uff1aTTS \u7522\u751f\u793a\u7bc4\u8a9e\u97f3\u3001\u9010\u53e5\u9a45\u52d5\u8ab2\u7a0b\u6f14\u7df4\u3001\u8f38\u51fa\u5206\u6578\u5831\u544a\uff08Rust\uff0c\u542b TUI / \u539f\u751f GUI\uff09",
5
5
  "keywords": [
6
6
  "speaking",
7
7
  "shadowing",
8
8
  "drill",
9
9
  "tts",
10
10
  "voicemeeter",
11
+ "vb-cable",
11
12
  "english",
12
13
  "cli",
13
14
  "tui",
@@ -25,7 +26,8 @@
25
26
  "speakdrill-gui": "bin/speakdrill-gui.js"
26
27
  },
27
28
  "files": [
28
- "bin/",
29
+ "bin/speakdrill.js",
30
+ "bin/speakdrill-gui.js",
29
31
  "scripts/",
30
32
  "README.md",
31
33
  "LICENSE"
@@ -42,10 +44,4 @@
42
44
  "cpu": [
43
45
  "x64"
44
46
  ]
45
- }
46
-
47
-
48
-
49
-
50
-
51
-
47
+ }
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * 安裝時下載對應平台的原生二進位。
3
+ * speakdrill 安裝腳本:從 GitHub Releases 下載預編譯執行檔。
4
4
  *
5
- * 環境變數:
6
- * SPEAKDRILL_SKIP_DOWNLOAD=1 跳過下載(本機開發用,會直接用 target/ 的執行檔)
7
- * SPEAKDRILL_VERSION 指定版本(預設讀 package.json)
5
+ * 停用下載:
6
+ * SPEAKDRILL_SKIP_DOWNLOAD=1 跳過下載(可改讀 target/ 的本機 build)
7
+ * SPEAKDRILL_VERSION 覆寫版本(預設讀 package.json)
8
8
  * SPEAKDRILL_REPO 覆寫 GitHub repo(預設 thumb2086/speakdrill)
9
9
  */
10
10
  const fs = require('fs');
@@ -17,14 +17,12 @@ const VERSION = process.env.SPEAKDRILL_VERSION || pkg.version;
17
17
  const REPO = process.env.SPEAKDRILL_REPO || 'thumb2086/speakdrill';
18
18
 
19
19
  if (process.env.SPEAKDRILL_SKIP_DOWNLOAD === '1') {
20
- console.log('[speakdrill] SPEAKDRILL_SKIP_DOWNLOAD=1,跳過下載');
20
+ console.log('[speakdrill] SPEAKDRILL_SKIP_DOWNLOAD=1;跳過下載');
21
21
  process.exit(0);
22
22
  }
23
23
 
24
24
  if (process.platform !== 'win32') {
25
- console.log(
26
- `[speakdrill] 目前只支援 Windows(需要 VoiceMeeter)。你的平台是 ${process.platform},跳過安裝。`
27
- );
25
+ console.log(`[speakdrill] 目前僅支援 Windows(VB-CABLE / VoiceMeeter);本平台為 ${process.platform},跳過安裝`);
28
26
  process.exit(0);
29
27
  }
30
28
 
@@ -39,7 +37,7 @@ const url = `https://github.com/${REPO}/releases/download/${tag}/${asset}`;
39
37
  function download(u, dest) {
40
38
  return new Promise((resolve, reject) => {
41
39
  const go = (u2, depth = 0) => {
42
- if (depth > 5) return reject(new Error('太多重新導向'));
40
+ if (depth > 5) return reject(new Error('too many redirects'));
43
41
  https
44
42
  .get(u2, { headers: { 'User-Agent': 'speakdrill-installer' } }, (res) => {
45
43
  if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
@@ -60,16 +58,25 @@ function download(u, dest) {
60
58
  });
61
59
  }
62
60
 
61
+ function ensure(outDir) {
62
+ for (const exe of exes) {
63
+ const p = path.join(outDir, exe);
64
+ if (!fs.existsSync(p)) {
65
+ throw new Error(`安裝後找不到 ${exe}(解壓或下載失敗)`);
66
+ }
67
+ }
68
+ }
69
+
70
+ function rmrf(p) {
71
+ if (fs.existsSync(p)) fs.rmSync(p, { recursive: true, force: true });
72
+ }
73
+
63
74
  (async () => {
75
+ // 每次安裝都重新下載並解壓,避免沿用舊 exe 造成版本錯位
76
+ rmrf(outDir);
64
77
  fs.mkdirSync(outDir, { recursive: true });
65
78
  const archive = path.join(outDir, asset);
66
79
 
67
- const existing = path.join(outDir, exes[0]);
68
- if (fs.existsSync(existing)) {
69
- console.log(`[speakdrill] 已存在 ${existing}`);
70
- return;
71
- }
72
-
73
80
  console.log(`[speakdrill] 下載 ${url}`);
74
81
  try {
75
82
  await download(url, archive);
@@ -80,10 +87,11 @@ function download(u, dest) {
80
87
  { stdio: 'inherit' }
81
88
  );
82
89
  fs.unlinkSync(archive);
83
- console.log(`[speakdrill] 安裝完成 → ${outDir}`);
90
+ ensure(outDir);
91
+ console.log(`[speakdrill] 安裝完成:${outDir}`);
84
92
  } catch (e) {
85
- console.error(`[speakdrill] 下載失敗:${e.message}`);
86
- console.error('[speakdrill] 可改用手動安裝,或設定 SPEAKDRILL_SKIP_DOWNLOAD=1 使用本機建置');
87
- process.exit(0); // 不讓 npm install 整個失敗
93
+ console.error(`[speakdrill] 下載/解壓失敗:${e.message}`);
94
+ console.error('[speakdrill] 可改用 SPEAKDRILL_SKIP_DOWNLOAD=1 略過下載');
95
+ process.exit(1);
88
96
  }
89
- })();
97
+ })();