libbitsub 1.11.0 → 1.12.1

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.
Files changed (83) hide show
  1. package/README.md +114 -17
  2. package/dist/index.d.ts +8 -5
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +8 -5
  5. package/dist/index.js.map +1 -1
  6. package/dist/integrations/hlsjs.d.ts +6 -0
  7. package/dist/integrations/hlsjs.d.ts.map +1 -1
  8. package/dist/integrations/hlsjs.js +3 -0
  9. package/dist/integrations/hlsjs.js.map +1 -1
  10. package/dist/integrations/index.d.ts +10 -2
  11. package/dist/integrations/index.d.ts.map +1 -1
  12. package/dist/integrations/index.js +10 -2
  13. package/dist/integrations/index.js.map +1 -1
  14. package/dist/integrations/react.d.ts +10 -1
  15. package/dist/integrations/react.d.ts.map +1 -1
  16. package/dist/integrations/react.js +11 -2
  17. package/dist/integrations/react.js.map +1 -1
  18. package/dist/integrations/shaka.d.ts +6 -0
  19. package/dist/integrations/shaka.d.ts.map +1 -1
  20. package/dist/integrations/shaka.js +3 -0
  21. package/dist/integrations/shaka.js.map +1 -1
  22. package/dist/integrations/shared.d.ts +4 -2
  23. package/dist/integrations/shared.d.ts.map +1 -1
  24. package/dist/integrations/shared.js.map +1 -1
  25. package/dist/integrations/videojs.d.ts +9 -0
  26. package/dist/integrations/videojs.d.ts.map +1 -1
  27. package/dist/integrations/videojs.js +3 -0
  28. package/dist/integrations/videojs.js.map +1 -1
  29. package/dist/ts/capabilities.d.ts +14 -0
  30. package/dist/ts/capabilities.d.ts.map +1 -0
  31. package/dist/ts/capabilities.js +111 -0
  32. package/dist/ts/capabilities.js.map +1 -0
  33. package/dist/ts/diagnostics.d.ts +6 -0
  34. package/dist/ts/diagnostics.d.ts.map +1 -1
  35. package/dist/ts/diagnostics.js +6 -0
  36. package/dist/ts/diagnostics.js.map +1 -1
  37. package/dist/ts/frame-export.d.ts +4 -0
  38. package/dist/ts/frame-export.d.ts.map +1 -1
  39. package/dist/ts/frame-export.js +4 -0
  40. package/dist/ts/frame-export.js.map +1 -1
  41. package/dist/ts/parsers.d.ts +39 -2
  42. package/dist/ts/parsers.d.ts.map +1 -1
  43. package/dist/ts/parsers.js +229 -1
  44. package/dist/ts/parsers.js.map +1 -1
  45. package/dist/ts/range-loader.d.ts +6 -0
  46. package/dist/ts/range-loader.d.ts.map +1 -1
  47. package/dist/ts/range-loader.js +3 -0
  48. package/dist/ts/range-loader.js.map +1 -1
  49. package/dist/ts/renderers.d.ts +129 -10
  50. package/dist/ts/renderers.d.ts.map +1 -1
  51. package/dist/ts/renderers.js +1342 -138
  52. package/dist/ts/renderers.js.map +1 -1
  53. package/dist/ts/types.d.ts +196 -6
  54. package/dist/ts/types.d.ts.map +1 -1
  55. package/dist/ts/utils.d.ts +2 -0
  56. package/dist/ts/utils.d.ts.map +1 -1
  57. package/dist/ts/utils.js +100 -2
  58. package/dist/ts/utils.js.map +1 -1
  59. package/dist/ts/video-frame-scheduler.d.ts +35 -0
  60. package/dist/ts/video-frame-scheduler.d.ts.map +1 -0
  61. package/dist/ts/video-frame-scheduler.js +98 -0
  62. package/dist/ts/video-frame-scheduler.js.map +1 -0
  63. package/dist/ts/worker.d.ts.map +1 -1
  64. package/dist/ts/worker.js +394 -0
  65. package/dist/ts/worker.js.map +1 -1
  66. package/dist/wrapper.d.ts +4 -3
  67. package/dist/wrapper.d.ts.map +1 -1
  68. package/dist/wrapper.js +3 -2
  69. package/dist/wrapper.js.map +1 -1
  70. package/package.json +7 -2
  71. package/pkg/README.md +114 -17
  72. package/pkg/libbitsub.d.ts +51 -1
  73. package/pkg/libbitsub.js +178 -3
  74. package/pkg/libbitsub_bg.wasm +0 -0
  75. package/pkg/libbitsub_bg.wasm.d.ts +21 -0
  76. package/pkg/package.json +4 -4
  77. package/src/integrations/hlsjs.ts +6 -0
  78. package/src/integrations/index.ts +10 -2
  79. package/src/integrations/react.tsx +17 -2
  80. package/src/integrations/shaka.ts +6 -0
  81. package/src/integrations/shared.ts +4 -1
  82. package/src/integrations/videojs.ts +9 -0
  83. package/src/wrapper.ts +22 -2
package/pkg/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # libbit(map)sub
2
2
 
