@twkevinzhang/lyric-align-ts 0.0.0-stage → 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 lyric-align-ts contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,51 @@
1
- # Temporary Holding Version
1
+ # @twkevinzhang/lyric-align-ts
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 瀏覽器端 Whisper ASR 與歌詞對齊,提供 contract v1 的 session API。ES module only;推論在 session 專用 module Worker 執行。
4
+
5
+ ## 使用
6
+
7
+ ```sh
8
+ npm install @twkevinzhang/lyric-align-ts
9
+ ```
10
+
11
+ ```ts
12
+ import { binding } from '@twkevinzhang/lyric-align-ts';
13
+
14
+ const controller = new AbortController();
15
+ const context = { signal: controller.signal, onProgress: console.log };
16
+ const session = await binding.createSession();
17
+ try {
18
+ await session.prepare({ language: 'en' }, context);
19
+ const segments = await session.transcribe(
20
+ { pcm, sampleRate: 16000 }, // 完整、單聲道、有限數值 Float32Array
21
+ { language: 'en' },
22
+ context,
23
+ );
24
+ const lines = await session.align(segments, lyrics, { karaoke: false }, context);
25
+ // 整首驗證成功後才套用字幕,所有時間為秒。
26
+ } finally {
27
+ await session.dispose();
28
+ }
29
+ ```
30
+
31
+ `pcm`、逐行 `lyrics` 由應用提供。套件不下載音訊、不控制播放器、不建立字幕或 SRT。空白行由應用保留於原文、排除於 align 輸入;其他行逐字保留、不插補。消費端須驗證全部行數、順序、原文、匹配與時間界限後才一次套用,score 是文字相似度,不是時間準確率。
32
+
33
+ 預設 WebGPU,固定 `onnx-community/whisper-small.en_timestamped`、revision `8085393831131554ad978a4e438295a734d3d2c0`、q4,僅支援 `en`。另可 `createBinding({ device: 'wasm' })` 明確選擇既有 WASM 配置,不自動 fallback。`capabilities.lyricsContext=false`,不要傳歌詞提示。支援 pairing、threshold、window、karaoke=false;預設 auto/window4/文字門檻。
34
+
35
+ ## 執行環境與資源
36
+
37
+ 需要支援 module Worker、WebAssembly 及所選後端的桌面瀏覽器、安全來源與足夠記憶體。這不是 Node.js 推論套件。包內含固定版 Transformers.js、ONNX Runtime Web 與壓縮 runtime,沒有額外 npm runtime dependencies。模型權重不含於 npm 包,prepare 首次向 Hugging Face 下載固定 revision 並由瀏覽器快取;音訊及歌詞不會上傳至推論服務。
38
+
39
+ 使用支援 Worker/`new URL(..., import.meta.url)` 資源處理的 bundler。若直接靜態載入,完整複製安裝目錄並保留 index.js 與 assets/ 的相對路徑。其他 bundler、extension offscreen/CSP 需自行驗證。host 啟用 COEP 時,Worker 回應必須使用相符 header;CSP 與 host permissions 必須允許 Worker、WASM、模型取得及 runtime 必要資源。
40
+
41
+ ## 生命週期
42
+
43
+ 同 session 依序等待 prepare → transcribe → align,不並行。`controller.abort()` 終止專用 Worker,操作拒絕 `{ code: 'ABORTED', message }`;等待操作結束後再 dispose,重試另建 session。dispose 可重複呼叫,操作尚未結束時會拒絕提前 dispose。
44
+
45
+ 錯誤為 `{ code, message }`。進度階段為 preparing-model、transcribing、aligning;sequence 在每次操作內從 1 遞增。有實測 total 才回報 measured(bytes/items 及 scope),否則為 indeterminate,不應推估百分比。
46
+
47
+ ## 驗證與限制
48
+
49
+ Chrome WebGPU 真實完整 130.30 秒英文音訊:6 ASR 段、12/12 行合法匹配,原文與順序保持;真實推論中途取消及重複 dispose 已測。這不是任意歌曲品質承諾。WASM 核心另有既有驗證,但不代表已重測 npm 安裝後的 WASM 全曲、其他硬體或消費端 extension。
50
+
51
+ 原創程式碼採 MIT;衍生演算法與內含依賴保留各自授權。詳見 LICENSE、THIRD_PARTY_NOTICES.md 與 licenses/。模型權重另外受模型來源授權約束。
@@ -0,0 +1,17 @@
1
+ # Third-party notices
2
+
3
+ The MIT license for lyric-align-ts applies to original project code. Third-party code retains its own license. Dependencies are bundled in the Worker artifact.
4
+
5
+ | Component | Version / source | License / notice |
6
+ | --- | --- | --- |
7
+ | lyric-align rules (TypeScript adaptation) | ebe62d8a8628d0b2579987598f0442ebffcc68bb | licenses/upstream.LICENSE (MIT) |
8
+ | faster-whisper / CTranslate2 rules (TypeScript adaptation) | 1.2.1 / 4.8.3 | licenses/asr-upstream.LICENSE (MIT) |
9
+ | Transformers.js | 4.3.1 | licenses/transformers.LICENSE (Apache-2.0) |
10
+ | Hugging Face tokenizers / jinja (included in Transformers.js browser bundle) | 0.2.0 / 0.5.10 | licenses/tokenizers.LICENSE (Apache-2.0), licenses/jinja.LICENSE (MIT) |
11
+ | ONNX Runtime Web | 1.31.0-dev.20260914-8d85527a0 | licenses/onnxruntime.LICENSE (MIT), licenses/onnxruntime.NOTICE |
12
+ | ONNX Runtime Common | 1.30.0 and Web runtime's 1.31.0-dev.20260911-2a43ec07e | licenses/onnxruntime.LICENSE (MIT) |
13
+ | pako | 3.0.2 | licenses/pako.LICENSE (MIT), licenses/pako-zlib.LICENSE (Zlib) |
14
+
15
+ ONNX Runtime notices are preserved from upstream commit 8d85527a010e294a26b274749f74294b2a32cec5. The complete upstream notice file covers multiple distributions and may list components not used by this browser build.
16
+
17
+ Model weights are not distributed in this package. The fixed Hugging Face revision is downloaded separately at prepare time; consult the model repository for its license. The upstream Python/C++ libraries are not executed by this TypeScript adaptation.
@@ -0,0 +1,4 @@
1
+ [diffend] Oversized file quarantined before diffing.
2
+ name: package/assets/worker-CNw7yNoM.js
3
+ size: 72223391 bytes
4
+ sha256: ddf0d50e0489cf472a47370b960743c4777837074859c73e0985713cb18b62f0
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./types/binding/index.js";
package/index.js ADDED
@@ -0,0 +1,130 @@
1
+ // app/lib/protocol.ts
2
+ var e = {
3
+ id: "onnx-community/whisper-small.en_timestamped",
4
+ revision: "8085393831131554ad978a4e438295a734d3d2c0"
5
+ };
6
+ // app/lib/binding/errors.ts
7
+ function t(e, t) {
8
+ return {
9
+ code: e,
10
+ message: t
11
+ };
12
+ }
13
+ var n = [
14
+ "UNSUPPORTED_LANGUAGE",
15
+ "UNSUPPORTED_DEVICE",
16
+ "UNSUPPORTED_OPTION",
17
+ "MODEL_LOAD_FAILED",
18
+ "INVALID_INPUT",
19
+ "OUT_OF_MEMORY",
20
+ "TRANSCRIPTION_FAILED",
21
+ "ALIGNMENT_FAILED",
22
+ "ABORTED"
23
+ ];
24
+ function r(e, r) {
25
+ if (e && typeof e == "object" && "code" in e && n.includes(String(e.code)) && "message" in e && typeof e.message == "string") return e;
26
+ let i = e instanceof Error ? e.message : String(e);
27
+ return t(/out of memory|allocation failed|memory access out of bounds/i.test(i) ? "OUT_OF_MEMORY" : r, i);
28
+ }
29
+ // app/lib/binding/transport.ts
30
+ function i(e, n) {
31
+ let i = 0, a = !1, o = !1, s, c, l = () => {
32
+ o || (o = !0, e.terminate());
33
+ }, u = (e, t) => {
34
+ let n = c;
35
+ n && (c = void 0, n.cleanup(), e ? n.reject(r(e, n.code)) : n.resolve(t));
36
+ }, d = (e) => {
37
+ a = !0, l(), u(t(c?.code ?? "INVALID_INPUT", e));
38
+ };
39
+ e.onerror = (e) => {
40
+ e.preventDefault(), d(e.message || "Worker crashed");
41
+ }, e.onmessageerror = () => d("Worker response could not be deserialized"), e.onmessage = ({ data: e }) => {
42
+ if (c && e.id === c.id) {
43
+ if (e.progress) try {
44
+ c.context?.onProgress?.(e.progress);
45
+ } catch {}
46
+ else u(e.error, e.result);
47
+ }
48
+ };
49
+ function f(r, o, s, d) {
50
+ return a || c ? Promise.reject(t("INVALID_INPUT", a ? "Session disposed or terminated" : "Session already busy")) : d?.signal.aborted ? Promise.reject(t("ABORTED", "Operation aborted")) : new Promise((f, p) => {
51
+ let m = () => {
52
+ a = !0, l(), u(t("ABORTED", "Operation aborted; session worker terminated"));
53
+ };
54
+ c = {
55
+ id: ++i,
56
+ code: s,
57
+ context: d,
58
+ resolve: (e) => f(e),
59
+ reject: p,
60
+ cleanup: () => d?.signal.removeEventListener("abort", m)
61
+ }, d?.signal.addEventListener("abort", m, { once: !0 });
62
+ try {
63
+ e.postMessage({
64
+ id: i,
65
+ method: r,
66
+ args: o,
67
+ device: n
68
+ });
69
+ } catch (e) {
70
+ a = !0, l(), u(e);
71
+ }
72
+ });
73
+ }
74
+ return {
75
+ prepare: (e, t) => f("prepare", [e], "MODEL_LOAD_FAILED", t),
76
+ transcribe: (e, t, n) => f("transcribe", [e, t], "TRANSCRIPTION_FAILED", n),
77
+ align: (e, t, n, r) => f("align", [
78
+ e,
79
+ t,
80
+ n
81
+ ], "ALIGNMENT_FAILED", r),
82
+ dispose() {
83
+ if (!s) {
84
+ if (c) return Promise.reject(t("INVALID_INPUT", "Wait for active operation before dispose"));
85
+ s = a ? Promise.resolve() : f("dispose", [], "INVALID_INPUT"), a = !0, s = s.finally(l);
86
+ }
87
+ return s;
88
+ }
89
+ };
90
+ }
91
+ // app/lib/binding/index.ts
92
+ function a(n = {}) {
93
+ let r = n.device ?? "webgpu";
94
+ if (r !== "wasm" && r !== "webgpu") throw t("UNSUPPORTED_DEVICE", "Supported devices: wasm, webgpu");
95
+ for (let e of Object.keys(n)) if (e !== "device") throw t("UNSUPPORTED_OPTION", `Unsupported binding option: ${e}`);
96
+ let a = Object.freeze({
97
+ contractVersion: 1,
98
+ libraryVersion: "0.1.0",
99
+ supportedLanguages: Object.freeze(["en"]),
100
+ model: Object.freeze({
101
+ ...e,
102
+ device: r,
103
+ dtype: "q4"
104
+ }),
105
+ alignmentOptions: Object.freeze([
106
+ "pairing",
107
+ "threshold",
108
+ "window",
109
+ "karaoke"
110
+ ]),
111
+ lyricsContext: !1
112
+ });
113
+ return Object.freeze({
114
+ capabilities: a,
115
+ async createSession() {
116
+ if (typeof Worker > "u" || r === "webgpu" && (typeof navigator > "u" || !navigator.gpu)) throw t("UNSUPPORTED_DEVICE", `Browser ${r} worker support is required`);
117
+ try {
118
+ return i(new Worker(new URL(
119
+ /* @vite-ignore */
120
+ new URL("assets/worker-CNw7yNoM.js", import.meta.url).href,
121
+ "" + import.meta.url
122
+ ), { type: "module" }), r);
123
+ } catch (e) {
124
+ throw t("UNSUPPORTED_DEVICE", e instanceof Error ? e.message : String(e));
125
+ }
126
+ }
127
+ });
128
+ }
129
+ var o = a();
130
+ export { o as binding, a as createBinding };
@@ -0,0 +1,70 @@
1
+ ASR control and alignment rules derived from faster-whisper 1.2.1 and CTranslate2 4.8.3.
2
+
3
+ MIT License
4
+
5
+ Copyright (c) 2023 SYSTRAN
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+
25
+ MIT License
26
+
27
+ Copyright (c) 2018- SYSTRAN.
28
+ Copyright (c) 2019- The OpenNMT Authors.
29
+
30
+ Permission is hereby granted, free of charge, to any person obtaining a copy
31
+ of this software and associated documentation files (the "Software"), to deal
32
+ in the Software without restriction, including without limitation the rights
33
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ copies of the Software, and to permit persons to whom the Software is
35
+ furnished to do so, subject to the following conditions:
36
+
37
+ The above copyright notice and this permission notice shall be included in all
38
+ copies or substantial portions of the Software.
39
+
40
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
43
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
46
+ SOFTWARE.
47
+
48
+ Bundled compression dependency: pako 3.0.2
49
+
50
+ (The MIT License)
51
+
52
+ Copyright (C) 2014-2017 by Vitaly Puzrin and Andrei Tuputcyn
53
+
54
+ Permission is hereby granted, free of charge, to any person obtaining a copy
55
+ of this software and associated documentation files (the "Software"), to deal
56
+ in the Software without restriction, including without limitation the rights
57
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
58
+ copies of the Software, and to permit persons to whom the Software is
59
+ furnished to do so, subject to the following conditions:
60
+
61
+ The above copyright notice and this permission notice shall be included in
62
+ all copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
65
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
66
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
67
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
68
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
69
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
70
+ THE SOFTWARE.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Hugging Face
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Microsoft Corporation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.