libbitsub 1.0.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.
@@ -0,0 +1,342 @@
1
+ /**
2
+ * Web Worker management for libbitsub.
3
+ * Handles off-main-thread subtitle parsing and rendering.
4
+ */
5
+ import { getWasmUrl } from './wasm';
6
+ let sharedWorker = null;
7
+ let workerInitPromise = null;
8
+ let messageId = 0;
9
+ const pendingCallbacks = new Map();
10
+ /** Check if Web Workers are available. */
11
+ export function isWorkerAvailable() {
12
+ return typeof Worker !== 'undefined' && typeof window !== 'undefined' && typeof Blob !== 'undefined';
13
+ }
14
+ /** Create inline worker script with embedded WASM loader. */
15
+ function createWorkerScript() {
16
+ return `
17
+ let wasmModule = null;
18
+ let pgsParser = null;
19
+ let vobSubParser = null;
20
+
21
+ // Minimal WASM bindings (inlined from wasm-bindgen output)
22
+ let wasm;
23
+ let cachedUint8Memory = null;
24
+ let WASM_VECTOR_LEN = 0;
25
+ let cachedTextEncoder = new TextEncoder();
26
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
27
+
28
+ function getUint8Memory() {
29
+ if (cachedUint8Memory === null || cachedUint8Memory.byteLength === 0) {
30
+ cachedUint8Memory = new Uint8Array(wasm.memory.buffer);
31
+ }
32
+ return cachedUint8Memory;
33
+ }
34
+
35
+ function passArray8ToWasm(arg) {
36
+ const ptr = wasm.__wbindgen_malloc(arg.length);
37
+ getUint8Memory().set(arg, ptr);
38
+ WASM_VECTOR_LEN = arg.length;
39
+ return ptr;
40
+ }
41
+
42
+ const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
43
+ ? function (arg, view) {
44
+ return cachedTextEncoder.encodeInto(arg, view);
45
+ }
46
+ : function (arg, view) {
47
+ const buf = cachedTextEncoder.encode(arg);
48
+ view.set(buf);
49
+ return { read: arg.length, written: buf.length };
50
+ });
51
+
52
+ function passStringToWasm(arg) {
53
+ let len = arg.length;
54
+ let ptr = wasm.__wbindgen_malloc(len);
55
+ const mem = getUint8Memory();
56
+ let offset = 0;
57
+ for (; offset < len; offset++) {
58
+ const code = arg.charCodeAt(offset);
59
+ if (code > 0x7F) break;
60
+ mem[ptr + offset] = code;
61
+ }
62
+ if (offset !== len) {
63
+ if (offset !== 0) arg = arg.slice(offset);
64
+ ptr = wasm.__wbindgen_realloc(ptr, len, len = offset + arg.length * 3);
65
+ const view = getUint8Memory().subarray(ptr + offset, ptr + len);
66
+ const ret = encodeString(arg, view);
67
+ offset += ret.written;
68
+ }
69
+ WASM_VECTOR_LEN = offset;
70
+ return ptr;
71
+ }
72
+
73
+ function getStringFromWasm(ptr, len) {
74
+ return cachedTextDecoder.decode(getUint8Memory().subarray(ptr, ptr + len));
75
+ }
76
+
77
+ async function initWasm(wasmUrl) {
78
+ if (wasm) return;
79
+
80
+ console.log('[libbitsub worker] Fetching WASM from:', wasmUrl);
81
+ const response = await fetch(wasmUrl);
82
+ if (!response.ok) {
83
+ throw new Error('Failed to fetch WASM: ' + response.status);
84
+ }
85
+
86
+ // Try to load the JS glue file
87
+ const jsGlueUrl = wasmUrl.replace('_bg.wasm', '.js').replace('.wasm', '.js');
88
+ console.log('[libbitsub worker] Loading JS glue from:', jsGlueUrl);
89
+
90
+ try {
91
+ const mod = await import(/* webpackIgnore: true */ jsGlueUrl);
92
+ const wasmBytes = await response.arrayBuffer();
93
+ await mod.default(wasmBytes);
94
+ wasmModule = mod;
95
+ wasm = mod.__wasm || mod;
96
+ console.log('[libbitsub worker] WASM initialized via JS glue');
97
+ } catch (jsError) {
98
+ console.warn('[libbitsub worker] JS glue import failed, using direct instantiation:', jsError.message);
99
+
100
+ // Fallback: direct WASM instantiation (limited functionality)
101
+ const wasmBytes = await response.arrayBuffer();
102
+ const result = await WebAssembly.instantiate(wasmBytes, {
103
+ __wbindgen_placeholder__: {
104
+ __wbindgen_throw: function(ptr, len) {
105
+ throw new Error(getStringFromWasm(ptr, len));
106
+ }
107
+ }
108
+ });
109
+ wasm = result.instance.exports;
110
+
111
+ // Create minimal module interface
112
+ wasmModule = {
113
+ PgsParser: class {
114
+ constructor() { this.ptr = wasm.pgsparser_new(); }
115
+ parse(data) {
116
+ const ptr = passArray8ToWasm(data);
117
+ return wasm.pgsparser_parse(this.ptr, ptr, WASM_VECTOR_LEN);
118
+ }
119
+ getTimestamps() {
120
+ return wasm.pgsparser_getTimestamps(this.ptr);
121
+ }
122
+ renderAtIndex(idx) { return wasm.pgsparser_renderAtIndex(this.ptr, idx); }
123
+ findIndexAtTimestamp(ts) { return wasm.pgsparser_findIndexAtTimestamp(this.ptr, ts); }
124
+ clearCache() { wasm.pgsparser_clearCache(this.ptr); }
125
+ free() { wasm.pgsparser_free(this.ptr); }
126
+ get count() { return wasm.pgsparser_count(this.ptr); }
127
+ },
128
+ VobSubParser: class {
129
+ constructor() { this.ptr = wasm.vobsubparser_new(); }
130
+ loadFromData(idx, sub) {
131
+ const idxPtr = passStringToWasm(idx);
132
+ const subPtr = passArray8ToWasm(sub);
133
+ wasm.vobsubparser_loadFromData(this.ptr, idxPtr, WASM_VECTOR_LEN, subPtr, sub.length);
134
+ }
135
+ loadFromSubOnly(sub) {
136
+ const ptr = passArray8ToWasm(sub);
137
+ wasm.vobsubparser_loadFromSubOnly(this.ptr, ptr, WASM_VECTOR_LEN);
138
+ }
139
+ getTimestamps() {
140
+ return wasm.vobsubparser_getTimestamps(this.ptr);
141
+ }
142
+ renderAtIndex(idx) { return wasm.vobsubparser_renderAtIndex(this.ptr, idx); }
143
+ findIndexAtTimestamp(ts) { return wasm.vobsubparser_findIndexAtTimestamp(this.ptr, ts); }
144
+ clearCache() { wasm.vobsubparser_clearCache(this.ptr); }
145
+ free() { wasm.vobsubparser_free(this.ptr); }
146
+ get count() { return wasm.vobsubparser_count(this.ptr); }
147
+ }
148
+ };
149
+ console.log('[libbitsub worker] WASM initialized via direct instantiation');
150
+ }
151
+ }
152
+
153
+ function convertFrame(frame, isVobSub) {
154
+ const compositions = [];
155
+ if (isVobSub) {
156
+ const rgba = frame.getRgba();
157
+ if (frame.width > 0 && frame.height > 0 && rgba.length === frame.width * frame.height * 4) {
158
+ const rgbaCopy = new Uint8Array(rgba.length);
159
+ rgbaCopy.set(rgba);
160
+ compositions.push({ rgba: rgbaCopy, x: frame.x, y: frame.y, width: frame.width, height: frame.height });
161
+ }
162
+ return { width: frame.screenWidth, height: frame.screenHeight, compositions };
163
+ }
164
+ for (let i = 0; i < frame.compositionCount; i++) {
165
+ const comp = frame.getComposition(i);
166
+ if (!comp) continue;
167
+ const rgba = comp.getRgba();
168
+ if (comp.width > 0 && comp.height > 0 && rgba.length === comp.width * comp.height * 4) {
169
+ const rgbaCopy = new Uint8Array(rgba.length);
170
+ rgbaCopy.set(rgba);
171
+ compositions.push({ rgba: rgbaCopy, x: comp.x, y: comp.y, width: comp.width, height: comp.height });
172
+ }
173
+ }
174
+ return { width: frame.width, height: frame.height, compositions };
175
+ }
176
+
177
+ function postResponse(response, transfer, id) {
178
+ if (id !== undefined) response._id = id;
179
+ self.postMessage(response, transfer?.length ? transfer : undefined);
180
+ }
181
+
182
+ self.onmessage = async function(event) {
183
+ const { _id, ...request } = event.data;
184
+ try {
185
+ switch (request.type) {
186
+ case 'init':
187
+ await initWasm(request.wasmUrl);
188
+ postResponse({ type: 'initComplete', success: true }, [], _id);
189
+ break;
190
+ case 'loadPgs':
191
+ pgsParser = new wasmModule.PgsParser();
192
+ const pgsCount = pgsParser.parse(new Uint8Array(request.data));
193
+ postResponse({ type: 'pgsLoaded', count: pgsCount, byteLength: request.data.byteLength }, [], _id);
194
+ break;
195
+ case 'loadVobSub':
196
+ vobSubParser = new wasmModule.VobSubParser();
197
+ vobSubParser.loadFromData(request.idxContent, new Uint8Array(request.subData));
198
+ postResponse({ type: 'vobSubLoaded', count: vobSubParser.count }, [], _id);
199
+ break;
200
+ case 'loadVobSubOnly':
201
+ vobSubParser = new wasmModule.VobSubParser();
202
+ vobSubParser.loadFromSubOnly(new Uint8Array(request.subData));
203
+ postResponse({ type: 'vobSubLoaded', count: vobSubParser.count }, [], _id);
204
+ break;
205
+ case 'renderPgsAtIndex': {
206
+ if (!pgsParser) { postResponse({ type: 'pgsFrame', frame: null }, [], _id); break; }
207
+ const frame = pgsParser.renderAtIndex(request.index);
208
+ if (!frame) { postResponse({ type: 'pgsFrame', frame: null }, [], _id); break; }
209
+ const frameData = convertFrame(frame, false);
210
+ postResponse({ type: 'pgsFrame', frame: frameData }, frameData.compositions.map(c => c.rgba.buffer), _id);
211
+ break;
212
+ }
213
+ case 'renderVobSubAtIndex': {
214
+ if (!vobSubParser) { postResponse({ type: 'vobSubFrame', frame: null }, [], _id); break; }
215
+ const frame = vobSubParser.renderAtIndex(request.index);
216
+ if (!frame) { postResponse({ type: 'vobSubFrame', frame: null }, [], _id); break; }
217
+ const frameData = convertFrame(frame, true);
218
+ postResponse({ type: 'vobSubFrame', frame: frameData }, frameData.compositions.map(c => c.rgba.buffer), _id);
219
+ break;
220
+ }
221
+ case 'findPgsIndex':
222
+ postResponse({ type: 'pgsIndex', index: pgsParser?.findIndexAtTimestamp(request.timeMs) ?? -1 }, [], _id);
223
+ break;
224
+ case 'findVobSubIndex':
225
+ postResponse({ type: 'vobSubIndex', index: vobSubParser?.findIndexAtTimestamp(request.timeMs) ?? -1 }, [], _id);
226
+ break;
227
+ case 'getPgsTimestamps':
228
+ postResponse({ type: 'pgsTimestamps', timestamps: pgsParser?.getTimestamps() ?? new Float64Array(0) }, [], _id);
229
+ break;
230
+ case 'getVobSubTimestamps':
231
+ postResponse({ type: 'vobSubTimestamps', timestamps: vobSubParser?.getTimestamps() ?? new Float64Array(0) }, [], _id);
232
+ break;
233
+ case 'clearPgsCache':
234
+ pgsParser?.clearCache();
235
+ postResponse({ type: 'cleared' }, [], _id);
236
+ break;
237
+ case 'clearVobSubCache':
238
+ vobSubParser?.clearCache();
239
+ postResponse({ type: 'cleared' }, [], _id);
240
+ break;
241
+ case 'disposePgs':
242
+ pgsParser?.free(); pgsParser = null;
243
+ postResponse({ type: 'disposed' }, [], _id);
244
+ break;
245
+ case 'disposeVobSub':
246
+ vobSubParser?.free(); vobSubParser = null;
247
+ postResponse({ type: 'disposed' }, [], _id);
248
+ break;
249
+ }
250
+ } catch (error) {
251
+ postResponse({ type: 'error', message: error instanceof Error ? error.message : String(error) }, [], _id);
252
+ }
253
+ };`;
254
+ }
255
+ /** Create or get the shared worker instance. */
256
+ export function getOrCreateWorker() {
257
+ if (sharedWorker)
258
+ return Promise.resolve(sharedWorker);
259
+ if (workerInitPromise)
260
+ return workerInitPromise;
261
+ workerInitPromise = new Promise((resolve, reject) => {
262
+ try {
263
+ console.log('[libbitsub] Creating worker...');
264
+ const blob = new Blob([createWorkerScript()], { type: 'application/javascript' });
265
+ const workerUrl = URL.createObjectURL(blob);
266
+ const worker = new Worker(workerUrl, { type: 'module' });
267
+ worker.onmessage = (event) => {
268
+ const { _id, ...response } = event.data;
269
+ if (_id !== undefined) {
270
+ const callback = pendingCallbacks.get(_id);
271
+ if (callback) {
272
+ pendingCallbacks.delete(_id);
273
+ callback.resolve(response);
274
+ }
275
+ }
276
+ };
277
+ worker.onerror = (error) => {
278
+ console.error('[libbitsub] Worker error:', error);
279
+ if (workerInitPromise) {
280
+ workerInitPromise = null;
281
+ reject(error);
282
+ }
283
+ };
284
+ sharedWorker = worker;
285
+ const wasmUrl = getWasmUrl();
286
+ console.log('[libbitsub] Initializing worker with WASM URL:', wasmUrl);
287
+ sendToWorker({ type: 'init', wasmUrl })
288
+ .then(() => {
289
+ console.log('[libbitsub] Worker initialized successfully');
290
+ URL.revokeObjectURL(workerUrl);
291
+ resolve(worker);
292
+ })
293
+ .catch((err) => {
294
+ console.error('[libbitsub] Worker initialization failed:', err);
295
+ URL.revokeObjectURL(workerUrl);
296
+ sharedWorker = null;
297
+ workerInitPromise = null;
298
+ reject(err);
299
+ });
300
+ }
301
+ catch (error) {
302
+ console.error('[libbitsub] Failed to create worker:', error);
303
+ workerInitPromise = null;
304
+ reject(error);
305
+ }
306
+ });
307
+ return workerInitPromise;
308
+ }
309
+ /** Default timeout for worker operations (30 seconds for large files) */
310
+ const WORKER_TIMEOUT = 30000;
311
+ /** Send a message to the worker with timeout support. */
312
+ export function sendToWorker(request, timeout = WORKER_TIMEOUT) {
313
+ return new Promise((resolve, reject) => {
314
+ if (!sharedWorker) {
315
+ reject(new Error('Worker not initialized'));
316
+ return;
317
+ }
318
+ const id = ++messageId;
319
+ // Set up timeout
320
+ const timeoutId = setTimeout(() => {
321
+ pendingCallbacks.delete(id);
322
+ reject(new Error(`Worker operation timed out after ${timeout}ms`));
323
+ }, timeout);
324
+ pendingCallbacks.set(id, {
325
+ resolve: (response) => {
326
+ clearTimeout(timeoutId);
327
+ resolve(response);
328
+ },
329
+ reject: (error) => {
330
+ clearTimeout(timeoutId);
331
+ reject(error);
332
+ }
333
+ });
334
+ const transfers = [];
335
+ if ('data' in request && request.data instanceof ArrayBuffer)
336
+ transfers.push(request.data);
337
+ if ('subData' in request && request.subData instanceof ArrayBuffer)
338
+ transfers.push(request.subData);
339
+ sharedWorker.postMessage({ ...request, _id: id }, transfers);
340
+ });
341
+ }
342
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/ts/worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * TypeScript wrapper for the libbitsub Rust rendering engine.
3
+ * Provides a compatible API with the original libpgs-js implementation.
4
+ */
5
+ export type { SubtitleData, SubtitleCompositionData, SubtitleDisplaySettings, VideoSubtitleOptions, VideoVobSubOptions, RenderResult, SubtitleFrame, VobSubFrame } from './ts/types';
6
+ export { initWasm, isWasmInitialized } from './ts/wasm';
7
+ export { PgsParser, VobSubParserLowLevel, UnifiedSubtitleParser } from './ts/parsers';
8
+ export { PgsRenderer, VobSubRenderer, type SubtitleRendererStats } from './ts/renderers';
9
+ import { PgsRenderer as _PgsRenderer, VobSubRenderer as _VobSubRenderer } from './ts/renderers';
10
+ import { UnifiedSubtitleParser as _UnifiedSubtitleParser } from './ts/parsers';
11
+ /** @deprecated Use PgsRenderer instead */
12
+ export declare const PGSRenderer: typeof _PgsRenderer;
13
+ /** @deprecated Use VobSubRenderer instead */
14
+ export declare const VobsubRenderer: typeof _VobSubRenderer;
15
+ /** @deprecated Use UnifiedSubtitleParser instead */
16
+ export declare const UnifiedSubtitleRenderer: typeof _UnifiedSubtitleParser;
17
+ //# sourceMappingURL=wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper.d.ts","sourceRoot":"","sources":["../src/wrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,YAAY,EACZ,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,WAAW,EACZ,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAGvD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAGrF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAMxF,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAE9E,0CAA0C;AAC1C,eAAO,MAAM,WAAW,qBAAe,CAAA;AAEvC,6CAA6C;AAC7C,eAAO,MAAM,cAAc,wBAAkB,CAAA;AAE7C,oDAAoD;AACpD,eAAO,MAAM,uBAAuB,+BAAyB,CAAA"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * TypeScript wrapper for the libbitsub Rust rendering engine.
3
+ * Provides a compatible API with the original libpgs-js implementation.
4
+ */
5
+ // Re-export WASM management
6
+ export { initWasm, isWasmInitialized } from './ts/wasm';
7
+ // Re-export parsers
8
+ export { PgsParser, VobSubParserLowLevel, UnifiedSubtitleParser } from './ts/parsers';
9
+ // Re-export renderers
10
+ export { PgsRenderer, VobSubRenderer } from './ts/renderers';
11
+ // =============================================================================
12
+ // Legacy Aliases (for backward compatibility)
13
+ // =============================================================================
14
+ import { PgsRenderer as _PgsRenderer, VobSubRenderer as _VobSubRenderer } from './ts/renderers';
15
+ import { UnifiedSubtitleParser as _UnifiedSubtitleParser } from './ts/parsers';
16
+ /** @deprecated Use PgsRenderer instead */
17
+ export const PGSRenderer = _PgsRenderer;
18
+ /** @deprecated Use VobSubRenderer instead */
19
+ export const VobsubRenderer = _VobSubRenderer;
20
+ /** @deprecated Use UnifiedSubtitleParser instead */
21
+ export const UnifiedSubtitleRenderer = _UnifiedSubtitleParser;
22
+ //# sourceMappingURL=wrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../src/wrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,4BAA4B;AAC5B,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAEvD,oBAAoB;AACpB,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAErF,sBAAsB;AACtB,OAAO,EAAE,WAAW,EAAE,cAAc,EAA8B,MAAM,gBAAgB,CAAA;AAExF,gFAAgF;AAChF,8CAA8C;AAC9C,gFAAgF;AAEhF,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAE9E,0CAA0C;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAA;AAEvC,6CAA6C;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAA;AAE7C,oDAAoD;AACpD,MAAM,CAAC,MAAM,uBAAuB,GAAG,sBAAsB,CAAA"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "libbitsub",
3
+ "version": "1.0.0",
4
+ "author": "altqx",
5
+ "license": "GPL-3.0-only",
6
+ "description": "High-performance WASM renderer for graphical subtitles (PGS and VobSub)",
7
+ "keywords": [
8
+ "libbitsub",
9
+ "pgs",
10
+ "vobsub",
11
+ "subtitle",
12
+ "wasm",
13
+ "rust",
14
+ "rendering"
15
+ ],
16
+ "main": "dist/index.js",
17
+ "module": "dist/index.js",
18
+ "types": "dist/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "import": "./dist/index.js",
22
+ "require": "./dist/index.js",
23
+ "types": "./dist/index.d.ts"
24
+ },
25
+ "./pkg": {
26
+ "import": "./pkg/libbitsub.js",
27
+ "types": "./pkg/libbitsub.d.ts"
28
+ }
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "pkg",
33
+ "src/wrapper.ts"
34
+ ],
35
+ "scripts": {
36
+ "build:wasm": "wasm-pack build --target web --out-dir pkg",
37
+ "build:wasm:release": "wasm-pack build --release --target web --out-dir pkg",
38
+ "build:wasm:bundler": "wasm-pack build --target bundler --out-dir pkg-bundler",
39
+ "build:ts": "tsc",
40
+ "build": "bun run build:wasm:release && bun run build:ts",
41
+ "clean": "rm -rf pkg pkg-bundler dist target",
42
+ "test": "cargo test",
43
+ "test:wasm": "wasm-pack test --headless --chrome",
44
+ "format": "cargo fmt && prettier . --write"
45
+ },
46
+ "devDependencies": {
47
+ "prettier": "^3.7.4",
48
+ "typescript": "^5.9.3"
49
+ },
50
+ "peerDependencies": {},
51
+ "engines": {
52
+ "node": ">=18"
53
+ }
54
+ }