3
- High-performance WASM renderer for graphical subtitles (PGS, VobSub, and MKS-embedded VobSub), written in Rust.
3
+ High-performance WASM renderer for graphical subtitles (PGS, VobSub, DVB-SUB, and MKS-embedded VobSub), written in Rust.
4
4
 
5
5
  Started as a fork of Arcus92's [libpgs-js](https://github.com/Arcus92/libpgs-js), this project was reworked for higher performance and broader format support. It keeps the familiar high-level PGS-oriented API while adding a lower-level parser surface, VobSub support, GPU backends, and worker-backed rendering.
6
6
 
@@ -8,6 +8,7 @@ Started as a fork of Arcus92's [libpgs-js](https://github.com/Arcus92/libpgs-js)
8
8
 
9
9
  - PGS (Blu-ray) subtitle parsing and rendering
10
10
  - VobSub (DVD) subtitle parsing and rendering
11
+ - DVB-SUB (ETSI EN 300 743) parsing and rendering via PES/ES and `"DV"` PTS-framed dumps
11
12
  - Matroska `.mks` extraction for embedded `S_VOBSUB` tracks
12
13
  - WebGPU, WebGL2, and Canvas2D rendering with automatic fallback
13
14
  - Worker-backed parsing/rendering for large subtitle files
@@ -33,7 +34,7 @@ https://gist.github.com/user-attachments/assets/a89ae9fe-23e4-4bc3-8cad-16a3f0fe
33
34
 
34
35
  ### Live demo
35
36
 
36
- https://a.rafasu.com/v
37
+ https://libbitsub.altqx.com
37
38
 
38
39
  ## Installation
39
40
 
