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.
- package/LICENSE +674 -0
- package/README.md +355 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/ts/parsers.d.ts +156 -0
- package/dist/ts/parsers.d.ts.map +1 -0
- package/dist/ts/parsers.js +366 -0
- package/dist/ts/parsers.js.map +1 -0
- package/dist/ts/renderers.d.ts +155 -0
- package/dist/ts/renderers.d.ts.map +1 -0
- package/dist/ts/renderers.js +640 -0
- package/dist/ts/renderers.js.map +1 -0
- package/dist/ts/types.d.ts +146 -0
- package/dist/ts/types.d.ts.map +1 -0
- package/dist/ts/types.js +5 -0
- package/dist/ts/types.js.map +1 -0
- package/dist/ts/utils.d.ts +11 -0
- package/dist/ts/utils.d.ts.map +1 -0
- package/dist/ts/utils.js +47 -0
- package/dist/ts/utils.js.map +1 -0
- package/dist/ts/wasm.d.ts +15 -0
- package/dist/ts/wasm.d.ts.map +1 -0
- package/dist/ts/wasm.js +54 -0
- package/dist/ts/wasm.js.map +1 -0
- package/dist/ts/worker.d.ts +12 -0
- package/dist/ts/worker.d.ts.map +1 -0
- package/dist/ts/worker.js +342 -0
- package/dist/ts/worker.js.map +1 -0
- package/dist/wrapper.d.ts +17 -0
- package/dist/wrapper.d.ts.map +1 -0
- package/dist/wrapper.js +22 -0
- package/dist/wrapper.js.map +1 -0
- package/package.json +54 -0
- package/pkg/LICENSE +674 -0
- package/pkg/README.md +355 -0
- package/pkg/libbitsub.d.ts +323 -0
- package/pkg/libbitsub.js +880 -0
- package/pkg/libbitsub_bg.wasm +0 -0
- package/pkg/libbitsub_bg.wasm.d.ts +68 -0
- package/pkg/package.json +31 -0
- package/src/wrapper.ts +41 -0
package/pkg/README.md
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# libbit(map)sub
|
|
2
|
+
|
|
3
|
+
High-performance WASM renderer for graphical subtitles (PGS and VobSub), written in Rust.
|
|
4
|
+
|
|
5
|
+
Started as a fork of Arcus92's [libpgs-js](https://github.com/Arcus92/libpgs-js), this project is re-engineered to maximize performance and extend functionality to VobSub, which was not supported by the original library. It remains fully backward compatible (only for PGS - obliviously). Special thanks to the original project for the inspiration!
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **PGS (Blu-ray)** subtitle parsing and rendering
|
|
10
|
+
- **VobSub (DVD)** subtitle parsing and rendering
|
|
11
|
+
- **High-performance** Rust-based rendering engine compiled to WebAssembly
|
|
12
|
+
- **Zero-copy** data transfer between JS and WASM where possible
|
|
13
|
+
- **Caching** for decoded bitmaps to optimize repeated rendering
|
|
14
|
+
- **TypeScript** support with full type definitions
|
|
15
|
+
|
|
16
|
+
## Showcase
|
|
17
|
+
|
|
18
|
+
### PGS (Created using Spp2Pgs)
|
|
19
|
+
|
|
20
|
+
https://gist.github.com/user-attachments/assets/55ac8e11-1964-4fb9-923e-dcac82dc7703
|
|
21
|
+
|
|
22
|
+
### Vobsub
|
|
23
|
+
|
|
24
|
+
https://gist.github.com/user-attachments/assets/a89ae9fe-23e4-4bc3-8cad-16a3f0fea665
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
bun add libbitsub
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Setup for Web Workers (Recommended)
|
|
33
|
+
|
|
34
|
+
For best performance with large subtitle files, copy the WASM files to your public folder so Web Workers can access them:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# For Next.js, Vite, or similar frameworks
|
|
38
|
+
mkdir -p public/libbitsub
|
|
39
|
+
cp node_modules/libbitsub/pkg/libbitsub_bg.wasm public/libbitsub/
|
|
40
|
+
cp node_modules/libbitsub/pkg/libbitsub.js public/libbitsub/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This enables off-main-thread parsing which prevents UI freezing when loading large PGS files.
|
|
44
|
+
|
|
45
|
+
## Prerequisites
|
|
46
|
+
|
|
47
|
+
To build from source, you need:
|
|
48
|
+
|
|
49
|
+
- [Rust](https://rustup.rs/) (1.70+)
|
|
50
|
+
- [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/)
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Install wasm-pack
|
|
54
|
+
cargo install wasm-pack
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Building
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Build WASM module and TypeScript wrapper
|
|
61
|
+
bun run build
|
|
62
|
+
|
|
63
|
+
# Build WASM only (for development)
|
|
64
|
+
bun run build:wasm
|
|
65
|
+
|
|
66
|
+
# Build release version (optimized)
|
|
67
|
+
bun run build:wasm:release
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
|
|
72
|
+
### Initialize WASM
|
|
73
|
+
|
|
74
|
+
Before using any renderer, you must initialize the WASM module:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { initWasm } from 'libbitsub'
|
|
78
|
+
|
|
79
|
+
// Initialize WASM (do this once at app startup)
|
|
80
|
+
await initWasm()
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## High-Level API (Video Integration)
|
|
84
|
+
|
|
85
|
+
The high-level API automatically handles video synchronization, canvas overlay, and subtitle fetching.
|
|
86
|
+
|
|
87
|
+
### PGS Subtitles (Video-Integrated)
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { PgsRenderer } from 'libbitsub'
|
|
91
|
+
|
|
92
|
+
// Create renderer with video element
|
|
93
|
+
const renderer = new PgsRenderer({
|
|
94
|
+
video: videoElement,
|
|
95
|
+
subUrl: '/subtitles/movie.sup',
|
|
96
|
+
workerUrl: '/libbitsub.js', // Optional, kept for API compatibility
|
|
97
|
+
// Lifecycle callbacks (optional)
|
|
98
|
+
onLoading: () => console.log('Loading subtitles...'),
|
|
99
|
+
onLoaded: () => console.log('Subtitles loaded!'),
|
|
100
|
+
onError: (error) => console.error('Failed to load:', error)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
// The renderer automatically:
|
|
104
|
+
// - Fetches the subtitle file
|
|
105
|
+
// - Creates a canvas overlay on the video
|
|
106
|
+
// - Syncs rendering with video playback
|
|
107
|
+
// - Handles resize events
|
|
108
|
+
|
|
109
|
+
// When done:
|
|
110
|
+
renderer.dispose()
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### VobSub Subtitles (Video-Integrated)
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { VobSubRenderer } from 'libbitsub'
|
|
117
|
+
|
|
118
|
+
// Create renderer with video element
|
|
119
|
+
const renderer = new VobSubRenderer({
|
|
120
|
+
video: videoElement,
|
|
121
|
+
subUrl: '/subtitles/movie.sub',
|
|
122
|
+
idxUrl: '/subtitles/movie.idx', // Optional, defaults to .sub path with .idx extension
|
|
123
|
+
workerUrl: '/libbitsub.js', // Optional
|
|
124
|
+
// Lifecycle callbacks (optional)
|
|
125
|
+
onLoading: () => setIsLoading(true),
|
|
126
|
+
onLoaded: () => setIsLoading(false),
|
|
127
|
+
onError: (error) => {
|
|
128
|
+
setIsLoading(false)
|
|
129
|
+
console.error('Subtitle error:', error)
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
// When done:
|
|
134
|
+
renderer.dispose()
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Subtitle Display Settings
|
|
138
|
+
|
|
139
|
+
Both `PgsRenderer` and `VobSubRenderer` support real-time customization of subtitle size and position:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// Get current settings
|
|
143
|
+
const settings = renderer.getDisplaySettings()
|
|
144
|
+
console.log(settings)
|
|
145
|
+
// Output: { scale: 1.0, verticalOffset: 0 }
|
|
146
|
+
|
|
147
|
+
// Update settings
|
|
148
|
+
renderer.setDisplaySettings({
|
|
149
|
+
scale: 1.2, // 1.2 = 120% size
|
|
150
|
+
verticalOffset: -10 // -10% (move up 10% of video height)
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
// Reset to defaults
|
|
154
|
+
renderer.resetDisplaySettings()
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Settings Reference:**
|
|
158
|
+
|
|
159
|
+
- `scale` (number): Scale factor for subtitles.
|
|
160
|
+
- `1.0` = 100% (Original size)
|
|
161
|
+
- `0.5` = 50%
|
|
162
|
+
- `2.0` = 200%
|
|
163
|
+
- Range: `0.1` to `3.0`
|
|
164
|
+
|
|
165
|
+
- `verticalOffset` (number): Vertical position offset as a percentage of video height.
|
|
166
|
+
- `0` = Original position
|
|
167
|
+
- Negative values move up (e.g., `-10` moves up by 10% of height)
|
|
168
|
+
- Positive values move down (e.g., `10` moves down by 10% of height)
|
|
169
|
+
- Range: `-50` to `50`
|
|
170
|
+
|
|
171
|
+
## Low-Level API (Programmatic Use)
|
|
172
|
+
|
|
173
|
+
For more control over rendering, use the low-level parsers directly.
|
|
174
|
+
|
|
175
|
+
### PGS Subtitles (Low-Level)
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
import { initWasm, PgsParser } from 'libbitsub'
|
|
179
|
+
|
|
180
|
+
await initWasm()
|
|
181
|
+
|
|
182
|
+
const parser = new PgsParser()
|
|
183
|
+
|
|
184
|
+
// Load PGS data from a .sup file
|
|
185
|
+
const response = await fetch('subtitles.sup')
|
|
186
|
+
const data = new Uint8Array(await response.arrayBuffer())
|
|
187
|
+
parser.load(data)
|
|
188
|
+
|
|
189
|
+
// Get timestamps
|
|
190
|
+
const timestamps = parser.getTimestamps() // Float64Array in milliseconds
|
|
191
|
+
|
|
192
|
+
// Render at a specific time
|
|
193
|
+
const subtitleData = parser.renderAtTimestamp(currentTimeInSeconds)
|
|
194
|
+
if (subtitleData) {
|
|
195
|
+
for (const comp of subtitleData.compositionData) {
|
|
196
|
+
ctx.putImageData(comp.pixelData, comp.x, comp.y)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Clean up
|
|
201
|
+
parser.dispose()
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### VobSub Subtitles (Low-Level)
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { initWasm, VobSubParserLowLevel } from 'libbitsub'
|
|
208
|
+
|
|
209
|
+
await initWasm()
|
|
210
|
+
|
|
211
|
+
const parser = new VobSubParserLowLevel()
|
|
212
|
+
|
|
213
|
+
// Load from IDX + SUB files
|
|
214
|
+
const idxResponse = await fetch('subtitles.idx')
|
|
215
|
+
const idxContent = await idxResponse.text()
|
|
216
|
+
const subResponse = await fetch('subtitles.sub')
|
|
217
|
+
const subData = new Uint8Array(await subResponse.arrayBuffer())
|
|
218
|
+
|
|
219
|
+
parser.loadFromData(idxContent, subData)
|
|
220
|
+
|
|
221
|
+
// Or load from SUB file only
|
|
222
|
+
// parser.loadFromSubOnly(subData);
|
|
223
|
+
|
|
224
|
+
// Render
|
|
225
|
+
const subtitleData = parser.renderAtTimestamp(currentTimeInSeconds)
|
|
226
|
+
if (subtitleData) {
|
|
227
|
+
for (const comp of subtitleData.compositionData) {
|
|
228
|
+
ctx.putImageData(comp.pixelData, comp.x, comp.y)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
parser.dispose()
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Unified Parser
|
|
236
|
+
|
|
237
|
+
For handling both formats with a single API:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { initWasm, UnifiedSubtitleParser } from 'libbitsub'
|
|
241
|
+
|
|
242
|
+
await initWasm()
|
|
243
|
+
|
|
244
|
+
const parser = new UnifiedSubtitleParser()
|
|
245
|
+
|
|
246
|
+
// Load PGS
|
|
247
|
+
parser.loadPgs(pgsData)
|
|
248
|
+
|
|
249
|
+
// Or load VobSub
|
|
250
|
+
// parser.loadVobSub(idxContent, subData);
|
|
251
|
+
|
|
252
|
+
console.log(parser.format) // 'pgs' or 'vobsub'
|
|
253
|
+
|
|
254
|
+
const subtitleData = parser.renderAtTimestamp(time)
|
|
255
|
+
// ... render to canvas
|
|
256
|
+
|
|
257
|
+
parser.dispose()
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## API Reference
|
|
261
|
+
|
|
262
|
+
### High-Level (Video-Integrated)
|
|
263
|
+
|
|
264
|
+
#### `PgsRenderer`
|
|
265
|
+
|
|
266
|
+
- `constructor(options: VideoSubtitleOptions)` - Create video-integrated PGS renderer
|
|
267
|
+
- `getDisplaySettings(): SubtitleDisplaySettings` - Get current display settings
|
|
268
|
+
- `setDisplaySettings(settings: Partial<SubtitleDisplaySettings>): void` - Update display settings
|
|
269
|
+
- `resetDisplaySettings(): void` - Reset display settings to defaults
|
|
270
|
+
- `dispose(): void` - Clean up all resources
|
|
271
|
+
|
|
272
|
+
#### `VobSubRenderer`
|
|
273
|
+
|
|
274
|
+
- `constructor(options: VideoVobSubOptions)` - Create video-integrated VobSub renderer
|
|
275
|
+
- `getDisplaySettings(): SubtitleDisplaySettings` - Get current display settings
|
|
276
|
+
- `setDisplaySettings(settings: Partial<SubtitleDisplaySettings>): void` - Update display settings
|
|
277
|
+
- `resetDisplaySettings(): void` - Reset display settings to defaults
|
|
278
|
+
- `dispose(): void` - Clean up all resources
|
|
279
|
+
|
|
280
|
+
### Low-Level (Programmatic)
|
|
281
|
+
|
|
282
|
+
#### `PgsParser`
|
|
283
|
+
|
|
284
|
+
- `load(data: Uint8Array): number` - Load PGS data, returns display set count
|
|
285
|
+
- `getTimestamps(): Float64Array` - Get all timestamps in milliseconds
|
|
286
|
+
- `count: number` - Number of display sets
|
|
287
|
+
- `findIndexAtTimestamp(timeSeconds: number): number` - Find index for timestamp
|
|
288
|
+
- `renderAtIndex(index: number): SubtitleData | undefined` - Render at index
|
|
289
|
+
- `renderAtTimestamp(timeSeconds: number): SubtitleData | undefined` - Render at time
|
|
290
|
+
- `clearCache(): void` - Clear decoded bitmap cache
|
|
291
|
+
- `dispose(): void` - Release resources
|
|
292
|
+
|
|
293
|
+
#### `VobSubParserLowLevel`
|
|
294
|
+
|
|
295
|
+
- `loadFromData(idxContent: string, subData: Uint8Array): void` - Load IDX + SUB
|
|
296
|
+
- `loadFromSubOnly(subData: Uint8Array): void` - Load SUB only
|
|
297
|
+
- Same rendering methods as PgsParser
|
|
298
|
+
|
|
299
|
+
#### `UnifiedSubtitleParser`
|
|
300
|
+
|
|
301
|
+
- `loadPgs(data: Uint8Array): number` - Load PGS data
|
|
302
|
+
- `loadVobSub(idxContent: string, subData: Uint8Array): void` - Load VobSub
|
|
303
|
+
- `loadVobSubOnly(subData: Uint8Array): void` - Load SUB only
|
|
304
|
+
- `format: 'pgs' | 'vobsub' | null` - Current format
|
|
305
|
+
- Same rendering methods as above
|
|
306
|
+
|
|
307
|
+
### Types
|
|
308
|
+
|
|
309
|
+
#### `VideoSubtitleOptions`
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
interface VideoSubtitleOptions {
|
|
313
|
+
video: HTMLVideoElement // Video element to sync with
|
|
314
|
+
subUrl: string // URL to subtitle file
|
|
315
|
+
workerUrl?: string // Worker URL (for API compatibility)
|
|
316
|
+
onLoading?: () => void // Called when subtitle loading starts
|
|
317
|
+
onLoaded?: () => void // Called when subtitle loading completes
|
|
318
|
+
onError?: (error: Error) => void // Called when subtitle loading fails
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
#### `VideoVobSubOptions`
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
interface VideoVobSubOptions extends VideoSubtitleOptions {
|
|
326
|
+
idxUrl?: string // URL to .idx file (optional)
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
#### `SubtitleDisplaySettings`
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
interface SubtitleDisplaySettings {
|
|
334
|
+
// Scale factor (1.0 = 100%, 0.5 = 50%, 2.0 = 200%)
|
|
335
|
+
scale: number
|
|
336
|
+
// Vertical offset as % of video height (-50 to 50)
|
|
337
|
+
verticalOffset: number
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
#### `SubtitleData`
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
interface SubtitleData {
|
|
345
|
+
width: number // Screen width
|
|
346
|
+
height: number // Screen height
|
|
347
|
+
compositionData: SubtitleCompositionData[]
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
interface SubtitleCompositionData {
|
|
351
|
+
pixelData: ImageData // RGBA pixel data
|
|
352
|
+
x: number // X position
|
|
353
|
+
y: number // Y position
|
|
354
|
+
}
|
|
355
|
+
```
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
export class PgsParser {
|
|
5
|
+
free(): void;
|
|
6
|
+
[Symbol.dispose](): void;
|
|
7
|
+
/**
|
|
8
|
+
* Clear the internal cache.
|
|
9
|
+
*/
|
|
10
|
+
clearCache(): void;
|
|
11
|
+
/**
|
|
12
|
+
* Get all timestamps in milliseconds as a Float64Array.
|
|
13
|
+
*/
|
|
14
|
+
getTimestamps(): Float64Array;
|
|
15
|
+
/**
|
|
16
|
+
* Render subtitle at the given index and return RGBA data.
|
|
17
|
+
* Returns null if index is invalid or no subtitle data.
|
|
18
|
+
*/
|
|
19
|
+
renderAtIndex(index: number): SubtitleFrame | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Find the display set index for a given timestamp in milliseconds.
|
|
22
|
+
*/
|
|
23
|
+
findIndexAtTimestamp(time_ms: number): number;
|
|
24
|
+
/**
|
|
25
|
+
* Create a new PGS parser.
|
|
26
|
+
*/
|
|
27
|
+
constructor();
|
|
28
|
+
/**
|
|
29
|
+
* Parse a PGS file from binary data.
|
|
30
|
+
* Returns the number of display sets parsed.
|
|
31
|
+
*/
|
|
32
|
+
parse(data: Uint8Array): number;
|
|
33
|
+
/**
|
|
34
|
+
* Get the number of display sets.
|
|
35
|
+
*/
|
|
36
|
+
readonly count: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class RenderResult {
|
|
40
|
+
private constructor();
|
|
41
|
+
free(): void;
|
|
42
|
+
[Symbol.dispose](): void;
|
|
43
|
+
/**
|
|
44
|
+
* Get composition X position at index.
|
|
45
|
+
*/
|
|
46
|
+
getCompositionX(index: number): number;
|
|
47
|
+
/**
|
|
48
|
+
* Get composition Y position at index.
|
|
49
|
+
*/
|
|
50
|
+
getCompositionY(index: number): number;
|
|
51
|
+
/**
|
|
52
|
+
* Get composition RGBA data at index.
|
|
53
|
+
*/
|
|
54
|
+
getCompositionRgba(index: number): Uint8Array;
|
|
55
|
+
/**
|
|
56
|
+
* Get composition width at index.
|
|
57
|
+
*/
|
|
58
|
+
getCompositionWidth(index: number): number;
|
|
59
|
+
/**
|
|
60
|
+
* Get composition height at index.
|
|
61
|
+
*/
|
|
62
|
+
getCompositionHeight(index: number): number;
|
|
63
|
+
readonly screenWidth: number;
|
|
64
|
+
readonly screenHeight: number;
|
|
65
|
+
/**
|
|
66
|
+
* Get the number of composition elements.
|
|
67
|
+
*/
|
|
68
|
+
readonly compositionCount: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export class SubtitleComposition {
|
|
72
|
+
private constructor();
|
|
73
|
+
free(): void;
|
|
74
|
+
[Symbol.dispose](): void;
|
|
75
|
+
/**
|
|
76
|
+
* Get RGBA pixel data as Uint8Array.
|
|
77
|
+
*/
|
|
78
|
+
getRgba(): Uint8Array;
|
|
79
|
+
readonly x: number;
|
|
80
|
+
readonly y: number;
|
|
81
|
+
readonly width: number;
|
|
82
|
+
readonly height: number;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Subtitle format type.
|
|
87
|
+
*/
|
|
88
|
+
export enum SubtitleFormat {
|
|
89
|
+
/**
|
|
90
|
+
* PGS (Blu-ray) subtitle format
|
|
91
|
+
*/
|
|
92
|
+
Pgs = 0,
|
|
93
|
+
/**
|
|
94
|
+
* VobSub (DVD) subtitle format
|
|
95
|
+
*/
|
|
96
|
+
VobSub = 1,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export class SubtitleFrame {
|
|
100
|
+
private constructor();
|
|
101
|
+
free(): void;
|
|
102
|
+
[Symbol.dispose](): void;
|
|
103
|
+
/**
|
|
104
|
+
* Get a composition by index.
|
|
105
|
+
*/
|
|
106
|
+
getComposition(index: number): SubtitleComposition | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Get the number of compositions.
|
|
109
|
+
*/
|
|
110
|
+
readonly compositionCount: number;
|
|
111
|
+
readonly width: number;
|
|
112
|
+
readonly height: number;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export class SubtitleRenderer {
|
|
116
|
+
free(): void;
|
|
117
|
+
[Symbol.dispose](): void;
|
|
118
|
+
/**
|
|
119
|
+
* Clear internal caches.
|
|
120
|
+
*/
|
|
121
|
+
clearCache(): void;
|
|
122
|
+
/**
|
|
123
|
+
* Load VobSub subtitle data from IDX and SUB.
|
|
124
|
+
*/
|
|
125
|
+
loadVobSub(idx_content: string, sub_data: Uint8Array): void;
|
|
126
|
+
/**
|
|
127
|
+
* Get all timestamps in milliseconds.
|
|
128
|
+
*/
|
|
129
|
+
getTimestamps(): Float64Array;
|
|
130
|
+
/**
|
|
131
|
+
* Render subtitle at the given index.
|
|
132
|
+
* Returns a unified RenderResult or null.
|
|
133
|
+
*/
|
|
134
|
+
renderAtIndex(index: number): RenderResult | undefined;
|
|
135
|
+
/**
|
|
136
|
+
* Load VobSub from SUB file only.
|
|
137
|
+
*/
|
|
138
|
+
loadVobSubOnly(sub_data: Uint8Array): void;
|
|
139
|
+
/**
|
|
140
|
+
* Render subtitle at the given timestamp in seconds.
|
|
141
|
+
*/
|
|
142
|
+
renderAtTimestamp(time_seconds: number): RenderResult | undefined;
|
|
143
|
+
/**
|
|
144
|
+
* Find the subtitle index for a given timestamp in milliseconds.
|
|
145
|
+
*/
|
|
146
|
+
findIndexAtTimestamp(time_ms: number): number;
|
|
147
|
+
/**
|
|
148
|
+
* Create a new subtitle renderer.
|
|
149
|
+
*/
|
|
150
|
+
constructor();
|
|
151
|
+
/**
|
|
152
|
+
* Dispose of all resources.
|
|
153
|
+
*/
|
|
154
|
+
dispose(): void;
|
|
155
|
+
/**
|
|
156
|
+
* Load PGS subtitle data.
|
|
157
|
+
*/
|
|
158
|
+
loadPgs(data: Uint8Array): number;
|
|
159
|
+
/**
|
|
160
|
+
* Get the number of subtitle entries.
|
|
161
|
+
*/
|
|
162
|
+
readonly count: number;
|
|
163
|
+
/**
|
|
164
|
+
* Get the current subtitle format.
|
|
165
|
+
*/
|
|
166
|
+
readonly format: SubtitleFormat | undefined;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export class VobSubFrame {
|
|
170
|
+
private constructor();
|
|
171
|
+
free(): void;
|
|
172
|
+
[Symbol.dispose](): void;
|
|
173
|
+
/**
|
|
174
|
+
* Get RGBA pixel data as Uint8Array.
|
|
175
|
+
*/
|
|
176
|
+
getRgba(): Uint8Array;
|
|
177
|
+
readonly screenWidth: number;
|
|
178
|
+
readonly screenHeight: number;
|
|
179
|
+
readonly x: number;
|
|
180
|
+
readonly y: number;
|
|
181
|
+
readonly width: number;
|
|
182
|
+
readonly height: number;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export class VobSubParser {
|
|
186
|
+
free(): void;
|
|
187
|
+
[Symbol.dispose](): void;
|
|
188
|
+
/**
|
|
189
|
+
* Clear the internal cache.
|
|
190
|
+
*/
|
|
191
|
+
clearCache(): void;
|
|
192
|
+
/**
|
|
193
|
+
* Get all timestamps in milliseconds as a Float64Array.
|
|
194
|
+
*/
|
|
195
|
+
getTimestamps(): Float64Array;
|
|
196
|
+
/**
|
|
197
|
+
* Load VobSub from IDX content and SUB data.
|
|
198
|
+
*/
|
|
199
|
+
loadFromData(idx_content: string, sub_data: Uint8Array): void;
|
|
200
|
+
/**
|
|
201
|
+
* Render subtitle at the given index and return RGBA data.
|
|
202
|
+
*/
|
|
203
|
+
renderAtIndex(index: number): VobSubFrame | undefined;
|
|
204
|
+
/**
|
|
205
|
+
* Load VobSub from SUB file only (scans for timestamps).
|
|
206
|
+
*/
|
|
207
|
+
loadFromSubOnly(sub_data: Uint8Array): void;
|
|
208
|
+
/**
|
|
209
|
+
* Find the subtitle index for a given timestamp in milliseconds.
|
|
210
|
+
* Returns -1 if no subtitle should be displayed at this time.
|
|
211
|
+
*/
|
|
212
|
+
findIndexAtTimestamp(time_ms: number): number;
|
|
213
|
+
/**
|
|
214
|
+
* Create a new VobSub parser.
|
|
215
|
+
*/
|
|
216
|
+
constructor();
|
|
217
|
+
/**
|
|
218
|
+
* Dispose of all resources.
|
|
219
|
+
*/
|
|
220
|
+
dispose(): void;
|
|
221
|
+
/**
|
|
222
|
+
* Get the number of subtitle entries.
|
|
223
|
+
*/
|
|
224
|
+
readonly count: number;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Initialize the WASM module. Call this once before using other functions.
|
|
229
|
+
*/
|
|
230
|
+
export function init(): void;
|
|
231
|
+
|
|
232
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
233
|
+
|
|
234
|
+
export interface InitOutput {
|
|
235
|
+
readonly memory: WebAssembly.Memory;
|
|
236
|
+
readonly __wbg_pgsparser_free: (a: number, b: number) => void;
|
|
237
|
+
readonly __wbg_renderresult_free: (a: number, b: number) => void;
|
|
238
|
+
readonly __wbg_subtitlecomposition_free: (a: number, b: number) => void;
|
|
239
|
+
readonly __wbg_subtitlerenderer_free: (a: number, b: number) => void;
|
|
240
|
+
readonly __wbg_vobsubframe_free: (a: number, b: number) => void;
|
|
241
|
+
readonly __wbg_vobsubparser_free: (a: number, b: number) => void;
|
|
242
|
+
readonly init: () => void;
|
|
243
|
+
readonly pgsparser_clearCache: (a: number) => void;
|
|
244
|
+
readonly pgsparser_count: (a: number) => number;
|
|
245
|
+
readonly pgsparser_findIndexAtTimestamp: (a: number, b: number) => number;
|
|
246
|
+
readonly pgsparser_getTimestamps: (a: number) => any;
|
|
247
|
+
readonly pgsparser_new: () => number;
|
|
248
|
+
readonly pgsparser_parse: (a: number, b: number, c: number) => number;
|
|
249
|
+
readonly pgsparser_renderAtIndex: (a: number, b: number) => number;
|
|
250
|
+
readonly renderresult_compositionCount: (a: number) => number;
|
|
251
|
+
readonly renderresult_getCompositionHeight: (a: number, b: number) => number;
|
|
252
|
+
readonly renderresult_getCompositionRgba: (a: number, b: number) => any;
|
|
253
|
+
readonly renderresult_getCompositionWidth: (a: number, b: number) => number;
|
|
254
|
+
readonly renderresult_getCompositionX: (a: number, b: number) => number;
|
|
255
|
+
readonly renderresult_getCompositionY: (a: number, b: number) => number;
|
|
256
|
+
readonly renderresult_screenHeight: (a: number) => number;
|
|
257
|
+
readonly renderresult_screenWidth: (a: number) => number;
|
|
258
|
+
readonly subtitlecomposition_getRgba: (a: number) => any;
|
|
259
|
+
readonly subtitlecomposition_height: (a: number) => number;
|
|
260
|
+
readonly subtitlecomposition_width: (a: number) => number;
|
|
261
|
+
readonly subtitlecomposition_x: (a: number) => number;
|
|
262
|
+
readonly subtitlecomposition_y: (a: number) => number;
|
|
263
|
+
readonly subtitleframe_getComposition: (a: number, b: number) => number;
|
|
264
|
+
readonly subtitlerenderer_clearCache: (a: number) => void;
|
|
265
|
+
readonly subtitlerenderer_count: (a: number) => number;
|
|
266
|
+
readonly subtitlerenderer_dispose: (a: number) => void;
|
|
267
|
+
readonly subtitlerenderer_findIndexAtTimestamp: (a: number, b: number) => number;
|
|
268
|
+
readonly subtitlerenderer_format: (a: number) => number;
|
|
269
|
+
readonly subtitlerenderer_getTimestamps: (a: number) => any;
|
|
270
|
+
readonly subtitlerenderer_loadPgs: (a: number, b: number, c: number) => number;
|
|
271
|
+
readonly subtitlerenderer_loadVobSub: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
272
|
+
readonly subtitlerenderer_loadVobSubOnly: (a: number, b: number, c: number) => void;
|
|
273
|
+
readonly subtitlerenderer_new: () => number;
|
|
274
|
+
readonly subtitlerenderer_renderAtIndex: (a: number, b: number) => number;
|
|
275
|
+
readonly subtitlerenderer_renderAtTimestamp: (a: number, b: number) => number;
|
|
276
|
+
readonly vobsubframe_getRgba: (a: number) => any;
|
|
277
|
+
readonly vobsubframe_height: (a: number) => number;
|
|
278
|
+
readonly vobsubframe_screenHeight: (a: number) => number;
|
|
279
|
+
readonly vobsubframe_screenWidth: (a: number) => number;
|
|
280
|
+
readonly vobsubframe_width: (a: number) => number;
|
|
281
|
+
readonly vobsubframe_x: (a: number) => number;
|
|
282
|
+
readonly vobsubframe_y: (a: number) => number;
|
|
283
|
+
readonly vobsubparser_clearCache: (a: number) => void;
|
|
284
|
+
readonly vobsubparser_count: (a: number) => number;
|
|
285
|
+
readonly vobsubparser_dispose: (a: number) => void;
|
|
286
|
+
readonly vobsubparser_findIndexAtTimestamp: (a: number, b: number) => number;
|
|
287
|
+
readonly vobsubparser_getTimestamps: (a: number) => any;
|
|
288
|
+
readonly vobsubparser_loadFromData: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
289
|
+
readonly vobsubparser_loadFromSubOnly: (a: number, b: number, c: number) => void;
|
|
290
|
+
readonly vobsubparser_new: () => number;
|
|
291
|
+
readonly vobsubparser_renderAtIndex: (a: number, b: number) => number;
|
|
292
|
+
readonly __wbg_subtitleframe_free: (a: number, b: number) => void;
|
|
293
|
+
readonly subtitleframe_width: (a: number) => number;
|
|
294
|
+
readonly subtitleframe_height: (a: number) => number;
|
|
295
|
+
readonly subtitleframe_compositionCount: (a: number) => number;
|
|
296
|
+
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
297
|
+
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
298
|
+
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
299
|
+
readonly __wbindgen_externrefs: WebAssembly.Table;
|
|
300
|
+
readonly __wbindgen_start: () => void;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
307
|
+
* a precompiled `WebAssembly.Module`.
|
|
308
|
+
*
|
|
309
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
310
|
+
*
|
|
311
|
+
* @returns {InitOutput}
|
|
312
|
+
*/
|
|
313
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
317
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
318
|
+
*
|
|
319
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
320
|
+
*
|
|
321
|
+
* @returns {Promise<InitOutput>}
|
|
322
|
+
*/
|
|
323
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|