libbitsub 1.7.0 → 1.7.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.
package/README.md CHANGED
@@ -384,222 +384,225 @@ console.log({
384
384
  - If worker startup fails, the high-level API falls back to main-thread parsing.
385
385
  - The library only handles bitmap subtitle formats. It does not parse text subtitle formats such as SRT or ASS.
386
386
 
387
- ## Low-Level API (Programmatic Use)
387
+ ## API Reference
388
388
 
389
- For more control over rendering, use the low-level parsers directly.
389
+ ### Top-level exports
390
390
 
391
- ### PGS Subtitles (Low-Level)
391
+ - `initWasm(): Promise<void>` initializes the WASM module.
392
+ - `isWasmInitialized(): boolean` reports whether initialization has completed.
393
+ - `isWebGPUSupported(): boolean` checks WebGPU support.
394
+ - `detectSubtitleFormat(source: AutoSubtitleSource): 'pgs' | 'vobsub' | null` detects the bitmap subtitle format from file hints or binary data.
395
+ - `createAutoSubtitleRenderer(options: AutoVideoSubtitleOptions): PgsRenderer | VobSubRenderer` creates a high-level renderer after format detection.
396
+ - Legacy aliases remain exported: `PGSRenderer`, `VobsubRenderer`, `UnifiedSubtitleRenderer`.
392
397
 
393
- ```typescript
394
- import { initWasm, PgsParser } from 'libbitsub'
398
+ ### High-level renderers
395
399
 
396
- await initWasm()
400
+ #### `PgsRenderer`
397
401
 
398
- const parser = new PgsParser()
402
+ - `constructor(options: VideoSubtitleOptions)` creates a video-synced PGS renderer.
403
+ - `getDisplaySettings(): SubtitleDisplaySettings` returns the current layout settings.
404
+ - `setDisplaySettings(settings: Partial<SubtitleDisplaySettings>): void` updates layout settings.
405
+ - `resetDisplaySettings(): void` resets layout settings to defaults.
406
+ - `getStats(): SubtitleRendererStats` returns render statistics.
407
+ - `getMetadata(): SubtitleParserMetadata | null` returns track-level metadata.
408
+ - `getCurrentCueMetadata(): SubtitleCueMetadata | null` returns the currently displayed cue metadata.
409
+ - `getCueMetadata(index: number): SubtitleCueMetadata | null` returns metadata for a specific cue.
410
+ - `getCacheLimit(): number` returns the active frame-cache limit.
411
+ - `setCacheLimit(limit: number): void` updates the frame-cache limit.
412
+ - `clearFrameCache(): void` clears the renderer-side and parser-side frame cache.
413
+ - `prefetchRange(startIndex: number, endIndex: number): Promise<void>` prefetches decoded frames for a cue range.
414
+ - `prefetchAroundTime(time: number, before?: number, after?: number): Promise<void>` prefetches around a playback time in seconds.
415
+ - `dispose(): void` releases DOM, parser, and worker resources.
399
416
 
400
- // Load PGS data from a .sup file
401
- const response = await fetch('subtitles.sup')
402
- const data = new Uint8Array(await response.arrayBuffer())
403
- parser.load(data)
417
+ #### `VobSubRenderer`
404
418
 
405
- // Get timestamps
406
- const timestamps = parser.getTimestamps() // Float64Array in milliseconds
419
+ - Supports all `PgsRenderer` methods above.
420
+ - `setDebandEnabled(enabled: boolean): void` enables or disables debanding.
421
+ - `setDebandThreshold(threshold: number): void` updates the deband threshold.
422
+ - `setDebandRange(range: number): void` updates the deband sample range.
423
+ - `debandEnabled: boolean` reports whether debanding is enabled.
407
424
 
408
- // Render at a specific time
409
- const subtitleData = parser.renderAtTimestamp(currentTimeInSeconds)
410
- if (subtitleData) {
411
- for (const comp of subtitleData.compositionData) {
412
- ctx.putImageData(comp.pixelData, comp.x, comp.y)
413
- }
414
- }
425
+ ### Low-level parsers
415
426
 
416
- // Clean up
417
- parser.dispose()
418
- ```
427
+ #### `PgsParser`
419
428
 
420
- ### VobSub Subtitles (Low-Level)
429
+ - `load(data: Uint8Array): number` loads PGS data and returns the cue count.
430
+ - `getTimestamps(): Float64Array` returns cue timestamps in milliseconds.
431
+ - `count: number` returns the number of cues.
432
+ - `findIndexAtTimestamp(timeSeconds: number): number` finds the cue index for a playback time in seconds.
433
+ - `renderAtIndex(index: number): SubtitleData | undefined` renders a cue by index.
434
+ - `renderAtTimestamp(timeSeconds: number): SubtitleData | undefined` renders a cue at a playback time.
435
+ - `getMetadata(): SubtitleParserMetadata` returns parser metadata.
436
+ - `getCueMetadata(index: number): SubtitleCueMetadata | null` returns cue metadata.
437
+ - `clearCache(): void` clears parser-side caches.
438
+ - `dispose(): void` frees parser resources.
421
439
 
422
- ```typescript
423
- import { initWasm, VobSubParserLowLevel } from 'libbitsub'
440
+ #### `VobSubParserLowLevel`
424
441
 
425
- await initWasm()
442
+ - `loadFromData(idxContent: string, subData: Uint8Array): void` loads IDX and SUB data.
443
+ - `loadFromSubOnly(subData: Uint8Array): void` loads SUB-only VobSub data.
444
+ - `getTimestamps(): Float64Array`, `count`, `findIndexAtTimestamp()`, `renderAtIndex()`, `renderAtTimestamp()`, `getMetadata()`, `getCueMetadata()`, `clearCache()`, and `dispose()` behave like `PgsParser`.
445
+ - `setDebandEnabled(enabled: boolean): void`, `setDebandThreshold(threshold: number): void`, `setDebandRange(range: number): void`, and `debandEnabled` control debanding.
426
446
 
427
- const parser = new VobSubParserLowLevel()
447
+ #### `UnifiedSubtitleParser`
428
448
 
429
- // Load from IDX + SUB files
430
- const idxResponse = await fetch('subtitles.idx')
431
- const idxContent = await idxResponse.text()
432
- const subResponse = await fetch('subtitles.sub')
433
- const subData = new Uint8Array(await subResponse.arrayBuffer())
449
+ - `loadPgs(data: Uint8Array): number` loads PGS data.
450
+ - `loadVobSub(idxContent: string, subData: Uint8Array): void` loads VobSub from IDX and SUB.
451
+ - `loadVobSubOnly(subData: Uint8Array): void` loads SUB-only VobSub data.
452
+ - `loadAuto(source: AutoSubtitleSource): SubtitleFormatName` detects and loads a supported bitmap subtitle format.
453
+ - `format: 'pgs' | 'vobsub' | null` returns the active format.
454
+ - `getTimestamps()`, `count`, `findIndexAtTimestamp()`, `renderAtIndex()`, `renderAtTimestamp()`, `getMetadata()`, `getCueMetadata()`, `clearCache()`, and `dispose()` are available as on the format-specific parsers.
434
455
 
435
- parser.loadFromData(idxContent, subData)
456
+ ### Core option and data types
436
457
 
437
- // Or load from SUB file only
438
- // parser.loadFromSubOnly(subData);
458
+ #### `VideoSubtitleOptions`
439
459
 
440
- // Render
441
- const subtitleData = parser.renderAtTimestamp(currentTimeInSeconds)
442
- if (subtitleData) {
443
- for (const comp of subtitleData.compositionData) {
444
- ctx.putImageData(comp.pixelData, comp.x, comp.y)
460
+ ```ts
461
+ interface VideoSubtitleOptions {
462
+ video: HTMLVideoElement
463
+ subUrl?: string
464
+ subContent?: ArrayBuffer
465
+ workerUrl?: string
466
+ onLoading?: () => void
467
+ onLoaded?: () => void
468
+ onError?: (error: Error) => void
469
+ onWebGPUFallback?: () => void
470
+ onWebGL2Fallback?: () => void
471
+ displaySettings?: Partial<SubtitleDisplaySettings>
472
+ cacheLimit?: number
473
+ prefetchWindow?: {
474
+ before?: number
475
+ after?: number
445
476
  }
477
+ onEvent?: (event: SubtitleRendererEvent) => void
446
478
  }
447
-
448
- parser.dispose()
449
479
  ```
450
480
 
451
- ### Unified Parser
452
-
453
- For handling both formats with a single API:
454
-
455
- ```typescript
456
- import { initWasm, UnifiedSubtitleParser } from 'libbitsub'
457
-
458
- await initWasm()
459
-
460
- const parser = new UnifiedSubtitleParser()
461
-
462
- // Load PGS
463
- parser.loadPgs(pgsData)
464
-
465
- // Or load VobSub
466
- // parser.loadVobSub(idxContent, subData);
467
-
468
- console.log(parser.format) // 'pgs' or 'vobsub'
469
-
470
- const subtitleData = parser.renderAtTimestamp(time)
471
- // ... render to canvas
481
+ #### `VideoVobSubOptions`
472
482
 
473
- parser.dispose()
483
+ ```ts
484
+ interface VideoVobSubOptions extends VideoSubtitleOptions {
485
+ idxUrl?: string
486
+ idxContent?: string
487
+ }
474
488
  ```
475
489
 
476
- ## API Reference
477
-
478
- ### High-Level (Video-Integrated)
479
-
480
- #### `PgsRenderer`
481
-
482
- - `constructor(options: VideoSubtitleOptions)` - Create video-integrated PGS renderer
483
- - `getDisplaySettings(): SubtitleDisplaySettings` - Get current display settings
484
- - `setDisplaySettings(settings: Partial<SubtitleDisplaySettings>): void` - Update display settings
485
- - `resetDisplaySettings(): void` - Reset display settings to defaults
486
- - `getStats(): SubtitleRendererStats` - Get performance statistics
487
- - `dispose(): void` - Clean up all resources
490
+ #### `AutoVideoSubtitleOptions`
488
491
 
489
- #### `VobSubRenderer`
490
-
491
- - `constructor(options: VideoVobSubOptions)` - Create video-integrated VobSub renderer
492
- - `getDisplaySettings(): SubtitleDisplaySettings` - Get current display settings
493
- - `setDisplaySettings(settings: Partial<SubtitleDisplaySettings>): void` - Update display settings
494
- - `resetDisplaySettings(): void` - Reset display settings to defaults
495
- - `getStats(): SubtitleRendererStats` - Get performance statistics
496
- - `setDebandEnabled(enabled: boolean): void` - Enable/disable debanding filter
497
- - `setDebandThreshold(threshold: number): void` - Set debanding threshold (0.0-255.0)
498
- - `setDebandRange(range: number): void` - Set debanding sample range (1-64)
499
- - `debandEnabled: boolean` - Check if debanding is enabled
500
- - `dispose(): void` - Clean up all resources
501
-
502
- ### Low-Level (Programmatic)
492
+ ```ts
493
+ interface AutoVideoSubtitleOptions extends Omit<VideoVobSubOptions, 'subUrl' | 'idxUrl'> {
494
+ subUrl?: string
495
+ idxUrl?: string
496
+ fileName?: string
497
+ }
498
+ ```
503
499
 
504
- #### `PgsParser`
500
+ #### `SubtitleDisplaySettings`
505
501
 
506
- - `load(data: Uint8Array): number` - Load PGS data, returns display set count
507
- - `getTimestamps(): Float64Array` - Get all timestamps in milliseconds
508
- - `count: number` - Number of display sets
509
- - `findIndexAtTimestamp(timeSeconds: number): number` - Find index for timestamp
510
- - `renderAtIndex(index: number): SubtitleData | undefined` - Render at index
511
- - `renderAtTimestamp(timeSeconds: number): SubtitleData | undefined` - Render at time
512
- - `clearCache(): void` - Clear decoded bitmap cache
513
- - `dispose(): void` - Release resources
502
+ ```ts
503
+ interface SubtitleDisplaySettings {
504
+ scale: number
505
+ verticalOffset: number
506
+ horizontalOffset: number
507
+ horizontalAlign: 'left' | 'center' | 'right'
508
+ bottomPadding: number
509
+ safeArea: number
510
+ opacity: number
511
+ }
512
+ ```
514
513
 
515
- #### `VobSubParserLowLevel`
514
+ #### `SubtitleRendererEvent`
516
515
 
517
- - `loadFromData(idxContent: string, subData: Uint8Array): void` - Load IDX + SUB
518
- - `loadFromSubOnly(subData: Uint8Array): void` - Load SUB only
519
- - `setDebandEnabled(enabled: boolean): void` - Enable/disable debanding filter
520
- - `setDebandThreshold(threshold: number): void` - Set debanding threshold (0.0-255.0)
521
- - `setDebandRange(range: number): void` - Set debanding sample range (1-64)
522
- - `debandEnabled: boolean` - Check if debanding is enabled
523
- - Same rendering methods as PgsParser
516
+ ```ts
517
+ type SubtitleRendererEvent =
518
+ | { type: 'loading'; format: SubtitleFormatName }
519
+ | { type: 'loaded'; format: SubtitleFormatName; metadata: SubtitleParserMetadata }
520
+ | { type: 'error'; format: SubtitleFormatName; error: Error }
521
+ | { type: 'renderer-change'; renderer: 'webgpu' | 'webgl2' | 'canvas2d' }
522
+ | { type: 'worker-state'; enabled: boolean; ready: boolean; sessionId: string | null; fallback?: boolean }
523
+ | { type: 'cache-change'; cachedFrames: number; pendingRenders: number; cacheLimit: number }
524
+ | { type: 'cue-change'; cue: SubtitleCueMetadata | null }
525
+ | { type: 'stats'; stats: SubtitleRendererStatsSnapshot }
526
+ ```
524
527
 
525
- #### `UnifiedSubtitleParser`
528
+ #### `SubtitleRendererStats` and `SubtitleRendererStatsSnapshot`
526
529
 
527
- - `loadPgs(data: Uint8Array): number` - Load PGS data
528
- - `loadVobSub(idxContent: string, subData: Uint8Array): void` - Load VobSub
529
- - `loadVobSubOnly(subData: Uint8Array): void` - Load SUB only
530
- - `format: 'pgs' | 'vobsub' | null` - Current format
531
- - Same rendering methods as above
530
+ Both shapes expose:
532
531
 
533
- ### Types
532
+ - `framesRendered`
533
+ - `framesDropped`
534
+ - `avgRenderTime`
535
+ - `maxRenderTime`
536
+ - `minRenderTime`
537
+ - `lastRenderTime`
538
+ - `renderFps`
539
+ - `usingWorker`
540
+ - `cachedFrames`
541
+ - `pendingRenders`
542
+ - `totalEntries`
543
+ - `currentIndex`
534
544
 
535
- #### `VideoSubtitleOptions`
545
+ #### `SubtitleParserMetadata`
536
546
 
537
- ```typescript
538
- interface VideoSubtitleOptions {
539
- video: HTMLVideoElement // Video element to sync with
540
- subUrl?: string // URL to subtitle file (provide this OR subContent)
541
- subContent?: ArrayBuffer // Direct subtitle content (provide this OR subUrl)
542
- workerUrl?: string // Worker URL (for API compatibility)
543
- onLoading?: () => void // Called when subtitle loading starts
544
- onLoaded?: () => void // Called when subtitle loading completes
545
- onError?: (error: Error) => void // Called when subtitle loading fails
546
- onWebGPUFallback?: () => void // Called when WebGPU init fails
547
- onWebGL2Fallback?: () => void // Called when WebGL2 init fails
547
+ ```ts
548
+ interface SubtitleParserMetadata {
549
+ format: 'pgs' | 'vobsub'
550
+ cueCount: number
551
+ screenWidth: number
552
+ screenHeight: number
553
+ language?: string | null
554
+ trackId?: string | null
555
+ hasIdxMetadata?: boolean
548
556
  }
549
557
  ```
550
558
 
551
- #### `VideoVobSubOptions`
559
+ #### `SubtitleCueMetadata`
552
560
 
553
- ```typescript
554
- interface VideoVobSubOptions extends VideoSubtitleOptions {
555
- idxUrl?: string // URL to .idx file (optional, defaults to subUrl with .idx extension)
556
- idxContent?: string // Direct .idx content (provide this OR idxUrl)
561
+ ```ts
562
+ interface SubtitleCueMetadata {
563
+ index: number
564
+ format: 'pgs' | 'vobsub'
565
+ startTime: number
566
+ endTime: number
567
+ duration: number
568
+ screenWidth: number
569
+ screenHeight: number
570
+ bounds: SubtitleCueBounds | null
571
+ compositionCount: number
572
+ paletteId?: number
573
+ compositionState?: number
574
+ language?: string | null
575
+ trackId?: string | null
576
+ filePosition?: number
557
577
  }
558
578
  ```
559
579
 
560
- #### `SubtitleDisplaySettings`
561
-
562
- ```typescript
563
- interface SubtitleDisplaySettings {
564
- // Scale factor (1.0 = 100%, 0.5 = 50%, 2.0 = 200%)
565
- scale: number
566
- // Vertical offset as % of video height (-50 to 50)
567
- verticalOffset: number
568
- }
569
- ```
580
+ #### `AutoSubtitleSource`
570
581
 
571
- #### `SubtitleRendererStats`
572
-
573
- ```typescript
574
- interface SubtitleRendererStats {
575
- framesRendered: number // Total frames rendered since initialization
576
- framesDropped: number // Frames dropped due to slow rendering
577
- avgRenderTime: number // Average render time in milliseconds
578
- maxRenderTime: number // Maximum render time in milliseconds
579
- minRenderTime: number // Minimum render time in milliseconds
580
- lastRenderTime: number // Last render time in milliseconds
581
- renderFps: number // Current FPS (renders per second)
582
- usingWorker: boolean // Whether rendering is using web worker
583
- cachedFrames: number // Number of cached frames
584
- pendingRenders: number // Number of pending renders
585
- totalEntries: number // Total subtitle entries/display sets
586
- currentIndex: number // Current subtitle index being displayed
582
+ ```ts
583
+ interface AutoSubtitleSource {
584
+ data?: ArrayBuffer | Uint8Array
585
+ subData?: ArrayBuffer | Uint8Array
586
+ idxContent?: string
587
+ fileName?: string
588
+ subUrl?: string
589
+ idxUrl?: string
587
590
  }
588
591
  ```
589
592
 
590
593
  #### `SubtitleData`
591
594
 
592
- ```typescript
595
+ ```ts
593
596
  interface SubtitleData {
594
- width: number // Screen width
595
- height: number // Screen height
597
+ width: number
598
+ height: number
596
599
  compositionData: SubtitleCompositionData[]
597
600
  }
598
601
 
599
602
  interface SubtitleCompositionData {
600
- pixelData: ImageData // RGBA pixel data
601
- x: number // X position
602
- y: number // Y position
603
+ pixelData: ImageData
604
+ x: number
605
+ y: number
603
606
  }
604
607
  ```
605
608
 
@@ -31,11 +31,14 @@ export declare class WebGPURenderer {
31
31
  private _canvas;
32
32
  private _initPromise;
33
33
  private _initialized;
34
+ private _lastCanvasWidth;
35
+ private _lastCanvasHeight;
34
36
  /**
35
37
  * Initialize the WebGPU renderer.
36
38
  * Returns a promise that resolves when initialization is complete.
37
39
  */
38
40
  init(): Promise<void>;
41
+ private assertShaderModuleValid;
39
42
  private _initDevice;
40
43
  /**
41
44
  * Configure the canvas for WebGPU rendering.
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-renderer.d.ts","sourceRoot":"","sources":["../../src/ts/webgpu-renderer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAqEtD,UAAU,WAAW;IACnB,OAAO,EAAE,UAAU,CAAA;IACnB,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,+GAA+G;IAC/G,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAA;IACpC,yFAAyF;IACzF,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,MAAM,EAAE,SAAS,GAAG,IAAI,CAAO;IAC/B,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAO;IACvC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAO;IACzC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAO;IACjC,eAAe,EAAE,kBAAkB,GAAG,IAAI,CAAO;IAGjD,aAAa,EAAE,SAAS,GAAG,IAAI,CAAO;IAGtC,eAAe,EAAE,SAAS,EAAE,CAAK;IAGjC,QAAQ,EAAE,WAAW,EAAE,CAAK;IAC5B,sBAAsB,EAAE,UAAU,EAAE,CAAK;IAEzC,MAAM,EAAE,gBAAgB,CAAe;IAEvC,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,YAAY,CAAQ;IAE5B;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAI1B;YAEa,WAAW;IA0GzB;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BvF;IAED;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAO9C;IAED,OAAO,CAAC,iBAAiB;IAiBzB;;OAEG;IACH,MAAM,CACJ,YAAY,EAAE,uBAAuB,EAAE,EACvC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,IAAI,CAqJN;IAED;;OAEG;IACH,KAAK,IAAI,IAAI,CAmBZ;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,OAAO,IAAI,IAAI,CAuBd;CACF"}
1
+ {"version":3,"file":"webgpu-renderer.d.ts","sourceRoot":"","sources":["../../src/ts/webgpu-renderer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AA2EtD,UAAU,WAAW;IACnB,OAAO,EAAE,UAAU,CAAA;IACnB,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,+GAA+G;IAC/G,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAA;IACpC,yFAAyF;IACzF,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,MAAM,EAAE,SAAS,GAAG,IAAI,CAAO;IAC/B,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAO;IACvC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAO;IACzC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAO;IACjC,eAAe,EAAE,kBAAkB,GAAG,IAAI,CAAO;IAGjD,aAAa,EAAE,SAAS,GAAG,IAAI,CAAO;IAGtC,eAAe,EAAE,SAAS,EAAE,CAAK;IAGjC,QAAQ,EAAE,WAAW,EAAE,CAAK;IAC5B,sBAAsB,EAAE,UAAU,EAAE,CAAK;IAEzC,MAAM,EAAE,gBAAgB,CAAe;IAEvC,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,gBAAgB,CAAI;IAC5B,OAAO,CAAC,iBAAiB,CAAI;IAE7B;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAI1B;YAEa,uBAAuB;YAgBvB,WAAW;IA6GzB;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCvF;IAED;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAU9C;IAED,OAAO,CAAC,iBAAiB;IAiBzB;;OAEG;IACH,MAAM,CACJ,YAAY,EAAE,uBAAuB,EAAE,EACvC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,IAAI,CA6JN;IAED;;OAEG;IACH,KAAK,IAAI,IAAI,CAwBZ;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,OAAO,IAAI,IAAI,CAyBd;CACF"}
@@ -51,6 +51,12 @@ fn vertexMain(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
51
51
  `;
52
52
  // WGSL Fragment Shader - sample RGBA texture directly
53
53
  const FRAGMENT_SHADER = /* wgsl */ `
54
+ struct Uniforms {
55
+ resolution: vec2f,
56
+ opacity: f32,
57
+ }
58
+
59
+ @group(0) @binding(0) var<uniform> uniforms: Uniforms;
54
60
  @group(0) @binding(2) var texSampler: sampler;
55
61
  @group(0) @binding(3) var tex: texture_2d<f32>;
56
62
 
@@ -91,6 +97,8 @@ export class WebGPURenderer {
91
97
  _canvas = null;
92
98
  _initPromise = null;
93
99
  _initialized = false;
100
+ _lastCanvasWidth = 0;
101
+ _lastCanvasHeight = 0;
94
102
  /**
95
103
  * Initialize the WebGPU renderer.
96
104
  * Returns a promise that resolves when initialization is complete.
@@ -101,6 +109,19 @@ export class WebGPURenderer {
101
109
  this._initPromise = this._initDevice();
102
110
  return this._initPromise;
103
111
  }
112
+ async assertShaderModuleValid(module, label) {
113
+ const info = await module.getCompilationInfo();
114
+ const errors = info.messages.filter(message => message.type === 'error');
115
+ if (errors.length === 0)
116
+ return;
117
+ const formatted = errors
118
+ .map(message => {
119
+ const line = message.lineNum > 0 ? `:${message.lineNum}:${message.linePos}` : '';
120
+ return `${label}${line} ${message.message}`;
121
+ })
122
+ .join('\n');
123
+ throw new Error(`WebGPU ${label} shader compilation failed:\n${formatted}`);
124
+ }
104
125
  async _initDevice() {
105
126
  if (!navigator.gpu) {
106
127
  throw new Error('WebGPU not supported');
@@ -120,6 +141,8 @@ export class WebGPURenderer {
120
141
  const fragmentModule = this.device.createShaderModule({
121
142
  code: FRAGMENT_SHADER
122
143
  });
144
+ await this.assertShaderModuleValid(vertexModule, 'vertex');
145
+ await this.assertShaderModuleValid(fragmentModule, 'fragment');
123
146
  // Create sampler - use linear filtering for smooth scaling
124
147
  this.sampler = this.device.createSampler({
125
148
  magFilter: 'linear',
@@ -162,7 +185,7 @@ export class WebGPURenderer {
162
185
  bindGroupLayouts: [this.bindGroupLayout]
163
186
  });
164
187
  // Create render pipeline with alpha blending
165
- this.pipeline = this.device.createRenderPipeline({
188
+ this.pipeline = await this.device.createRenderPipelineAsync({
166
189
  layout: pipelineLayout,
167
190
  vertex: {
168
191
  module: vertexModule,
@@ -203,7 +226,15 @@ export class WebGPURenderer {
203
226
  if (!this.device) {
204
227
  throw new Error('WebGPU device not initialized');
205
228
  }
229
+ if (width <= 0 || height <= 0) {
230
+ return;
231
+ }
206
232
  this._canvas = canvas;
233
+ // Update canvas size before configuring to keep the swap chain in sync.
234
+ canvas.width = width;
235
+ canvas.height = height;
236
+ this._lastCanvasWidth = width;
237
+ this._lastCanvasHeight = height;
207
238
  // Get WebGPU context
208
239
  if (!this.context) {
209
240
  this.context = canvas.getContext('webgpu');
@@ -216,9 +247,6 @@ export class WebGPURenderer {
216
247
  alphaMode: 'premultiplied'
217
248
  });
218
249
  }
219
- // Update canvas size
220
- canvas.width = width;
221
- canvas.height = height;
222
250
  // Update uniform buffer with resolution
223
251
  this.device.queue.writeBuffer(this.uniformBuffer, 0, new Float32Array([width, height, 1, 0]));
224
252
  }
@@ -226,10 +254,14 @@ export class WebGPURenderer {
226
254
  * Update canvas dimensions.
227
255
  */
228
256
  updateSize(width, height) {
229
- if (!this.device || !this._canvas)
257
+ if (!this.device || !this._canvas || width <= 0 || height <= 0)
258
+ return;
259
+ if (width === this._lastCanvasWidth && height === this._lastCanvasHeight)
230
260
  return;
231
261
  this._canvas.width = width;
232
262
  this._canvas.height = height;
263
+ this._lastCanvasWidth = width;
264
+ this._lastCanvasHeight = height;
233
265
  this.device.queue.writeBuffer(this.uniformBuffer, 0, new Float32Array([width, height, 1, 0]));
234
266
  }
235
267
  createTextureInfo(width, height) {
@@ -251,11 +283,20 @@ export class WebGPURenderer {
251
283
  * Render subtitle compositions to the canvas.
252
284
  */
253
285
  render(compositions, screenWidth, screenHeight, scaleX, scaleY, shiftX, shiftY, opacity) {
254
- if (!this.device || !this.context || !this.pipeline)
286
+ if (!this.device || !this.context || !this.pipeline || !this._canvas)
255
287
  return;
288
+ let textureView;
289
+ try {
290
+ const currentTexture = this.context.getCurrentTexture();
291
+ if (currentTexture.width === 0 || currentTexture.height === 0)
292
+ return;
293
+ textureView = currentTexture.createView();
294
+ }
295
+ catch {
296
+ return;
297
+ }
256
298
  this.device.queue.writeBuffer(this.uniformBuffer, 0, new Float32Array([this._canvas.width, this._canvas.height, opacity, 0]));
257
299
  const commandEncoder = this.device.createCommandEncoder();
258
- const textureView = this.context.getCurrentTexture().createView();
259
300
  // Begin render pass with clear
260
301
  const renderPass = commandEncoder.beginRenderPass({
261
302
  colorAttachments: [
@@ -380,20 +421,27 @@ export class WebGPURenderer {
380
421
  clear() {
381
422
  if (!this.device || !this.context)
382
423
  return;
383
- const commandEncoder = this.device.createCommandEncoder();
384
- const textureView = this.context.getCurrentTexture().createView();
385
- const renderPass = commandEncoder.beginRenderPass({
386
- colorAttachments: [
387
- {
388
- view: textureView,
389
- clearValue: { r: 0, g: 0, b: 0, a: 0 },
390
- loadOp: 'clear',
391
- storeOp: 'store'
392
- }
393
- ]
394
- });
395
- renderPass.end();
396
- this.device.queue.submit([commandEncoder.finish()]);
424
+ try {
425
+ const currentTexture = this.context.getCurrentTexture();
426
+ if (currentTexture.width === 0 || currentTexture.height === 0)
427
+ return;
428
+ const commandEncoder = this.device.createCommandEncoder();
429
+ const renderPass = commandEncoder.beginRenderPass({
430
+ colorAttachments: [
431
+ {
432
+ view: currentTexture.createView(),
433
+ clearValue: { r: 0, g: 0, b: 0, a: 0 },
434
+ loadOp: 'clear',
435
+ storeOp: 'store'
436
+ }
437
+ ]
438
+ });
439
+ renderPass.end();
440
+ this.device.queue.submit([commandEncoder.finish()]);
441
+ }
442
+ catch {
443
+ return;
444
+ }
397
445
  }
398
446
  /**
399
447
  * Check if renderer is initialized.
@@ -424,6 +472,8 @@ export class WebGPURenderer {
424
472
  this._canvas = null;
425
473
  this._initialized = false;
426
474
  this._initPromise = null;
475
+ this._lastCanvasWidth = 0;
476
+ this._lastCanvasHeight = 0;
427
477
  }
428
478
  }
429
479
  //# sourceMappingURL=webgpu-renderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-renderer.js","sourceRoot":"","sources":["../../src/ts/webgpu-renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webgpu-renderer.js","sourceRoot":"","sources":["../../src/ts/webgpu-renderer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libbitsub",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "author": "altqx",
5
5
  "license": "MIT",
6
6
  "description": "High-performance WASM renderer for graphical subtitles (PGS and VobSub)",
package/pkg/README.md CHANGED
@@ -384,222 +384,225 @@ console.log({
384
384
  - If worker startup fails, the high-level API falls back to main-thread parsing.
385
385
  - The library only handles bitmap subtitle formats. It does not parse text subtitle formats such as SRT or ASS.
386
386
 
387
- ## Low-Level API (Programmatic Use)
387
+ ## API Reference
388
388
 
389
- For more control over rendering, use the low-level parsers directly.
389
+ ### Top-level exports
390
390
 
391
- ### PGS Subtitles (Low-Level)
391
+ - `initWasm(): Promise<void>` initializes the WASM module.
392
+ - `isWasmInitialized(): boolean` reports whether initialization has completed.
393
+ - `isWebGPUSupported(): boolean` checks WebGPU support.
394
+ - `detectSubtitleFormat(source: AutoSubtitleSource): 'pgs' | 'vobsub' | null` detects the bitmap subtitle format from file hints or binary data.
395
+ - `createAutoSubtitleRenderer(options: AutoVideoSubtitleOptions): PgsRenderer | VobSubRenderer` creates a high-level renderer after format detection.
396
+ - Legacy aliases remain exported: `PGSRenderer`, `VobsubRenderer`, `UnifiedSubtitleRenderer`.
392
397
 
393
- ```typescript
394
- import { initWasm, PgsParser } from 'libbitsub'
398
+ ### High-level renderers
395
399
 
396
- await initWasm()
400
+ #### `PgsRenderer`
397
401
 
398
- const parser = new PgsParser()
402
+ - `constructor(options: VideoSubtitleOptions)` creates a video-synced PGS renderer.
403
+ - `getDisplaySettings(): SubtitleDisplaySettings` returns the current layout settings.
404
+ - `setDisplaySettings(settings: Partial<SubtitleDisplaySettings>): void` updates layout settings.
405
+ - `resetDisplaySettings(): void` resets layout settings to defaults.
406
+ - `getStats(): SubtitleRendererStats` returns render statistics.
407
+ - `getMetadata(): SubtitleParserMetadata | null` returns track-level metadata.
408
+ - `getCurrentCueMetadata(): SubtitleCueMetadata | null` returns the currently displayed cue metadata.
409
+ - `getCueMetadata(index: number): SubtitleCueMetadata | null` returns metadata for a specific cue.
410
+ - `getCacheLimit(): number` returns the active frame-cache limit.
411
+ - `setCacheLimit(limit: number): void` updates the frame-cache limit.
412
+ - `clearFrameCache(): void` clears the renderer-side and parser-side frame cache.
413
+ - `prefetchRange(startIndex: number, endIndex: number): Promise<void>` prefetches decoded frames for a cue range.
414
+ - `prefetchAroundTime(time: number, before?: number, after?: number): Promise<void>` prefetches around a playback time in seconds.
415
+ - `dispose(): void` releases DOM, parser, and worker resources.
399
416
 
400
- // Load PGS data from a .sup file
401
- const response = await fetch('subtitles.sup')
402
- const data = new Uint8Array(await response.arrayBuffer())
403
- parser.load(data)
417
+ #### `VobSubRenderer`
404
418
 
405
- // Get timestamps
406
- const timestamps = parser.getTimestamps() // Float64Array in milliseconds
419
+ - Supports all `PgsRenderer` methods above.
420
+ - `setDebandEnabled(enabled: boolean): void` enables or disables debanding.
421
+ - `setDebandThreshold(threshold: number): void` updates the deband threshold.
422
+ - `setDebandRange(range: number): void` updates the deband sample range.
423
+ - `debandEnabled: boolean` reports whether debanding is enabled.
407
424
 
408
- // Render at a specific time
409
- const subtitleData = parser.renderAtTimestamp(currentTimeInSeconds)
410
- if (subtitleData) {
411
- for (const comp of subtitleData.compositionData) {
412
- ctx.putImageData(comp.pixelData, comp.x, comp.y)
413
- }
414
- }
425
+ ### Low-level parsers
415
426
 
416
- // Clean up
417
- parser.dispose()
418
- ```
427
+ #### `PgsParser`
419
428
 
420
- ### VobSub Subtitles (Low-Level)
429
+ - `load(data: Uint8Array): number` loads PGS data and returns the cue count.
430
+ - `getTimestamps(): Float64Array` returns cue timestamps in milliseconds.
431
+ - `count: number` returns the number of cues.
432
+ - `findIndexAtTimestamp(timeSeconds: number): number` finds the cue index for a playback time in seconds.
433
+ - `renderAtIndex(index: number): SubtitleData | undefined` renders a cue by index.
434
+ - `renderAtTimestamp(timeSeconds: number): SubtitleData | undefined` renders a cue at a playback time.
435
+ - `getMetadata(): SubtitleParserMetadata` returns parser metadata.
436
+ - `getCueMetadata(index: number): SubtitleCueMetadata | null` returns cue metadata.
437
+ - `clearCache(): void` clears parser-side caches.
438
+ - `dispose(): void` frees parser resources.
421
439
 
422
- ```typescript
423
- import { initWasm, VobSubParserLowLevel } from 'libbitsub'
440
+ #### `VobSubParserLowLevel`
424
441
 
425
- await initWasm()
442
+ - `loadFromData(idxContent: string, subData: Uint8Array): void` loads IDX and SUB data.
443
+ - `loadFromSubOnly(subData: Uint8Array): void` loads SUB-only VobSub data.
444
+ - `getTimestamps(): Float64Array`, `count`, `findIndexAtTimestamp()`, `renderAtIndex()`, `renderAtTimestamp()`, `getMetadata()`, `getCueMetadata()`, `clearCache()`, and `dispose()` behave like `PgsParser`.
445
+ - `setDebandEnabled(enabled: boolean): void`, `setDebandThreshold(threshold: number): void`, `setDebandRange(range: number): void`, and `debandEnabled` control debanding.
426
446
 
427
- const parser = new VobSubParserLowLevel()
447
+ #### `UnifiedSubtitleParser`
428
448
 
429
- // Load from IDX + SUB files
430
- const idxResponse = await fetch('subtitles.idx')
431
- const idxContent = await idxResponse.text()
432
- const subResponse = await fetch('subtitles.sub')
433
- const subData = new Uint8Array(await subResponse.arrayBuffer())
449
+ - `loadPgs(data: Uint8Array): number` loads PGS data.
450
+ - `loadVobSub(idxContent: string, subData: Uint8Array): void` loads VobSub from IDX and SUB.
451
+ - `loadVobSubOnly(subData: Uint8Array): void` loads SUB-only VobSub data.
452
+ - `loadAuto(source: AutoSubtitleSource): SubtitleFormatName` detects and loads a supported bitmap subtitle format.
453
+ - `format: 'pgs' | 'vobsub' | null` returns the active format.
454
+ - `getTimestamps()`, `count`, `findIndexAtTimestamp()`, `renderAtIndex()`, `renderAtTimestamp()`, `getMetadata()`, `getCueMetadata()`, `clearCache()`, and `dispose()` are available as on the format-specific parsers.
434
455
 
435
- parser.loadFromData(idxContent, subData)
456
+ ### Core option and data types
436
457
 
437
- // Or load from SUB file only
438
- // parser.loadFromSubOnly(subData);
458
+ #### `VideoSubtitleOptions`
439
459
 
440
- // Render
441
- const subtitleData = parser.renderAtTimestamp(currentTimeInSeconds)
442
- if (subtitleData) {
443
- for (const comp of subtitleData.compositionData) {
444
- ctx.putImageData(comp.pixelData, comp.x, comp.y)
460
+ ```ts
461
+ interface VideoSubtitleOptions {
462
+ video: HTMLVideoElement
463
+ subUrl?: string
464
+ subContent?: ArrayBuffer
465
+ workerUrl?: string
466
+ onLoading?: () => void
467
+ onLoaded?: () => void
468
+ onError?: (error: Error) => void
469
+ onWebGPUFallback?: () => void
470
+ onWebGL2Fallback?: () => void
471
+ displaySettings?: Partial<SubtitleDisplaySettings>
472
+ cacheLimit?: number
473
+ prefetchWindow?: {
474
+ before?: number
475
+ after?: number
445
476
  }
477
+ onEvent?: (event: SubtitleRendererEvent) => void
446
478
  }
447
-
448
- parser.dispose()
449
479
  ```
450
480
 
451
- ### Unified Parser
452
-
453
- For handling both formats with a single API:
454
-
455
- ```typescript
456
- import { initWasm, UnifiedSubtitleParser } from 'libbitsub'
457
-
458
- await initWasm()
459
-
460
- const parser = new UnifiedSubtitleParser()
461
-
462
- // Load PGS
463
- parser.loadPgs(pgsData)
464
-
465
- // Or load VobSub
466
- // parser.loadVobSub(idxContent, subData);
467
-
468
- console.log(parser.format) // 'pgs' or 'vobsub'
469
-
470
- const subtitleData = parser.renderAtTimestamp(time)
471
- // ... render to canvas
481
+ #### `VideoVobSubOptions`
472
482
 
473
- parser.dispose()
483
+ ```ts
484
+ interface VideoVobSubOptions extends VideoSubtitleOptions {
485
+ idxUrl?: string
486
+ idxContent?: string
487
+ }
474
488
  ```
475
489
 
476
- ## API Reference
477
-
478
- ### High-Level (Video-Integrated)
479
-
480
- #### `PgsRenderer`
481
-
482
- - `constructor(options: VideoSubtitleOptions)` - Create video-integrated PGS renderer
483
- - `getDisplaySettings(): SubtitleDisplaySettings` - Get current display settings
484
- - `setDisplaySettings(settings: Partial<SubtitleDisplaySettings>): void` - Update display settings
485
- - `resetDisplaySettings(): void` - Reset display settings to defaults
486
- - `getStats(): SubtitleRendererStats` - Get performance statistics
487
- - `dispose(): void` - Clean up all resources
490
+ #### `AutoVideoSubtitleOptions`
488
491
 
489
- #### `VobSubRenderer`
490
-
491
- - `constructor(options: VideoVobSubOptions)` - Create video-integrated VobSub renderer
492
- - `getDisplaySettings(): SubtitleDisplaySettings` - Get current display settings
493
- - `setDisplaySettings(settings: Partial<SubtitleDisplaySettings>): void` - Update display settings
494
- - `resetDisplaySettings(): void` - Reset display settings to defaults
495
- - `getStats(): SubtitleRendererStats` - Get performance statistics
496
- - `setDebandEnabled(enabled: boolean): void` - Enable/disable debanding filter
497
- - `setDebandThreshold(threshold: number): void` - Set debanding threshold (0.0-255.0)
498
- - `setDebandRange(range: number): void` - Set debanding sample range (1-64)
499
- - `debandEnabled: boolean` - Check if debanding is enabled
500
- - `dispose(): void` - Clean up all resources
501
-
502
- ### Low-Level (Programmatic)
492
+ ```ts
493
+ interface AutoVideoSubtitleOptions extends Omit<VideoVobSubOptions, 'subUrl' | 'idxUrl'> {
494
+ subUrl?: string
495
+ idxUrl?: string
496
+ fileName?: string
497
+ }
498
+ ```
503
499
 
504
- #### `PgsParser`
500
+ #### `SubtitleDisplaySettings`
505
501
 
506
- - `load(data: Uint8Array): number` - Load PGS data, returns display set count
507
- - `getTimestamps(): Float64Array` - Get all timestamps in milliseconds
508
- - `count: number` - Number of display sets
509
- - `findIndexAtTimestamp(timeSeconds: number): number` - Find index for timestamp
510
- - `renderAtIndex(index: number): SubtitleData | undefined` - Render at index
511
- - `renderAtTimestamp(timeSeconds: number): SubtitleData | undefined` - Render at time
512
- - `clearCache(): void` - Clear decoded bitmap cache
513
- - `dispose(): void` - Release resources
502
+ ```ts
503
+ interface SubtitleDisplaySettings {
504
+ scale: number
505
+ verticalOffset: number
506
+ horizontalOffset: number
507
+ horizontalAlign: 'left' | 'center' | 'right'
508
+ bottomPadding: number
509
+ safeArea: number
510
+ opacity: number
511
+ }
512
+ ```
514
513
 
515
- #### `VobSubParserLowLevel`
514
+ #### `SubtitleRendererEvent`
516
515
 
517
- - `loadFromData(idxContent: string, subData: Uint8Array): void` - Load IDX + SUB
518
- - `loadFromSubOnly(subData: Uint8Array): void` - Load SUB only
519
- - `setDebandEnabled(enabled: boolean): void` - Enable/disable debanding filter
520
- - `setDebandThreshold(threshold: number): void` - Set debanding threshold (0.0-255.0)
521
- - `setDebandRange(range: number): void` - Set debanding sample range (1-64)
522
- - `debandEnabled: boolean` - Check if debanding is enabled
523
- - Same rendering methods as PgsParser
516
+ ```ts
517
+ type SubtitleRendererEvent =
518
+ | { type: 'loading'; format: SubtitleFormatName }
519
+ | { type: 'loaded'; format: SubtitleFormatName; metadata: SubtitleParserMetadata }
520
+ | { type: 'error'; format: SubtitleFormatName; error: Error }
521
+ | { type: 'renderer-change'; renderer: 'webgpu' | 'webgl2' | 'canvas2d' }
522
+ | { type: 'worker-state'; enabled: boolean; ready: boolean; sessionId: string | null; fallback?: boolean }
523
+ | { type: 'cache-change'; cachedFrames: number; pendingRenders: number; cacheLimit: number }
524
+ | { type: 'cue-change'; cue: SubtitleCueMetadata | null }
525
+ | { type: 'stats'; stats: SubtitleRendererStatsSnapshot }
526
+ ```
524
527
 
525
- #### `UnifiedSubtitleParser`
528
+ #### `SubtitleRendererStats` and `SubtitleRendererStatsSnapshot`
526
529
 
527
- - `loadPgs(data: Uint8Array): number` - Load PGS data
528
- - `loadVobSub(idxContent: string, subData: Uint8Array): void` - Load VobSub
529
- - `loadVobSubOnly(subData: Uint8Array): void` - Load SUB only
530
- - `format: 'pgs' | 'vobsub' | null` - Current format
531
- - Same rendering methods as above
530
+ Both shapes expose:
532
531
 
533
- ### Types
532
+ - `framesRendered`
533
+ - `framesDropped`
534
+ - `avgRenderTime`
535
+ - `maxRenderTime`
536
+ - `minRenderTime`
537
+ - `lastRenderTime`
538
+ - `renderFps`
539
+ - `usingWorker`
540
+ - `cachedFrames`
541
+ - `pendingRenders`
542
+ - `totalEntries`
543
+ - `currentIndex`
534
544
 
535
- #### `VideoSubtitleOptions`
545
+ #### `SubtitleParserMetadata`
536
546
 
537
- ```typescript
538
- interface VideoSubtitleOptions {
539
- video: HTMLVideoElement // Video element to sync with
540
- subUrl?: string // URL to subtitle file (provide this OR subContent)
541
- subContent?: ArrayBuffer // Direct subtitle content (provide this OR subUrl)
542
- workerUrl?: string // Worker URL (for API compatibility)
543
- onLoading?: () => void // Called when subtitle loading starts
544
- onLoaded?: () => void // Called when subtitle loading completes
545
- onError?: (error: Error) => void // Called when subtitle loading fails
546
- onWebGPUFallback?: () => void // Called when WebGPU init fails
547
- onWebGL2Fallback?: () => void // Called when WebGL2 init fails
547
+ ```ts
548
+ interface SubtitleParserMetadata {
549
+ format: 'pgs' | 'vobsub'
550
+ cueCount: number
551
+ screenWidth: number
552
+ screenHeight: number
553
+ language?: string | null
554
+ trackId?: string | null
555
+ hasIdxMetadata?: boolean
548
556
  }
549
557
  ```
550
558
 
551
- #### `VideoVobSubOptions`
559
+ #### `SubtitleCueMetadata`
552
560
 
553
- ```typescript
554
- interface VideoVobSubOptions extends VideoSubtitleOptions {
555
- idxUrl?: string // URL to .idx file (optional, defaults to subUrl with .idx extension)
556
- idxContent?: string // Direct .idx content (provide this OR idxUrl)
561
+ ```ts
562
+ interface SubtitleCueMetadata {
563
+ index: number
564
+ format: 'pgs' | 'vobsub'
565
+ startTime: number
566
+ endTime: number
567
+ duration: number
568
+ screenWidth: number
569
+ screenHeight: number
570
+ bounds: SubtitleCueBounds | null
571
+ compositionCount: number
572
+ paletteId?: number
573
+ compositionState?: number
574
+ language?: string | null
575
+ trackId?: string | null
576
+ filePosition?: number
557
577
  }
558
578
  ```
559
579
 
560
- #### `SubtitleDisplaySettings`
561
-
562
- ```typescript
563
- interface SubtitleDisplaySettings {
564
- // Scale factor (1.0 = 100%, 0.5 = 50%, 2.0 = 200%)
565
- scale: number
566
- // Vertical offset as % of video height (-50 to 50)
567
- verticalOffset: number
568
- }
569
- ```
580
+ #### `AutoSubtitleSource`
570
581
 
571
- #### `SubtitleRendererStats`
572
-
573
- ```typescript
574
- interface SubtitleRendererStats {
575
- framesRendered: number // Total frames rendered since initialization
576
- framesDropped: number // Frames dropped due to slow rendering
577
- avgRenderTime: number // Average render time in milliseconds
578
- maxRenderTime: number // Maximum render time in milliseconds
579
- minRenderTime: number // Minimum render time in milliseconds
580
- lastRenderTime: number // Last render time in milliseconds
581
- renderFps: number // Current FPS (renders per second)
582
- usingWorker: boolean // Whether rendering is using web worker
583
- cachedFrames: number // Number of cached frames
584
- pendingRenders: number // Number of pending renders
585
- totalEntries: number // Total subtitle entries/display sets
586
- currentIndex: number // Current subtitle index being displayed
582
+ ```ts
583
+ interface AutoSubtitleSource {
584
+ data?: ArrayBuffer | Uint8Array
585
+ subData?: ArrayBuffer | Uint8Array
586
+ idxContent?: string
587
+ fileName?: string
588
+ subUrl?: string
589
+ idxUrl?: string
587
590
  }
588
591
  ```
589
592
 
590
593
  #### `SubtitleData`
591
594
 
592
- ```typescript
595
+ ```ts
593
596
  interface SubtitleData {
594
- width: number // Screen width
595
- height: number // Screen height
597
+ width: number
598
+ height: number
596
599
  compositionData: SubtitleCompositionData[]
597
600
  }
598
601
 
599
602
  interface SubtitleCompositionData {
600
- pixelData: ImageData // RGBA pixel data
601
- x: number // X position
602
- y: number // Y position
603
+ pixelData: ImageData
604
+ x: number
605
+ y: number
603
606
  }
604
607
  ```
605
608
 
package/pkg/libbitsub.js CHANGED
@@ -865,7 +865,7 @@ export function init() {
865
865
  function __wbg_get_imports() {
866
866
  const import0 = {
867
867
  __proto__: null,
868
- __wbg___wbindgen_throw_df03e93053e0f4bc: function(arg0, arg1) {
868
+ __wbg___wbindgen_throw_6ddd609b62940d55: function(arg0, arg1) {
869
869
  throw new Error(getStringFromWasm0(arg0, arg1));
870
870
  },
871
871
  __wbg_error_a6fa202b58aa1cd3: function(arg0, arg1) {
@@ -879,7 +879,7 @@ function __wbg_get_imports() {
879
879
  wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
880
880
  }
881
881
  },
882
- __wbg_length_5e07cf181b2745fb: function(arg0) {
882
+ __wbg_length_ea16607d7b61445b: function(arg0) {
883
883
  const ret = arg0.length;
884
884
  return ret;
885
885
  },
@@ -887,22 +887,22 @@ function __wbg_get_imports() {
887
887
  const ret = new Error();
888
888
  return ret;
889
889
  },
890
- __wbg_new_from_slice_e98c2bb0a59c32a0: function(arg0, arg1) {
890
+ __wbg_new_from_slice_22da9388ac046e50: function(arg0, arg1) {
891
891
  const ret = new Uint8Array(getArrayU8FromWasm0(arg0, arg1));
892
892
  return ret;
893
893
  },
894
- __wbg_new_with_length_9b57e4a9683723fa: function(arg0) {
894
+ __wbg_new_with_length_825018a1616e9e55: function(arg0) {
895
895
  const ret = new Uint8Array(arg0 >>> 0);
896
896
  return ret;
897
897
  },
898
- __wbg_new_with_length_fbe257d20500214d: function(arg0) {
898
+ __wbg_new_with_length_eae667475c36c4e4: function(arg0) {
899
899
  const ret = new Float64Array(arg0 >>> 0);
900
900
  return ret;
901
901
  },
902
- __wbg_prototypesetcall_d1a7133bc8d83aa9: function(arg0, arg1, arg2) {
902
+ __wbg_prototypesetcall_d62e5099504357e6: function(arg0, arg1, arg2) {
903
903
  Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
904
904
  },
905
- __wbg_set_index_0a7915ae2e548e40: function(arg0, arg1, arg2) {
905
+ __wbg_set_index_a56629feb5ac0ffa: function(arg0, arg1, arg2) {
906
906
  arg0[arg1 >>> 0] = arg2;
907
907
  },
908
908
  __wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {
Binary file
package/pkg/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "altqx"
6
6
  ],
7
7
  "description": "High-performance WASM renderer for graphical subtitles (PGS and VobSub)",
8
- "version": "1.7.0",
8
+ "version": "1.7.1",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",