@@ -256,6 +257,7 @@ const renderer = new PgsRenderer({
256
257
  },
257
258
  cacheLimit: 32,
258
259
  prefetchWindow: { before: 1, after: 2 },
260
+ frameAwareSync: true,
259
261
  onWarning: (warning) => {
260
262
  console.warn(warning.code, warning.message, warning.details)
261
263
  },
@@ -269,6 +271,33 @@ const renderer = new PgsRenderer({
269
271
  renderer.dispose()
270
272
  ```
271
273
 
274
+ Mount into a fullscreen shell or Shadow DOM root, reuse a player-owned canvas,
275
+ cap high-DPI backing-store cost, or bypass automatic backend selection:
276
+
277
+ ```ts
278
+ const renderer = new PgsRenderer({
279
+ video: videoElement,
280
+ subUrl: '/subtitles/movie.sup',
281
+ container: shadowRoot, // HTMLElement or ShadowRoot; defaults to video.parentElement
282
+ canvas: playerOverlayCanvas, // optional; remains mounted after dispose()
283
+ devicePixelRatioCap: 2,
284
+ backend: 'webgl2' // 'auto' | 'webgpu' | 'webgl2' | 'worker-offscreen' | 'canvas2d'
285
+ })
286
+ ```
287
+
288
+ An explicitly requested GPU or worker backend falls back to Canvas2D if it cannot
289
+ initialize. A supplied `container` takes precedence over the canvas's current parent;
290
+ without one, an already-mounted caller canvas stays in its existing host. Automatic
291
+ selection does not transfer a caller-owned canvas to a worker; request
292
+ `backend: 'worker-offscreen'` explicitly to allow that ownership transfer.
293
+
294
+ Frame-aware synchronization is enabled by default. On browsers with
295
+ `requestVideoFrameCallback()`, cue lookup uses the `mediaTime` of the frame sent
296
+ to the compositor instead of polling `video.currentTime`. Older browsers fall
297
+ back to `requestAnimationFrame()` automatically; set `frameAwareSync: false` to
298
+ force that compatibility path. The active path is available as
299
+ `renderer.getSynchronizationMode()` and as `getStats().syncMode`.
300
+
272
301
  ### VobSub renderer
273
302
 
274
303
  ```ts
@@ -290,6 +319,45 @@ renderer.setDebandThreshold(64)
290
319
  renderer.setDebandRange(15)
291
320
  ```
292
321
 
322
+ ### DVB renderer
323
+
324
+ ```ts
325
+ import { DvbRenderer } from 'libbitsub'
326
+
327
+ const renderer = new DvbRenderer({
328
+ video: videoElement,
329
+ subUrl: '/subtitles/track.dvb'
330
+ })
331
+ ```
332
+
333
+ DVB dumps use libbitsub framing:
334
+
335
+ ```
336
+ "DV" | pts_90k_be_u32 | payload_len_be_u32 | payload…
337
+ ```
338
+
339
+ `payload` is a PES data field (`0x20 0x00 …`) or raw segments (`sync_byte 0x0F`). Concatenated MPEG PES packets (`00 00 01 BD`) with PTS are also accepted.
340
+
341
+ The DVB decoder renders bitmap object coding method 0. Character-string and reserved object coding methods are ignored.
342
+
343
+ ### Live / push streams
344
+
345
+ PGS and DVB renderers can start without a URL or in-memory subtitle file. Push transport or demuxer chunks as they arrive; calls are processed in order even when they are made before renderer initialization completes.
346
+
347
+ ```ts
348
+ import { DvbRenderer } from 'libbitsub'
349
+
350
+ const renderer = new DvbRenderer({ video: videoElement })
351
+
352
+ const added = await renderer.append(dvbPesChunk) // newly indexed cues
353
+ const total = await renderer.flush() // finalize trailing input; total indexed cues
354
+
355
+ await renderer.reset() // clear cues/caches/display, then reuse the same renderer
356
+ await renderer.append(nextChannelChunk)
357
+ ```
358
+
359
+ `append()` accepts `Uint8Array` or `ArrayBuffer` without detaching the caller's buffer. `flush()` discards incomplete trailing bytes; later appends are still accepted. `reset()` keeps the canvas, worker session, render loop, and configuration alive while clearing the stream state. VobSub does not expose the push API because it depends on its `.idx`/container index.
360
+
293
361
  ### Automatic format detection
294
362
 
295
363
  ```ts
@@ -302,7 +370,7 @@ const renderer = createAutoSubtitleRenderer({
302
370
  })
303
371
  ```
304
372
 
305
- Automatic detection uses file hints when available and otherwise inspects the binary payload. `.mks` sources are treated as VobSub only when they contain an embedded `S_VOBSUB` track. If the format cannot be identified confidently, it throws instead of silently forcing a parser.
373
+ Automatic detection uses file hints when available and otherwise inspects the binary payload. `.idx` / `idxContent` still means VobSub. Bare `.sub` is content-probed for DVB before VobSub. `.mks` sources are treated as VobSub only when they contain an embedded `S_VOBSUB` track. If the format cannot be identified confidently, it throws instead of silently forcing a parser.
306
374
 
307
375
  ## Layout controls
308
376
 
@@ -608,7 +676,7 @@ Emitted events:
608
676
  | `loaded` | subtitle format and parser metadata |
609
677
  | `error` | subtitle format and `SubtitleDiagnosticErrorLike` |
610
678
  | `warning` | `SubtitleDiagnosticWarning` |
611
- | `renderer-change` | active backend: `webgpu`, `webgl2`, or `canvas2d` |
679
+ | `renderer-change` | active backend: `webgpu`, `webgl2`, `worker-offscreen`, or `canvas2d` |
612
680
  | `worker-state` | whether worker mode is enabled, ready, fallback status, and the active session ID |
613
681
  | `cache-change` | cached frame count, pending renders, and configured cache limit |
614
682
  | `cue-change` | current cue metadata or `null` when nothing is displayed |
@@ -634,6 +702,7 @@ const stats = renderer.getStats()
634
702
  - `pendingRenders`
635
703
  - `totalEntries`
636
704
  - `currentIndex`
705
+ - `syncMode`
637
706
 
638
707
  `getCacheStats()` adds worker/session state for the current renderer cache, while `getLastRenderInfo()` exposes the most recent render outcome with a status of `rendered`, `cleared`, `pending`, `empty`, or `failed`.
639
708
 
@@ -683,23 +752,31 @@ const parser = new UnifiedSubtitleParser({
683
752
  parser.loadAuto({ data: subtitleBytes, fileName: 'track.sup' })
684
753
  ```
685
754
 
686
- ## GPU backends
755
+ ## GPU / present backends
687
756
 
688
757
  libbitsub prefers:
689
758
 
690
- 1. WebGPU
691
- 2. WebGL2
692
- 3. Canvas2D
759
+ 1. WebGPU (main-thread present)
760
+ 2. WebGL2 (main-thread present)
761
+ 3. Worker OffscreenCanvas (decode + Canvas2D present off the UI thread)
762
+ 4. Canvas2D (main-thread fallback for older TVs)
693
763
 
694
764
  ```ts
695
- import { isWebGPUSupported } from 'libbitsub'
765
+ import { getRuntimeCapabilities, isWebGPUSupported } from 'libbitsub'
696
766
 
697
767
  console.log({
698
- webgpu: isWebGPUSupported()
768
+ webgpu: isWebGPUSupported(),
769
+ capabilities: getRuntimeCapabilities()
699
770
  })
700
771
  ```
701
772
 
702
- WebGL2 and Canvas2D fallback remain automatic. Use `onWebGPUFallback`, `onWebGL2Fallback`, `onEvent`, or `onWarning` if you need to observe backend changes.
773
+ When Worker OffscreenCanvas is selected, composition/present moves into the shared worker —
774
+ not only parsing — which reduces UI stalls during subtitle track switches on constrained devices.
775
+ The existing transferable RGBA path remains for main-thread GPU/Canvas2D present.
776
+
777
+ Use `onWebGPUFallback`, `onWebGL2Fallback`, `onEvent`, `onWarning`, or `getRuntimeCapabilities()`
778
+ to observe or explain the active backend path. Set `offscreenRender: false` to force main-thread
779
+ Canvas2D on the software tier.
703
780
 
704
781
  ## Compatibility & visual regression
705
782
 
@@ -736,8 +813,8 @@ Browser/device support matrix (including webOS TV): [docs/COMPATIBILITY.md](./do
736
813
  - `warmup(): Promise<void>` / `ready(): Promise<void>` pre-initialize the shared subtitle worker (including in-worker WASM). Safe to call multiple times; concurrent callers share one init promise. Prefer these in TV/player apps before the first track switch.
737
814
  - `isWorkerAvailable(): boolean` / `isWorkerReady(): boolean` report worker support and whether the shared worker has finished initializing.
738
815
  - `isWebGPUSupported(): boolean` checks WebGPU support.
739
- - `detectSubtitleFormat(source: AutoSubtitleSource): 'pgs' | 'vobsub' | null` detects the bitmap subtitle format from file hints or binary data.
740
- - `createAutoSubtitleRenderer(options: AutoVideoSubtitleOptions): PgsRenderer | VobSubRenderer` creates a high-level renderer after format detection.
816
+ - `detectSubtitleFormat(source: AutoSubtitleSource): 'pgs' | 'vobsub' | 'dvb' | null` detects the bitmap subtitle format from file hints or binary data.
817
+ - `createAutoSubtitleRenderer(options: AutoVideoSubtitleOptions): PgsRenderer | VobSubRenderer | DvbRenderer` creates a high-level renderer after format detection.
741
818
  - `openSubtitles(source, options?): Promise<OpenedSubtitles>` initializes WASM, auto-detects the low-level format, and returns a normalized parser handle.
742
819
  - `probeRangeSupport(url, options?)` / `fetchSubtitleAsset(url, options?, onChunk?)` / `fetchSubtitleText(url, options?)` perform Range-aware progressive asset downloads for custom loaders.
743
820
  - `renderFrameData(frame, options?): SubtitleRenderedFrameData | null` composes a `SubtitleData` frame into exportable pixels.
@@ -768,16 +845,23 @@ Browser/device support matrix (including webOS TV): [docs/COMPATIBILITY.md](./do
768
845
  - `clearFrameCache(): void` clears the renderer-side and parser-side frame cache.
769
846
  - `prefetchRange(startIndex: number, endIndex: number): Promise<void>` prefetches decoded frames for a cue range.
770
847
  - `prefetchAroundTime(time: number, before?: number, after?: number): Promise<void>` prefetches around a playback time in seconds.
848
+ - `append(data: Uint8Array | ArrayBuffer): Promise<number>` pushes live bytes and returns newly indexed cues.
849
+ - `flush(): Promise<number>` finalizes trailing input and returns the total cue count.
850
+ - `reset(): Promise<void>` clears live parser, cue, cache, and presentation state for reuse.
771
851
  - `dispose(): void` releases DOM, parser, and worker resources.
772
852
 
773
853
  #### `VobSubRenderer`
774
854
 
775
- - Supports all `PgsRenderer` methods above.
855
+ - Supports the common `PgsRenderer` methods above, except `append()`, `flush()`, and `reset()`.
776
856
  - `setDebandEnabled(enabled: boolean): void` enables or disables debanding.
777
857
  - `setDebandThreshold(threshold: number): void` updates the deband threshold.
778
858
  - `setDebandRange(range: number): void` updates the deband sample range.
779
859
  - `debandEnabled: boolean` reports whether debanding is enabled.
780
860
 
861
+ #### `DvbRenderer`
862
+
863
+ - Supports all `PgsRenderer` methods above, including the live push API (no debanding).
864
+
781
865
  ### Low-level parsers
782
866
 
783
867
  #### `PgsParser`
@@ -795,6 +879,12 @@ Browser/device support matrix (including webOS TV): [docs/COMPATIBILITY.md](./do
795
879
  - `clearCache(): void` clears parser-side caches.
796
880
  - `dispose(): void` frees parser resources.
797
881
 
882
+ #### `DvbParser`
883
+
884
+ - Same progressive surface as `PgsParser` for `"DV"`-framed dumps and MPEG PES streams.
885
+ - `load(data: Uint8Array): number` / `feed` / `finishFeed` / `renderAtIndex` / `renderAtTimestamp` / `getMetadata` / `getCueMetadata` / `dispose`.
886
+ - `getEndTimestamps(): Float64Array` returns the page-timeout-aware cue end timestamps in milliseconds.
887
+
798
888
  #### `VobSubParserLowLevel`
799
889
 
800
890
  - `loadFromData(idxContent: string, subData: Uint8Array): void` loads IDX and SUB data (simple in-memory path).
@@ -810,8 +900,9 @@ Browser/device support matrix (including webOS TV): [docs/COMPATIBILITY.md](./do
810
900
  - `loadPgs(data: Uint8Array): number` loads PGS data.
811
901
  - `loadVobSub(idxContent: string, subData: Uint8Array): void` loads VobSub from IDX and SUB.
812
902
  - `loadVobSubOnly(subData: Uint8Array): void` loads SUB-only VobSub data.
903
+ - `loadDvb(data: Uint8Array): number` loads DVB data.
813
904
  - `loadAuto(source: AutoSubtitleSource): SubtitleFormatName` detects and loads a supported bitmap subtitle format.
814
- - `format: 'pgs' | 'vobsub' | null` returns the active format.
905
+ - `format: 'pgs' | 'vobsub' | 'dvb' | null` returns the active format.
815
906
  - `getTimestamps()`, `count`, `findIndexAtTimestamp()`, `renderAtIndex()`, `renderAtTimestamp()`, `getMetadata()`, `getCueMetadata()`, `clearCache()`, and `dispose()` are available as on the format-specific parsers.
816
907
 
817
908
  ### Core option and data types
@@ -821,6 +912,10 @@ Browser/device support matrix (including webOS TV): [docs/COMPATIBILITY.md](./do
821
912
  ```ts
822
913
  interface VideoSubtitleOptions {
823
914
  video: HTMLVideoElement
915
+ container?: HTMLElement | ShadowRoot
916
+ canvas?: HTMLCanvasElement
917
+ devicePixelRatioCap?: number
918
+ backend?: 'auto' | 'webgpu' | 'webgl2' | 'worker-offscreen' | 'canvas2d'
824
919
  subUrl?: string
825
920
  subContent?: ArrayBuffer
826
921
  workerUrl?: string
@@ -829,6 +924,8 @@ interface VideoSubtitleOptions {
829
924
  onError?: (error: Error) => void
830
925
  onWebGPUFallback?: () => void
831
926
  onWebGL2Fallback?: () => void
927
+ offscreenRender?: boolean // default true — Worker OffscreenCanvas on Canvas2D tier
928
+ frameAwareSync?: boolean // default true — sync to presented-frame mediaTime when available
832
929
  displaySettings?: Partial<SubtitleDisplaySettings>
833
930
  cacheLimit?: number
834
931
  prefetchWindow?: {
@@ -883,7 +980,7 @@ type SubtitleRendererEvent =
883
980
  | { type: 'loaded'; format: SubtitleFormatName; metadata: SubtitleParserMetadata }
884
981
  | { type: 'error'; format: SubtitleFormatName; error: SubtitleDiagnosticErrorLike }
885
982
  | { type: 'warning'; warning: SubtitleDiagnosticWarning }
886
- | { type: 'renderer-change'; renderer: 'webgpu' | 'webgl2' | 'canvas2d' }
983
+ | { type: 'renderer-change'; renderer: 'webgpu' | 'webgl2' | 'worker-offscreen' | 'canvas2d' }
887
984
  | { type: 'worker-state'; enabled: boolean; ready: boolean; sessionId: string | null; fallback?: boolean }
888
985
  | { type: 'cache-change'; cachedFrames: number; pendingRenders: number; cacheLimit: number }
889
986
  | { type: 'cue-change'; cue: SubtitleCueMetadata | null }
@@ -916,7 +1013,7 @@ Related diagnostics shapes:
916
1013
 
917
1014
  ```ts
918
1015
  interface SubtitleParserMetadata {
919
- format: 'pgs' | 'vobsub'
1016
+ format: 'pgs' | 'vobsub' | 'dvb'
920
1017
  cueCount: number
921
1018
  screenWidth: number
922
1019
  screenHeight: number
@@ -1,6 +1,33 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
3
 
4
+ /**
5
+ * DVB subtitle parser and renderer exposed to JavaScript.
6
+ */
7
+ export class DvbParser {
8
+ free(): void;
9
+ [Symbol.dispose](): void;
10
+ clearCache(): void;
11
+ feed(data: Uint8Array): number;
12
+ findIndexAtTimestamp(time_ms: number): number;
13
+ finishFeed(): number;
14
+ getCueCompositionCount(index: number): number;
15
+ getCueEndTime(index: number): number;
16
+ getCuePageState(index: number): number;
17
+ getCueStartTime(index: number): number;
18
+ getEndTimestamps(): Float64Array;
19
+ getTimestamps(): Float64Array;
20
+ constructor();
21
+ parse(data: Uint8Array): number;
22
+ renderAtIndex(index: number): SubtitleFrame | undefined;
23
+ reset(): void;
24
+ readonly count: number;
25
+ readonly lastRenderIssue: string;
26
+ readonly pendingLen: number;
27
+ readonly screenHeight: number;
28
+ readonly screenWidth: number;
29
+ }
30
+
4
31
  /**
5
32
  * PGS subtitle parser and renderer exposed to JavaScript.
6
33
  */
@@ -65,6 +92,7 @@ export class SubtitleComposition {
65
92
  export enum SubtitleFormat {
66
93
  Pgs = 0,
67
94
  VobSub = 1,
95
+ Dvb = 2,
68
96
  }
69
97
 
70
98
  /**
@@ -81,7 +109,7 @@ export class SubtitleFrame {
81
109
  }
82
110
 
83
111
  /**
84
- * Unified subtitle renderer for both PGS and VobSub formats.
112
+ * Unified subtitle renderer for PGS, VobSub, and DVB formats.
85
113
  */
86
114
  export class SubtitleRenderer {
87
115
  free(): void;
@@ -93,6 +121,7 @@ export class SubtitleRenderer {
93
121
  getCueEndTime(index: number): number;
94
122
  getCueStartTime(index: number): number;
95
123
  getTimestamps(): Float64Array;
124
+ loadDvb(data: Uint8Array): number;
96
125
  loadPgs(data: Uint8Array): number;
97
126
  loadVobSub(idx_content: string, sub_data: Uint8Array): void;
98
127
  loadVobSubMks(mks_data: Uint8Array): void;
@@ -170,6 +199,7 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
170
199
 
171
200
  export interface InitOutput {
172
201
  readonly memory: WebAssembly.Memory;
202
+ readonly __wbg_dvbparser_free: (a: number, b: number) => void;
173
203
  readonly __wbg_pgsparser_free: (a: number, b: number) => void;
174
204
  readonly __wbg_renderresult_free: (a: number, b: number) => void;
175
205
  readonly __wbg_subtitlecomposition_free: (a: number, b: number) => void;
@@ -177,6 +207,25 @@ export interface InitOutput {
177
207
  readonly __wbg_subtitlerenderer_free: (a: number, b: number) => void;
178
208
  readonly __wbg_vobsubframe_free: (a: number, b: number) => void;
179
209
  readonly __wbg_vobsubparser_free: (a: number, b: number) => void;
210
+ readonly dvbparser_clearCache: (a: number) => void;
211
+ readonly dvbparser_count: (a: number) => number;
212
+ readonly dvbparser_feed: (a: number, b: number, c: number) => number;
213
+ readonly dvbparser_findIndexAtTimestamp: (a: number, b: number) => number;
214
+ readonly dvbparser_finishFeed: (a: number) => number;
215
+ readonly dvbparser_getCueCompositionCount: (a: number, b: number) => number;
216
+ readonly dvbparser_getCueEndTime: (a: number, b: number) => number;
217
+ readonly dvbparser_getCuePageState: (a: number, b: number) => number;
218
+ readonly dvbparser_getCueStartTime: (a: number, b: number) => number;
219
+ readonly dvbparser_getEndTimestamps: (a: number) => any;
220
+ readonly dvbparser_getTimestamps: (a: number) => any;
221
+ readonly dvbparser_lastRenderIssue: (a: number) => [number, number];
222
+ readonly dvbparser_new: () => number;
223
+ readonly dvbparser_parse: (a: number, b: number, c: number) => number;
224
+ readonly dvbparser_pendingLen: (a: number) => number;
225
+ readonly dvbparser_renderAtIndex: (a: number, b: number) => number;
226
+ readonly dvbparser_reset: (a: number) => void;
227
+ readonly dvbparser_screenHeight: (a: number) => number;
228
+ readonly dvbparser_screenWidth: (a: number) => number;
180
229
  readonly init: () => void;
181
230
  readonly pgsparser_clearCache: (a: number) => void;
182
231
  readonly pgsparser_count: (a: number) => number;
@@ -226,6 +275,7 @@ export interface InitOutput {
226
275
  readonly subtitlerenderer_hasIdxMetadata: (a: number) => number;
227
276
  readonly subtitlerenderer_language: (a: number) => [number, number];
228
277
  readonly subtitlerenderer_lastRenderIssue: (a: number) => [number, number];
278
+ readonly subtitlerenderer_loadDvb: (a: number, b: number, c: number) => number;
229
279
  readonly subtitlerenderer_loadPgs: (a: number, b: number, c: number) => number;
230
280
  readonly subtitlerenderer_loadVobSub: (a: number, b: number, c: number, d: number, e: number) => void;
231
281
  readonly subtitlerenderer_loadVobSubMks: (a: number, b: number, c: number) => [number, number];
package/pkg/libbitsub.js CHANGED
@@ -1,5 +1,166 @@
1
1
  /* @ts-self-types="./libbitsub.d.ts" */
2
2
 
3
+ /**
4
+ * DVB subtitle parser and renderer exposed to JavaScript.
5
+ */
6
+ export class DvbParser {
7
+ __destroy_into_raw() {
8
+ const ptr = this.__wbg_ptr;
9
+ this.__wbg_ptr = 0;
10
+ DvbParserFinalization.unregister(this);
11
+ return ptr;
12
+ }
13
+ free() {
14
+ const ptr = this.__destroy_into_raw();
15
+ wasm.__wbg_dvbparser_free(ptr, 0);
16
+ }
17
+ clearCache() {
18
+ wasm.dvbparser_clearCache(this.__wbg_ptr);
19
+ }
20
+ /**
21
+ * @returns {number}
22
+ */
23
+ get count() {
24
+ const ret = wasm.dvbparser_count(this.__wbg_ptr);
25
+ return ret >>> 0;
26
+ }
27
+ /**
28
+ * @param {Uint8Array} data
29
+ * @returns {number}
30
+ */
31
+ feed(data) {
32
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
33
+ const len0 = WASM_VECTOR_LEN;
34
+ const ret = wasm.dvbparser_feed(this.__wbg_ptr, ptr0, len0);
35
+ return ret >>> 0;
36
+ }
37
+ /**
38
+ * @param {number} time_ms
39
+ * @returns {number}
40
+ */
41
+ findIndexAtTimestamp(time_ms) {
42
+ const ret = wasm.dvbparser_findIndexAtTimestamp(this.__wbg_ptr, time_ms);
43
+ return ret;
44
+ }
45
+ /**
46
+ * @returns {number}
47
+ */
48
+ finishFeed() {
49
+ const ret = wasm.dvbparser_finishFeed(this.__wbg_ptr);
50
+ return ret >>> 0;
51
+ }
52
+ /**
53
+ * @param {number} index
54
+ * @returns {number}
55
+ */
56
+ getCueCompositionCount(index) {
57
+ const ret = wasm.dvbparser_getCueCompositionCount(this.__wbg_ptr, index);
58
+ return ret >>> 0;
59
+ }
60
+ /**
61
+ * @param {number} index
62
+ * @returns {number}
63
+ */
64
+ getCueEndTime(index) {
65
+ const ret = wasm.dvbparser_getCueEndTime(this.__wbg_ptr, index);
66
+ return ret;
67
+ }
68
+ /**
69
+ * @param {number} index
70
+ * @returns {number}
71
+ */
72
+ getCuePageState(index) {
73
+ const ret = wasm.dvbparser_getCuePageState(this.__wbg_ptr, index);
74
+ return ret;
75
+ }
76
+ /**
77
+ * @param {number} index
78
+ * @returns {number}
79
+ */
80
+ getCueStartTime(index) {
81
+ const ret = wasm.dvbparser_getCueStartTime(this.__wbg_ptr, index);
82
+ return ret;
83
+ }
84
+ /**
85
+ * @returns {Float64Array}
86
+ */
87
+ getEndTimestamps() {
88
+ const ret = wasm.dvbparser_getEndTimestamps(this.__wbg_ptr);
89
+ return ret;
90
+ }
91
+ /**
92
+ * @returns {Float64Array}
93
+ */
94
+ getTimestamps() {
95
+ const ret = wasm.dvbparser_getTimestamps(this.__wbg_ptr);
96
+ return ret;
97
+ }
98
+ /**
99
+ * @returns {string}
100
+ */
101
+ get lastRenderIssue() {
102
+ let deferred1_0;
103
+ let deferred1_1;
104
+ try {
105
+ const ret = wasm.dvbparser_lastRenderIssue(this.__wbg_ptr);
106
+ deferred1_0 = ret[0];
107
+ deferred1_1 = ret[1];
108
+ return getStringFromWasm0(ret[0], ret[1]);
109
+ } finally {
110
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
111
+ }
112
+ }
113
+ constructor() {
114
+ const ret = wasm.dvbparser_new();
115
+ this.__wbg_ptr = ret;
116
+ DvbParserFinalization.register(this, this.__wbg_ptr, this);
117
+ return this;
118
+ }
119
+ /**
120
+ * @param {Uint8Array} data
121
+ * @returns {number}
122
+ */
123
+ parse(data) {
124
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
125
+ const len0 = WASM_VECTOR_LEN;
126
+ const ret = wasm.dvbparser_parse(this.__wbg_ptr, ptr0, len0);
127
+ return ret >>> 0;
128
+ }
129
+ /**
130
+ * @returns {number}
131
+ */
132
+ get pendingLen() {
133
+ const ret = wasm.dvbparser_pendingLen(this.__wbg_ptr);
134
+ return ret >>> 0;
135
+ }
136
+ /**
137
+ * @param {number} index
138
+ * @returns {SubtitleFrame | undefined}
139
+ */
140
+ renderAtIndex(index) {
141
+ const ret = wasm.dvbparser_renderAtIndex(this.__wbg_ptr, index);
142
+ return ret === 0 ? undefined : SubtitleFrame.__wrap(ret);
143
+ }
144
+ reset() {
145
+ wasm.dvbparser_reset(this.__wbg_ptr);
146
+ }
147
+ /**
148
+ * @returns {number}
149
+ */
150
+ get screenHeight() {
151
+ const ret = wasm.dvbparser_screenHeight(this.__wbg_ptr);
152
+ return ret;
153
+ }
154
+ /**
155
+ * @returns {number}
156
+ */
157
+ get screenWidth() {
158
+ const ret = wasm.dvbparser_screenWidth(this.__wbg_ptr);
159
+ return ret;
160
+ }
161
+ }
162
+ if (Symbol.dispose) DvbParser.prototype[Symbol.dispose] = DvbParser.prototype.free;
163
+
3
164
  /**
4
165
  * PGS subtitle parser and renderer exposed to JavaScript.
5
166
  */
@@ -306,11 +467,12 @@ if (Symbol.dispose) SubtitleComposition.prototype[Symbol.dispose] = SubtitleComp
306
467
 
307
468
  /**
308
469
  * Subtitle format type.
309
- * @enum {0 | 1}
470
+ * @enum {0 | 1 | 2}
310
471
  */
311
472
  export const SubtitleFormat = Object.freeze({
312
473
  Pgs: 0, "0": "Pgs",
313
474
  VobSub: 1, "1": "VobSub",
475
+ Dvb: 2, "2": "Dvb",
314
476
  });
315
477
 
316
478
  /**
@@ -366,7 +528,7 @@ export class SubtitleFrame {
366
528
  if (Symbol.dispose) SubtitleFrame.prototype[Symbol.dispose] = SubtitleFrame.prototype.free;
367
529
 
368
530
  /**
369
- * Unified subtitle renderer for both PGS and VobSub formats.
531
+ * Unified subtitle renderer for PGS, VobSub, and DVB formats.
370
532
  */
371
533
  export class SubtitleRenderer {
372
534
  __destroy_into_raw() {
@@ -405,7 +567,7 @@ export class SubtitleRenderer {
405
567
  */
406
568
  get format() {
407
569
  const ret = wasm.subtitlerenderer_format(this.__wbg_ptr);
408
- return ret === 2 ? undefined : ret;
570
+ return ret === 3 ? undefined : ret;
409
571
  }
410
572
  /**
411
573
  * @param {number} index
@@ -475,6 +637,16 @@ export class SubtitleRenderer {
475
637
  wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
476
638
  }
477
639
  }
640
+ /**
641
+ * @param {Uint8Array} data
642
+ * @returns {number}
643
+ */
644
+ loadDvb(data) {
645
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
646
+ const len0 = WASM_VECTOR_LEN;
647
+ const ret = wasm.subtitlerenderer_loadDvb(this.__wbg_ptr, ptr0, len0);
648
+ return ret >>> 0;
649
+ }
478
650
  /**
479
651
  * @param {Uint8Array} data
480
652
  * @returns {number}
@@ -946,6 +1118,9 @@ function __wbg_get_imports() {
946
1118
  };
947
1119
  }
948
1120
 
1121
+ const DvbParserFinalization = (typeof FinalizationRegistry === 'undefined')
1122
+ ? { register: () => {}, unregister: () => {} }
1123
+ : new FinalizationRegistry(ptr => wasm.__wbg_dvbparser_free(ptr, 1));
949
1124
  const PgsParserFinalization = (typeof FinalizationRegistry === 'undefined')
950
1125
  ? { register: () => {}, unregister: () => {} }
951
1126
  : new FinalizationRegistry(ptr => wasm.__wbg_pgsparser_free(ptr, 1));
Binary file
@@ -1,6 +1,7 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
3
  export const memory: WebAssembly.Memory;
4
+ export const __wbg_dvbparser_free: (a: number, b: number) => void;
4
5
  export const __wbg_pgsparser_free: (a: number, b: number) => void;
5
6
  export const __wbg_renderresult_free: (a: number, b: number) => void;
6
7
  export const __wbg_subtitlecomposition_free: (a: number, b: number) => void;
@@ -8,6 +9,25 @@ export const __wbg_subtitleframe_free: (a: number, b: number) => void;
8
9
  export const __wbg_subtitlerenderer_free: (a: number, b: number) => void;
9
10
  export const __wbg_vobsubframe_free: (a: number, b: number) => void;
10
11
  export const __wbg_vobsubparser_free: (a: number, b: number) => void;
12
+ export const dvbparser_clearCache: (a: number) => void;
13
+ export const dvbparser_count: (a: number) => number;
14
+ export const dvbparser_feed: (a: number, b: number, c: number) => number;
15
+ export const dvbparser_findIndexAtTimestamp: (a: number, b: number) => number;
16
+ export const dvbparser_finishFeed: (a: number) => number;
17
+ export const dvbparser_getCueCompositionCount: (a: number, b: number) => number;
18
+ export const dvbparser_getCueEndTime: (a: number, b: number) => number;
19
+ export const dvbparser_getCuePageState: (a: number, b: number) => number;
20
+ export const dvbparser_getCueStartTime: (a: number, b: number) => number;
21
+ export const dvbparser_getEndTimestamps: (a: number) => any;
22
+ export const dvbparser_getTimestamps: (a: number) => any;
23
+ export const dvbparser_lastRenderIssue: (a: number) => [number, number];
24
+ export const dvbparser_new: () => number;
25
+ export const dvbparser_parse: (a: number, b: number, c: number) => number;
26
+ export const dvbparser_pendingLen: (a: number) => number;
27
+ export const dvbparser_renderAtIndex: (a: number, b: number) => number;
28
+ export const dvbparser_reset: (a: number) => void;
29
+ export const dvbparser_screenHeight: (a: number) => number;
30
+ export const dvbparser_screenWidth: (a: number) => number;
11
31
  export const init: () => void;
12
32
  export const pgsparser_clearCache: (a: number) => void;
13
33
  export const pgsparser_count: (a: number) => number;
@@ -57,6 +77,7 @@ export const subtitlerenderer_getTimestamps: (a: number) => any;
57
77
  export const subtitlerenderer_hasIdxMetadata: (a: number) => number;
58
78
  export const subtitlerenderer_language: (a: number) => [number, number];
59
79
  export const subtitlerenderer_lastRenderIssue: (a: number) => [number, number];
80
+ export const subtitlerenderer_loadDvb: (a: number, b: number, c: number) => number;
60
81
  export const subtitlerenderer_loadPgs: (a: number, b: number, c: number) => number;
61
82
  export const subtitlerenderer_loadVobSub: (a: number, b: number, c: number, d: number, e: number) => void;
62
83
  export const subtitlerenderer_loadVobSubMks: (a: number, b: number, c: number) => [number, number];
package/pkg/package.json CHANGED
@@ -4,8 +4,8 @@
4
4
  "collaborators": [
5
5
  "altqx"
6
6
  ],
7
- "description": "High-performance WASM renderer for graphical subtitles (PGS and VobSub)",
8
- "version": "1.11.0",
7
+ "description": "High-performance WASM renderer for graphical subtitles (PGS, VobSub, and DVB)",
8
+ "version": "1.12.1",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
@@ -24,8 +24,8 @@
24
24
  "keywords": [
25
25
  "pgs",
26
26
  "vobsub",
27
+ "dvb",
27
28
  "subtitle",
28
- "wasm",
29
- "rendering"
29
+ "wasm"
30
30
  ]
31
31
  }