libbitsub 1.5.1 → 1.7.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/README.md +262 -223
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/ts/parsers.d.ts +18 -1
- package/dist/ts/parsers.d.ts.map +1 -1
- package/dist/ts/parsers.js +151 -0
- package/dist/ts/parsers.js.map +1 -1
- package/dist/ts/renderers.d.ts +54 -4
- package/dist/ts/renderers.d.ts.map +1 -1
- package/dist/ts/renderers.js +457 -87
- package/dist/ts/renderers.js.map +1 -1
- package/dist/ts/types.d.ts +147 -3
- package/dist/ts/types.d.ts.map +1 -1
- package/dist/ts/utils.d.ts +11 -1
- package/dist/ts/utils.d.ts.map +1 -1
- package/dist/ts/utils.js +100 -1
- package/dist/ts/utils.js.map +1 -1
- package/dist/ts/wasm.js.map +1 -1
- package/dist/ts/webgl2-renderer.d.ts +57 -0
- package/dist/ts/webgl2-renderer.d.ts.map +1 -0
- package/dist/ts/webgl2-renderer.js +293 -0
- package/dist/ts/webgl2-renderer.js.map +1 -0
- package/dist/ts/webgpu-renderer.d.ts +5 -1
- package/dist/ts/webgpu-renderer.d.ts.map +1 -1
- package/dist/ts/webgpu-renderer.js +64 -45
- package/dist/ts/webgpu-renderer.js.map +1 -1
- package/dist/ts/worker.d.ts.map +1 -1
- package/dist/ts/worker.js +145 -87
- package/dist/ts/worker.js.map +1 -1
- package/dist/wrapper.d.ts +3 -2
- package/dist/wrapper.d.ts.map +1 -1
- package/dist/wrapper.js +3 -1
- package/dist/wrapper.js.map +1 -1
- package/package.json +3 -2
- package/pkg/README.md +262 -223
- package/pkg/libbitsub.d.ts +120 -0
- package/pkg/libbitsub.js +251 -15
- package/pkg/libbitsub_bg.wasm +0 -0
- package/pkg/libbitsub_bg.wasm.d.ts +24 -0
- package/pkg/package.json +1 -1
- package/src/wrapper.ts +14 -1
package/dist/ts/worker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/ts/worker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAe5D,0CAA0C;AAC1C,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/ts/worker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAe5D,0CAA0C;AAC1C,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAkUD,gDAAgD;AAChD,wBAAgB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAgDnD;AAKD,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,SAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CA8BtG"}
|
package/dist/ts/worker.js
CHANGED
|
@@ -15,15 +15,13 @@ export function isWorkerAvailable() {
|
|
|
15
15
|
function createWorkerScript() {
|
|
16
16
|
return `
|
|
17
17
|
let wasmModule = null;
|
|
18
|
-
let pgsParser = null;
|
|
19
|
-
let vobSubParser = null;
|
|
20
|
-
|
|
21
|
-
// Minimal WASM bindings (inlined from wasm-bindgen output)
|
|
22
18
|
let wasm;
|
|
23
19
|
let cachedUint8Memory = null;
|
|
24
20
|
let WASM_VECTOR_LEN = 0;
|
|
25
21
|
let cachedTextEncoder = new TextEncoder();
|
|
26
22
|
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
23
|
+
const pgsParsers = new Map();
|
|
24
|
+
const vobSubParsers = new Map();
|
|
27
25
|
|
|
28
26
|
function getUint8Memory() {
|
|
29
27
|
if (cachedUint8Memory === null || cachedUint8Memory.byteLength === 0) {
|
|
@@ -39,15 +37,13 @@ function passArray8ToWasm(arg) {
|
|
|
39
37
|
return ptr;
|
|
40
38
|
}
|
|
41
39
|
|
|
42
|
-
const encodeString =
|
|
43
|
-
? function (arg, view)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return { read: arg.length, written: buf.length };
|
|
50
|
-
});
|
|
40
|
+
const encodeString = typeof cachedTextEncoder.encodeInto === 'function'
|
|
41
|
+
? function(arg, view) { return cachedTextEncoder.encodeInto(arg, view); }
|
|
42
|
+
: function(arg, view) {
|
|
43
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
44
|
+
view.set(buf);
|
|
45
|
+
return { read: arg.length, written: buf.length };
|
|
46
|
+
};
|
|
51
47
|
|
|
52
48
|
function passStringToWasm(arg) {
|
|
53
49
|
let len = arg.length;
|
|
@@ -74,30 +70,57 @@ function getStringFromWasm(ptr, len) {
|
|
|
74
70
|
return cachedTextDecoder.decode(getUint8Memory().subarray(ptr, ptr + len));
|
|
75
71
|
}
|
|
76
72
|
|
|
73
|
+
function buildPgsMetadata(parser) {
|
|
74
|
+
return {
|
|
75
|
+
format: 'pgs',
|
|
76
|
+
cueCount: parser.count,
|
|
77
|
+
screenWidth: parser.screenWidth || 0,
|
|
78
|
+
screenHeight: parser.screenHeight || 0
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function buildVobSubMetadata(parser) {
|
|
83
|
+
return {
|
|
84
|
+
format: 'vobsub',
|
|
85
|
+
cueCount: parser.count,
|
|
86
|
+
screenWidth: parser.screenWidth || 0,
|
|
87
|
+
screenHeight: parser.screenHeight || 0,
|
|
88
|
+
language: parser.language || '',
|
|
89
|
+
trackId: parser.trackId || '',
|
|
90
|
+
hasIdxMetadata: !!parser.hasIdxMetadata
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function disposeSession(sessionId) {
|
|
95
|
+
const pgsParser = pgsParsers.get(sessionId);
|
|
96
|
+
if (pgsParser) {
|
|
97
|
+
pgsParser.free();
|
|
98
|
+
pgsParsers.delete(sessionId);
|
|
99
|
+
}
|
|
100
|
+
const vobSubParser = vobSubParsers.get(sessionId);
|
|
101
|
+
if (vobSubParser) {
|
|
102
|
+
vobSubParser.free();
|
|
103
|
+
vobSubParsers.delete(sessionId);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
77
107
|
async function initWasm(wasmUrl) {
|
|
78
108
|
if (wasm) return;
|
|
79
|
-
|
|
80
|
-
console.log('[libbitsub worker] Fetching WASM from:', wasmUrl);
|
|
109
|
+
|
|
81
110
|
const response = await fetch(wasmUrl);
|
|
82
111
|
if (!response.ok) {
|
|
83
112
|
throw new Error('Failed to fetch WASM: ' + response.status);
|
|
84
113
|
}
|
|
85
|
-
|
|
86
|
-
// Try to load the JS glue file
|
|
114
|
+
|
|
87
115
|
const jsGlueUrl = wasmUrl.replace('_bg.wasm', '.js').replace('.wasm', '.js');
|
|
88
|
-
|
|
89
|
-
|
|
116
|
+
|
|
90
117
|
try {
|
|
91
118
|
const mod = await import(/* webpackIgnore: true */ jsGlueUrl);
|
|
92
119
|
const wasmBytes = await response.arrayBuffer();
|
|
93
120
|
await mod.default(wasmBytes);
|
|
94
121
|
wasmModule = mod;
|
|
95
122
|
wasm = mod.__wasm || mod;
|
|
96
|
-
|
|
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)
|
|
123
|
+
} catch {
|
|
101
124
|
const wasmBytes = await response.arrayBuffer();
|
|
102
125
|
const result = await WebAssembly.instantiate(wasmBytes, {
|
|
103
126
|
__wbindgen_placeholder__: {
|
|
@@ -107,8 +130,7 @@ async function initWasm(wasmUrl) {
|
|
|
107
130
|
}
|
|
108
131
|
});
|
|
109
132
|
wasm = result.instance.exports;
|
|
110
|
-
|
|
111
|
-
// Create minimal module interface
|
|
133
|
+
|
|
112
134
|
wasmModule = {
|
|
113
135
|
PgsParser: class {
|
|
114
136
|
constructor() { this.ptr = wasm.pgsparser_new(); }
|
|
@@ -116,37 +138,43 @@ async function initWasm(wasmUrl) {
|
|
|
116
138
|
const ptr = passArray8ToWasm(data);
|
|
117
139
|
return wasm.pgsparser_parse(this.ptr, ptr, WASM_VECTOR_LEN);
|
|
118
140
|
}
|
|
119
|
-
getTimestamps() {
|
|
120
|
-
return wasm.pgsparser_getTimestamps(this.ptr);
|
|
121
|
-
}
|
|
141
|
+
getTimestamps() { return wasm.pgsparser_getTimestamps(this.ptr); }
|
|
122
142
|
renderAtIndex(idx) { return wasm.pgsparser_renderAtIndex(this.ptr, idx); }
|
|
123
143
|
findIndexAtTimestamp(ts) { return wasm.pgsparser_findIndexAtTimestamp(this.ptr, ts); }
|
|
124
144
|
clearCache() { wasm.pgsparser_clearCache(this.ptr); }
|
|
125
145
|
free() { wasm.pgsparser_free(this.ptr); }
|
|
126
146
|
get count() { return wasm.pgsparser_count(this.ptr); }
|
|
147
|
+
get screenWidth() { return wasm.pgsparser_screenWidth(this.ptr); }
|
|
148
|
+
get screenHeight() { return wasm.pgsparser_screenHeight(this.ptr); }
|
|
127
149
|
},
|
|
128
150
|
VobSubParser: class {
|
|
129
151
|
constructor() { this.ptr = wasm.vobsubparser_new(); }
|
|
130
152
|
loadFromData(idx, sub) {
|
|
131
153
|
const idxPtr = passStringToWasm(idx);
|
|
154
|
+
const idxLen = WASM_VECTOR_LEN;
|
|
132
155
|
const subPtr = passArray8ToWasm(sub);
|
|
133
|
-
wasm.vobsubparser_loadFromData(this.ptr, idxPtr,
|
|
156
|
+
wasm.vobsubparser_loadFromData(this.ptr, idxPtr, idxLen, subPtr, sub.length);
|
|
134
157
|
}
|
|
135
158
|
loadFromSubOnly(sub) {
|
|
136
159
|
const ptr = passArray8ToWasm(sub);
|
|
137
160
|
wasm.vobsubparser_loadFromSubOnly(this.ptr, ptr, WASM_VECTOR_LEN);
|
|
138
161
|
}
|
|
139
|
-
getTimestamps() {
|
|
140
|
-
return wasm.vobsubparser_getTimestamps(this.ptr);
|
|
141
|
-
}
|
|
162
|
+
getTimestamps() { return wasm.vobsubparser_getTimestamps(this.ptr); }
|
|
142
163
|
renderAtIndex(idx) { return wasm.vobsubparser_renderAtIndex(this.ptr, idx); }
|
|
143
164
|
findIndexAtTimestamp(ts) { return wasm.vobsubparser_findIndexAtTimestamp(this.ptr, ts); }
|
|
144
165
|
clearCache() { wasm.vobsubparser_clearCache(this.ptr); }
|
|
145
166
|
free() { wasm.vobsubparser_free(this.ptr); }
|
|
167
|
+
setDebandEnabled(enabled) { wasm.vobsubparser_setDebandEnabled(this.ptr, enabled); }
|
|
168
|
+
setDebandThreshold(threshold) { wasm.vobsubparser_setDebandThreshold(this.ptr, threshold); }
|
|
169
|
+
setDebandRange(range) { wasm.vobsubparser_setDebandRange(this.ptr, range); }
|
|
146
170
|
get count() { return wasm.vobsubparser_count(this.ptr); }
|
|
171
|
+
get screenWidth() { return wasm.vobsubparser_screenWidth(this.ptr); }
|
|
172
|
+
get screenHeight() { return wasm.vobsubparser_screenHeight(this.ptr); }
|
|
173
|
+
get language() { return wasm.vobsubparser_language(this.ptr); }
|
|
174
|
+
get trackId() { return wasm.vobsubparser_trackId(this.ptr); }
|
|
175
|
+
get hasIdxMetadata() { return !!wasm.vobsubparser_hasIdxMetadata(this.ptr); }
|
|
147
176
|
}
|
|
148
177
|
};
|
|
149
|
-
console.log('[libbitsub worker] WASM initialized via direct instantiation');
|
|
150
178
|
}
|
|
151
179
|
}
|
|
152
180
|
|
|
@@ -161,6 +189,7 @@ function convertFrame(frame, isVobSub) {
|
|
|
161
189
|
}
|
|
162
190
|
return { width: frame.screenWidth, height: frame.screenHeight, compositions };
|
|
163
191
|
}
|
|
192
|
+
|
|
164
193
|
for (let i = 0; i < frame.compositionCount; i++) {
|
|
165
194
|
const comp = frame.getComposition(i);
|
|
166
195
|
if (!comp) continue;
|
|
@@ -171,93 +200,130 @@ function convertFrame(frame, isVobSub) {
|
|
|
171
200
|
compositions.push({ rgba: rgbaCopy, x: comp.x, y: comp.y, width: comp.width, height: comp.height });
|
|
172
201
|
}
|
|
173
202
|
}
|
|
203
|
+
|
|
174
204
|
return { width: frame.width, height: frame.height, compositions };
|
|
175
205
|
}
|
|
176
206
|
|
|
177
207
|
function postResponse(response, transfer, id) {
|
|
178
208
|
if (id !== undefined) response._id = id;
|
|
179
|
-
self.postMessage(response, transfer
|
|
209
|
+
self.postMessage(response, transfer && transfer.length > 0 ? transfer : undefined);
|
|
180
210
|
}
|
|
181
211
|
|
|
182
212
|
self.onmessage = async function(event) {
|
|
183
213
|
const { _id, ...request } = event.data;
|
|
214
|
+
|
|
184
215
|
try {
|
|
185
216
|
switch (request.type) {
|
|
186
|
-
case 'init':
|
|
217
|
+
case 'init': {
|
|
187
218
|
await initWasm(request.wasmUrl);
|
|
188
219
|
postResponse({ type: 'initComplete', success: true }, [], _id);
|
|
189
220
|
break;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
221
|
+
}
|
|
222
|
+
case 'loadPgs': {
|
|
223
|
+
disposeSession(request.sessionId);
|
|
224
|
+
const parser = new wasmModule.PgsParser();
|
|
225
|
+
const count = parser.parse(new Uint8Array(request.data));
|
|
226
|
+
pgsParsers.set(request.sessionId, parser);
|
|
227
|
+
postResponse({ type: 'pgsLoaded', count, byteLength: request.data.byteLength, metadata: buildPgsMetadata(parser) }, [], _id);
|
|
194
228
|
break;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
229
|
+
}
|
|
230
|
+
case 'loadVobSub': {
|
|
231
|
+
disposeSession(request.sessionId);
|
|
232
|
+
const parser = new wasmModule.VobSubParser();
|
|
233
|
+
parser.loadFromData(request.idxContent, new Uint8Array(request.subData));
|
|
234
|
+
vobSubParsers.set(request.sessionId, parser);
|
|
235
|
+
postResponse({ type: 'vobSubLoaded', count: parser.count, metadata: buildVobSubMetadata(parser) }, [], _id);
|
|
199
236
|
break;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
237
|
+
}
|
|
238
|
+
case 'loadVobSubOnly': {
|
|
239
|
+
disposeSession(request.sessionId);
|
|
240
|
+
const parser = new wasmModule.VobSubParser();
|
|
241
|
+
parser.loadFromSubOnly(new Uint8Array(request.subData));
|
|
242
|
+
vobSubParsers.set(request.sessionId, parser);
|
|
243
|
+
postResponse({ type: 'vobSubLoaded', count: parser.count, metadata: buildVobSubMetadata(parser) }, [], _id);
|
|
204
244
|
break;
|
|
245
|
+
}
|
|
205
246
|
case 'renderPgsAtIndex': {
|
|
206
|
-
|
|
207
|
-
|
|
247
|
+
const parser = pgsParsers.get(request.sessionId);
|
|
248
|
+
if (!parser) { postResponse({ type: 'pgsFrame', frame: null }, [], _id); break; }
|
|
249
|
+
const frame = parser.renderAtIndex(request.index);
|
|
208
250
|
if (!frame) { postResponse({ type: 'pgsFrame', frame: null }, [], _id); break; }
|
|
209
251
|
const frameData = convertFrame(frame, false);
|
|
210
|
-
postResponse({ type: 'pgsFrame', frame: frameData }, frameData.compositions.map(c => c.rgba.buffer), _id);
|
|
252
|
+
postResponse({ type: 'pgsFrame', frame: frameData }, frameData.compositions.map((c) => c.rgba.buffer), _id);
|
|
211
253
|
break;
|
|
212
254
|
}
|
|
213
255
|
case 'renderVobSubAtIndex': {
|
|
214
|
-
|
|
215
|
-
|
|
256
|
+
const parser = vobSubParsers.get(request.sessionId);
|
|
257
|
+
if (!parser) { postResponse({ type: 'vobSubFrame', frame: null }, [], _id); break; }
|
|
258
|
+
const frame = parser.renderAtIndex(request.index);
|
|
216
259
|
if (!frame) { postResponse({ type: 'vobSubFrame', frame: null }, [], _id); break; }
|
|
217
260
|
const frameData = convertFrame(frame, true);
|
|
218
|
-
postResponse({ type: 'vobSubFrame', frame: frameData }, frameData.compositions.map(c => c.rgba.buffer), _id);
|
|
261
|
+
postResponse({ type: 'vobSubFrame', frame: frameData }, frameData.compositions.map((c) => c.rgba.buffer), _id);
|
|
219
262
|
break;
|
|
220
263
|
}
|
|
221
|
-
case 'findPgsIndex':
|
|
222
|
-
|
|
264
|
+
case 'findPgsIndex': {
|
|
265
|
+
const parser = pgsParsers.get(request.sessionId);
|
|
266
|
+
postResponse({ type: 'pgsIndex', index: parser ? parser.findIndexAtTimestamp(request.timeMs) : -1 }, [], _id);
|
|
223
267
|
break;
|
|
224
|
-
|
|
225
|
-
|
|
268
|
+
}
|
|
269
|
+
case 'findVobSubIndex': {
|
|
270
|
+
const parser = vobSubParsers.get(request.sessionId);
|
|
271
|
+
postResponse({ type: 'vobSubIndex', index: parser ? parser.findIndexAtTimestamp(request.timeMs) : -1 }, [], _id);
|
|
226
272
|
break;
|
|
227
|
-
|
|
228
|
-
|
|
273
|
+
}
|
|
274
|
+
case 'getPgsTimestamps': {
|
|
275
|
+
const parser = pgsParsers.get(request.sessionId);
|
|
276
|
+
postResponse({ type: 'pgsTimestamps', timestamps: parser ? parser.getTimestamps() : new Float64Array(0) }, [], _id);
|
|
229
277
|
break;
|
|
230
|
-
|
|
231
|
-
|
|
278
|
+
}
|
|
279
|
+
case 'getVobSubTimestamps': {
|
|
280
|
+
const parser = vobSubParsers.get(request.sessionId);
|
|
281
|
+
postResponse({ type: 'vobSubTimestamps', timestamps: parser ? parser.getTimestamps() : new Float64Array(0) }, [], _id);
|
|
232
282
|
break;
|
|
233
|
-
|
|
234
|
-
|
|
283
|
+
}
|
|
284
|
+
case 'clearPgsCache': {
|
|
285
|
+
pgsParsers.get(request.sessionId)?.clearCache();
|
|
235
286
|
postResponse({ type: 'cleared' }, [], _id);
|
|
236
287
|
break;
|
|
237
|
-
|
|
238
|
-
|
|
288
|
+
}
|
|
289
|
+
case 'clearVobSubCache': {
|
|
290
|
+
vobSubParsers.get(request.sessionId)?.clearCache();
|
|
239
291
|
postResponse({ type: 'cleared' }, [], _id);
|
|
240
292
|
break;
|
|
241
|
-
|
|
242
|
-
|
|
293
|
+
}
|
|
294
|
+
case 'disposePgs': {
|
|
295
|
+
const parser = pgsParsers.get(request.sessionId);
|
|
296
|
+
if (parser) {
|
|
297
|
+
parser.free();
|
|
298
|
+
pgsParsers.delete(request.sessionId);
|
|
299
|
+
}
|
|
243
300
|
postResponse({ type: 'disposed' }, [], _id);
|
|
244
301
|
break;
|
|
245
|
-
|
|
246
|
-
|
|
302
|
+
}
|
|
303
|
+
case 'disposeVobSub': {
|
|
304
|
+
const parser = vobSubParsers.get(request.sessionId);
|
|
305
|
+
if (parser) {
|
|
306
|
+
parser.free();
|
|
307
|
+
vobSubParsers.delete(request.sessionId);
|
|
308
|
+
}
|
|
247
309
|
postResponse({ type: 'disposed' }, [], _id);
|
|
248
310
|
break;
|
|
249
|
-
|
|
250
|
-
|
|
311
|
+
}
|
|
312
|
+
case 'setVobSubDebandEnabled': {
|
|
313
|
+
vobSubParsers.get(request.sessionId)?.setDebandEnabled(request.enabled);
|
|
251
314
|
postResponse({ type: 'debandSet' }, [], _id);
|
|
252
315
|
break;
|
|
253
|
-
|
|
254
|
-
|
|
316
|
+
}
|
|
317
|
+
case 'setVobSubDebandThreshold': {
|
|
318
|
+
vobSubParsers.get(request.sessionId)?.setDebandThreshold(request.threshold);
|
|
255
319
|
postResponse({ type: 'debandSet' }, [], _id);
|
|
256
320
|
break;
|
|
257
|
-
|
|
258
|
-
|
|
321
|
+
}
|
|
322
|
+
case 'setVobSubDebandRange': {
|
|
323
|
+
vobSubParsers.get(request.sessionId)?.setDebandRange(request.range);
|
|
259
324
|
postResponse({ type: 'debandSet' }, [], _id);
|
|
260
325
|
break;
|
|
326
|
+
}
|
|
261
327
|
}
|
|
262
328
|
} catch (error) {
|
|
263
329
|
postResponse({ type: 'error', message: error instanceof Error ? error.message : String(error) }, [], _id);
|
|
@@ -272,7 +338,6 @@ export function getOrCreateWorker() {
|
|
|
272
338
|
return workerInitPromise;
|
|
273
339
|
workerInitPromise = new Promise((resolve, reject) => {
|
|
274
340
|
try {
|
|
275
|
-
console.log('[libbitsub] Creating worker...');
|
|
276
341
|
const blob = new Blob([createWorkerScript()], { type: 'application/javascript' });
|
|
277
342
|
const workerUrl = URL.createObjectURL(blob);
|
|
278
343
|
const worker = new Worker(workerUrl, { type: 'module' });
|
|
@@ -287,23 +352,18 @@ export function getOrCreateWorker() {
|
|
|
287
352
|
}
|
|
288
353
|
};
|
|
289
354
|
worker.onerror = (error) => {
|
|
290
|
-
console.error('[libbitsub] Worker error:', error);
|
|
291
355
|
if (workerInitPromise) {
|
|
292
356
|
workerInitPromise = null;
|
|
293
|
-
reject(error);
|
|
357
|
+
reject(error instanceof ErrorEvent ? new Error(error.message) : new Error(String(error)));
|
|
294
358
|
}
|
|
295
359
|
};
|
|
296
360
|
sharedWorker = worker;
|
|
297
|
-
|
|
298
|
-
console.log('[libbitsub] Initializing worker with WASM URL:', wasmUrl);
|
|
299
|
-
sendToWorker({ type: 'init', wasmUrl })
|
|
361
|
+
sendToWorker({ type: 'init', wasmUrl: getWasmUrl() })
|
|
300
362
|
.then(() => {
|
|
301
|
-
console.log('[libbitsub] Worker initialized successfully');
|
|
302
363
|
URL.revokeObjectURL(workerUrl);
|
|
303
364
|
resolve(worker);
|
|
304
365
|
})
|
|
305
366
|
.catch((err) => {
|
|
306
|
-
console.error('[libbitsub] Worker initialization failed:', err);
|
|
307
367
|
URL.revokeObjectURL(workerUrl);
|
|
308
368
|
sharedWorker = null;
|
|
309
369
|
workerInitPromise = null;
|
|
@@ -311,9 +371,8 @@ export function getOrCreateWorker() {
|
|
|
311
371
|
});
|
|
312
372
|
}
|
|
313
373
|
catch (error) {
|
|
314
|
-
console.error('[libbitsub] Failed to create worker:', error);
|
|
315
374
|
workerInitPromise = null;
|
|
316
|
-
reject(error);
|
|
375
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
317
376
|
}
|
|
318
377
|
});
|
|
319
378
|
return workerInitPromise;
|
|
@@ -328,7 +387,6 @@ export function sendToWorker(request, timeout = WORKER_TIMEOUT) {
|
|
|
328
387
|
return;
|
|
329
388
|
}
|
|
330
389
|
const id = ++messageId;
|
|
331
|
-
// Set up timeout
|
|
332
390
|
const timeoutId = setTimeout(() => {
|
|
333
391
|
pendingCallbacks.delete(id);
|
|
334
392
|
reject(new Error(`Worker operation timed out after ${timeout}ms`));
|
package/dist/ts/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/ts/worker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAEnC,IAAI,YAAY,GAAkB,IAAI,CAAA;AACtC,IAAI,iBAAiB,GAA2B,IAAI,CAAA;AACpD,IAAI,SAAS,GAAG,CAAC,CAAA;AAEjB,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAM7B,CAAA;AAEH,0CAA0C;AAC1C,MAAM,UAAU,iBAAiB;
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/ts/worker.ts"],"names":[],"mappings":"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"}
|
package/dist/wrapper.d.ts
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* TypeScript wrapper for the libbitsub Rust rendering engine.
|
|
3
3
|
* Provides a compatible API with the original libpgs-js implementation.
|
|
4
4
|
*/
|
|
5
|
-
export type { SubtitleData, SubtitleCompositionData, SubtitleDisplaySettings, VideoSubtitleOptions, VideoVobSubOptions, RenderResult, SubtitleFrame, VobSubFrame } from './ts/types';
|
|
5
|
+
export type { AutoSubtitleSource, AutoVideoSubtitleOptions, SubtitleCueBounds, SubtitleCueMetadata, SubtitleData, SubtitleCompositionData, SubtitleDisplaySettings, SubtitleFormatName, SubtitleHorizontalAlign, SubtitleParserMetadata, SubtitleRendererBackend, SubtitleRendererEvent, SubtitleRendererStatsSnapshot, VideoSubtitleOptions, VideoVobSubOptions, RenderResult, SubtitleFrame, VobSubFrame } from './ts/types';
|
|
6
6
|
export { initWasm, isWasmInitialized } from './ts/wasm';
|
|
7
7
|
export { isWebGPUSupported } from './ts/webgpu-renderer';
|
|
8
8
|
export { PgsParser, VobSubParserLowLevel, UnifiedSubtitleParser } from './ts/parsers';
|
|
9
|
-
export { PgsRenderer, VobSubRenderer, type SubtitleRendererStats } from './ts/renderers';
|
|
9
|
+
export { PgsRenderer, VobSubRenderer, createAutoSubtitleRenderer, type SubtitleRendererStats } from './ts/renderers';
|
|
10
|
+
export { detectSubtitleFormat } from './ts/utils';
|
|
10
11
|
import { PgsRenderer as _PgsRenderer, VobSubRenderer as _VobSubRenderer } from './ts/renderers';
|
|
11
12
|
import { UnifiedSubtitleParser as _UnifiedSubtitleParser } from './ts/parsers';
|
|
12
13
|
/** @deprecated Use PgsRenderer instead */
|
package/dist/wrapper.d.ts.map
CHANGED
|
@@ -1 +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,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAGxD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAGrF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"wrapper.d.ts","sourceRoot":"","sources":["../src/wrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,6BAA6B,EAC7B,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,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAGxD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAGrF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,0BAA0B,EAAE,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAGpH,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAMjD,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"}
|
package/dist/wrapper.js
CHANGED
|
@@ -9,7 +9,9 @@ export { isWebGPUSupported } from './ts/webgpu-renderer';
|
|
|
9
9
|
// Re-export parsers
|
|
10
10
|
export { PgsParser, VobSubParserLowLevel, UnifiedSubtitleParser } from './ts/parsers';
|
|
11
11
|
// Re-export renderers
|
|
12
|
-
export { PgsRenderer, VobSubRenderer } from './ts/renderers';
|
|
12
|
+
export { PgsRenderer, VobSubRenderer, createAutoSubtitleRenderer } from './ts/renderers';
|
|
13
|
+
// Re-export format detection utilities
|
|
14
|
+
export { detectSubtitleFormat } from './ts/utils';
|
|
13
15
|
// =============================================================================
|
|
14
16
|
// Legacy Aliases (for backward compatibility)
|
|
15
17
|
// =============================================================================
|
package/dist/wrapper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../src/wrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../src/wrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAwBH,4BAA4B;AAC5B,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAEvD,6BAA6B;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAExD,oBAAoB;AACpB,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAErF,sBAAsB;AACtB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,0BAA0B,EAA8B,MAAM,gBAAgB,CAAA;AAEpH,uCAAuC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAEjD,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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libbitsub",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"author": "altqx",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "High-performance WASM renderer for graphical subtitles (PGS and VobSub)",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"build:wasm": "wasm-pack build --target web --out-dir pkg",
|
|
39
39
|
"build:wasm:release": "wasm-pack build --release --target web --out-dir pkg",
|
|
40
40
|
"build:wasm:bundler": "wasm-pack build --target bundler --out-dir pkg-bundler",
|
|
41
|
-
"build:ts": "
|
|
41
|
+
"build:ts": "tsgo",
|
|
42
42
|
"build": "bun run build:wasm:release && bun run build:ts",
|
|
43
43
|
"clean": "rm -rf pkg pkg-bundler dist target",
|
|
44
44
|
"test": "cargo test",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"format": "cargo fmt && prettier . --write"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
+
"@typescript/native-preview": "^7.0.0-dev.20260306.1",
|
|
49
50
|
"prettier": "^3.8.1",
|
|
50
51
|
"typescript": "^5.9.3"
|
|
51
52
|
},
|