avbridge 2.2.1 → 2.3.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.
Files changed (119) hide show
  1. package/CHANGELOG.md +80 -1
  2. package/NOTICE.md +2 -2
  3. package/README.md +2 -3
  4. package/THIRD_PARTY_LICENSES.md +2 -2
  5. package/dist/avi-2JPBSHGA.js +183 -0
  6. package/dist/avi-2JPBSHGA.js.map +1 -0
  7. package/dist/avi-F6WZJK5T.cjs +185 -0
  8. package/dist/avi-F6WZJK5T.cjs.map +1 -0
  9. package/dist/{avi-GCGM7OJI.js → avi-NJXAXUXK.js} +9 -3
  10. package/dist/avi-NJXAXUXK.js.map +1 -0
  11. package/dist/{avi-6SJLWIWW.cjs → avi-W6L3BTWU.cjs} +10 -4
  12. package/dist/avi-W6L3BTWU.cjs.map +1 -0
  13. package/dist/{chunk-ILKDNBSE.js → chunk-2PGRFCWB.js} +59 -10
  14. package/dist/chunk-2PGRFCWB.js.map +1 -0
  15. package/dist/chunk-5YAWWKA3.js +18 -0
  16. package/dist/chunk-5YAWWKA3.js.map +1 -0
  17. package/dist/chunk-6UUT4BEA.cjs +219 -0
  18. package/dist/chunk-6UUT4BEA.cjs.map +1 -0
  19. package/dist/{chunk-UF2N5L63.cjs → chunk-7RGG6ME7.cjs} +489 -76
  20. package/dist/chunk-7RGG6ME7.cjs.map +1 -0
  21. package/dist/{chunk-WD2ZNQA7.js → chunk-DCSOQH2N.js} +7 -4
  22. package/dist/chunk-DCSOQH2N.js.map +1 -0
  23. package/dist/chunk-F3LQJKXK.cjs +20 -0
  24. package/dist/chunk-F3LQJKXK.cjs.map +1 -0
  25. package/dist/chunk-IAYKFGFG.js +200 -0
  26. package/dist/chunk-IAYKFGFG.js.map +1 -0
  27. package/dist/chunk-NNVOHKXJ.cjs +204 -0
  28. package/dist/chunk-NNVOHKXJ.cjs.map +1 -0
  29. package/dist/{chunk-DMWARSEF.js → chunk-NV7ILLWH.js} +483 -74
  30. package/dist/chunk-NV7ILLWH.js.map +1 -0
  31. package/dist/{chunk-HZLQNKFN.cjs → chunk-QQXBPW72.js} +54 -15
  32. package/dist/chunk-QQXBPW72.js.map +1 -0
  33. package/dist/chunk-XKPSTC34.cjs +210 -0
  34. package/dist/chunk-XKPSTC34.cjs.map +1 -0
  35. package/dist/{chunk-L4NPOJ36.cjs → chunk-Z33SBWL5.cjs} +7 -4
  36. package/dist/chunk-Z33SBWL5.cjs.map +1 -0
  37. package/dist/element-browser.js +558 -85
  38. package/dist/element-browser.js.map +1 -1
  39. package/dist/element.cjs +4 -4
  40. package/dist/element.d.cts +1 -1
  41. package/dist/element.d.ts +1 -1
  42. package/dist/element.js +3 -3
  43. package/dist/index.cjs +174 -26
  44. package/dist/index.cjs.map +1 -1
  45. package/dist/index.d.cts +48 -4
  46. package/dist/index.d.ts +48 -4
  47. package/dist/index.js +93 -12
  48. package/dist/index.js.map +1 -1
  49. package/dist/libav-http-reader-AZLE7YFS.cjs +16 -0
  50. package/dist/{libav-http-reader-FPYDBMYK.cjs.map → libav-http-reader-AZLE7YFS.cjs.map} +1 -1
  51. package/dist/libav-http-reader-WXG3Z7AI.js +3 -0
  52. package/dist/{libav-http-reader-NQJVY273.js.map → libav-http-reader-WXG3Z7AI.js.map} +1 -1
  53. package/dist/{player-U2NPmFvA.d.cts → player-B6WB74RD.d.cts} +62 -3
  54. package/dist/{player-U2NPmFvA.d.ts → player-B6WB74RD.d.ts} +62 -3
  55. package/dist/player.cjs +5500 -0
  56. package/dist/player.cjs.map +1 -0
  57. package/dist/player.d.cts +649 -0
  58. package/dist/player.d.ts +649 -0
  59. package/dist/player.js +5498 -0
  60. package/dist/player.js.map +1 -0
  61. package/dist/source-73CAH6HW.cjs +28 -0
  62. package/dist/{source-CN43EI7Z.cjs.map → source-73CAH6HW.cjs.map} +1 -1
  63. package/dist/source-F656KYYV.js +3 -0
  64. package/dist/{source-FFZ7TW2B.js.map → source-F656KYYV.js.map} +1 -1
  65. package/dist/source-QJR3OHTW.js +3 -0
  66. package/dist/source-QJR3OHTW.js.map +1 -0
  67. package/dist/source-VB74JQ7Z.cjs +28 -0
  68. package/dist/source-VB74JQ7Z.cjs.map +1 -0
  69. package/dist/variant-routing-434STYAB.js +3 -0
  70. package/dist/{variant-routing-JOBWXYKD.js.map → variant-routing-434STYAB.js.map} +1 -1
  71. package/dist/variant-routing-HONNAA6R.cjs +12 -0
  72. package/dist/{variant-routing-GOHB2RZN.cjs.map → variant-routing-HONNAA6R.cjs.map} +1 -1
  73. package/package.json +9 -1
  74. package/src/classify/rules.ts +27 -5
  75. package/src/convert/remux.ts +8 -0
  76. package/src/convert/transcode.ts +41 -8
  77. package/src/element/avbridge-player.ts +845 -0
  78. package/src/element/player-icons.ts +25 -0
  79. package/src/element/player-styles.ts +472 -0
  80. package/src/errors.ts +47 -0
  81. package/src/index.ts +23 -0
  82. package/src/player-element.ts +18 -0
  83. package/src/player.ts +104 -12
  84. package/src/plugins/builtin.ts +2 -2
  85. package/src/probe/avi.ts +4 -0
  86. package/src/probe/index.ts +40 -10
  87. package/src/strategies/fallback/audio-output.ts +31 -0
  88. package/src/strategies/fallback/decoder.ts +83 -2
  89. package/src/strategies/fallback/index.ts +29 -4
  90. package/src/strategies/fallback/variant-routing.ts +7 -13
  91. package/src/strategies/fallback/video-renderer.ts +124 -32
  92. package/src/strategies/hybrid/decoder.ts +131 -20
  93. package/src/strategies/hybrid/index.ts +31 -5
  94. package/src/strategies/remux/mse.ts +12 -2
  95. package/src/subtitles/index.ts +7 -3
  96. package/src/types.ts +53 -1
  97. package/src/util/libav-http-reader.ts +5 -1
  98. package/src/util/source.ts +28 -8
  99. package/src/util/transport.ts +26 -0
  100. package/vendor/libav/avbridge/libav-6.8.8.0-avbridge.wasm.mjs +1 -1
  101. package/vendor/libav/avbridge/libav-6.8.8.0-avbridge.wasm.wasm +0 -0
  102. package/dist/avi-6SJLWIWW.cjs.map +0 -1
  103. package/dist/avi-GCGM7OJI.js.map +0 -1
  104. package/dist/chunk-DMWARSEF.js.map +0 -1
  105. package/dist/chunk-HZLQNKFN.cjs.map +0 -1
  106. package/dist/chunk-ILKDNBSE.js.map +0 -1
  107. package/dist/chunk-J5MCMN3S.js +0 -27
  108. package/dist/chunk-J5MCMN3S.js.map +0 -1
  109. package/dist/chunk-L4NPOJ36.cjs.map +0 -1
  110. package/dist/chunk-NZU7W256.cjs +0 -29
  111. package/dist/chunk-NZU7W256.cjs.map +0 -1
  112. package/dist/chunk-UF2N5L63.cjs.map +0 -1
  113. package/dist/chunk-WD2ZNQA7.js.map +0 -1
  114. package/dist/libav-http-reader-FPYDBMYK.cjs +0 -16
  115. package/dist/libav-http-reader-NQJVY273.js +0 -3
  116. package/dist/source-CN43EI7Z.cjs +0 -28
  117. package/dist/source-FFZ7TW2B.js +0 -3
  118. package/dist/variant-routing-GOHB2RZN.cjs +0 -12
  119. package/dist/variant-routing-JOBWXYKD.js +0 -3
@@ -17,7 +17,7 @@ type ContainerKind = "mp4" | "mov" | "mkv" | "webm" | "avi" | "asf" | "flv" | "r
17
17
  /** Video codec families. Strings, not enums, so plugins can extend. */
18
18
  type VideoCodec = "h264" | "h265" | "vp8" | "vp9" | "av1" | "mpeg4" | "wmv3" | "vc1" | "rv10" | "rv20" | "rv30" | "rv40" | "mpeg2" | "mpeg1" | "theora" | (string & {});
19
19
  /** Audio codec families. */
20
- type AudioCodec = "aac" | "mp3" | "opus" | "vorbis" | "flac" | "pcm" | "ac3" | "eac3" | "wmav2" | "wmapro" | "alac" | "cook" | "ra_144" | "ra_288" | "sipr" | "atrac3" | (string & {});
20
+ type AudioCodec = "aac" | "mp3" | "opus" | "vorbis" | "flac" | "pcm" | "ac3" | "eac3" | "wmav2" | "wmapro" | "alac" | "cook" | "ra_144" | "ra_288" | "sipr" | "atrac3" | "dts" | "truehd" | (string & {});
21
21
  interface VideoTrackInfo {
22
22
  id: number;
23
23
  codec: VideoCodec;
@@ -156,7 +156,7 @@ interface Plugin {
156
156
  name: string;
157
157
  canHandle(context: MediaContext): boolean;
158
158
  /** Returns a session if it claims the context, otherwise throws. */
159
- execute(context: MediaContext, target: HTMLVideoElement): Promise<PlaybackSession>;
159
+ execute(context: MediaContext, target: HTMLVideoElement, transport?: TransportConfig): Promise<PlaybackSession>;
160
160
  }
161
161
  /** Player creation options. */
162
162
  interface CreatePlayerOptions {
@@ -196,6 +196,36 @@ interface CreatePlayerOptions {
196
196
  * strategy in the fallback chain on failure or stall.
197
197
  */
198
198
  autoEscalate?: boolean;
199
+ /**
200
+ * Behavior when the browser tab becomes hidden.
201
+ * - `"pause"` (default): auto-pause on hide, auto-resume on visible
202
+ * if the user had been playing. Matches YouTube, Netflix, and
203
+ * native media players. Prevents degraded playback from Chrome's
204
+ * background throttling of requestAnimationFrame and setTimeout.
205
+ * - `"continue"`: keep playing. Playback will degrade anyway due to
206
+ * browser throttling, but useful for consumers who want full
207
+ * control of visibility handling themselves.
208
+ */
209
+ backgroundBehavior?: "pause" | "continue";
210
+ /**
211
+ * Extra {@link RequestInit} merged into every HTTP request the player
212
+ * makes (probe Range requests, subtitle fetches, libav HTTP reader).
213
+ * Headers are merged, not overwritten — so you can add `Authorization`
214
+ * without losing the player's `Range` header.
215
+ */
216
+ requestInit?: RequestInit;
217
+ /**
218
+ * Custom fetch implementation. Defaults to `globalThis.fetch`. Useful
219
+ * for interceptors, logging, or environments without a global fetch.
220
+ */
221
+ fetchFn?: FetchFn;
222
+ }
223
+ /** Signature-compatible with `globalThis.fetch`. */
224
+ type FetchFn = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
225
+ /** Internal transport config bundle. Not part of the public API. */
226
+ interface TransportConfig {
227
+ requestInit?: RequestInit;
228
+ fetchFn?: FetchFn;
199
229
  }
200
230
  /** Events emitted by {@link UnifiedPlayer}. Strongly typed. */
201
231
  interface PlayerEventMap {
@@ -236,6 +266,24 @@ interface ConvertOptions {
236
266
  onProgress?: (info: ProgressInfo) => void;
237
267
  /** When true, reject on any uncertain codec/container combo. Default: `false` (best-effort). */
238
268
  strict?: boolean;
269
+ /**
270
+ * Write output progressively to a `WritableStream` instead of accumulating
271
+ * in memory. Use with the File System Access API (`showSaveFilePicker()`) to
272
+ * transcode files larger than available memory.
273
+ *
274
+ * When set, the returned `ConvertResult.blob` will be an empty Blob (the
275
+ * real data went to the stream). The caller is responsible for closing the
276
+ * stream after the returned promise resolves.
277
+ *
278
+ * @example
279
+ * ```ts
280
+ * const handle = await showSaveFilePicker({ suggestedName: "output.mp4" });
281
+ * const writable = await handle.createWritable();
282
+ * const result = await transcode(file, { outputStream: writable });
283
+ * await writable.close();
284
+ * ```
285
+ */
286
+ outputStream?: WritableStream;
239
287
  }
240
288
  /** Progress information passed to {@link ConvertOptions.onProgress}. */
241
289
  interface ProgressInfo {
@@ -325,8 +373,12 @@ declare class UnifiedPlayer {
325
373
  private lastProgressPosition;
326
374
  private errorListener;
327
375
  private endedListener;
376
+ private userIntent;
377
+ private autoPausedForVisibility;
378
+ private visibilityListener;
328
379
  private switchingPromise;
329
380
  private subtitleResources;
381
+ private readonly transport;
330
382
  /**
331
383
  * @internal Use {@link createPlayer} or {@link UnifiedPlayer.create} instead.
332
384
  */
@@ -354,6 +406,13 @@ declare class UnifiedPlayer {
354
406
  play(): Promise<void>;
355
407
  /** Pause playback. No-op if the player is not ready or already paused. */
356
408
  pause(): void;
409
+ /**
410
+ * Handle browser tab visibility changes. On hide: pause if the user
411
+ * had been playing. On show: resume if we were the one who paused.
412
+ * Skips when `backgroundBehavior: "continue"` is set (listener isn't
413
+ * installed in that case).
414
+ */
415
+ private onVisibilityChange;
357
416
  /** Seek to the given time in seconds. Throws if the player is not ready. */
358
417
  seek(time: number): Promise<void>;
359
418
  /** Switch the active audio track by track ID. Throws if the player is not ready. */
@@ -371,4 +430,4 @@ declare class UnifiedPlayer {
371
430
  }
372
431
  declare function createPlayer(options: CreatePlayerOptions): Promise<UnifiedPlayer>;
373
432
 
374
- export { type AudioCodec as A, type Classification as C, type DiagnosticsSnapshot as D, type HardwareAccelerationHint as H, type MediaContext as M, type OutputAudioCodec as O, type PlaybackSession as P, type StrategyClass as S, type TranscodeOptions as T, UnifiedPlayer as U, type VideoCodec as V, type MediaInput as a, type ConvertOptions as b, type ConvertResult as c, type AudioTrackInfo as d, type ContainerKind as e, type CreatePlayerOptions as f, type OutputFormat as g, type OutputVideoCodec as h, type PlayerEventMap as i, type PlayerEventName as j, type Plugin as k, type ProgressInfo as l, type StrategyName as m, type SubtitleTrackInfo as n, type TranscodeQuality as o, type VideoTrackInfo as p, createPlayer as q };
433
+ export { type AudioCodec as A, type Classification as C, type DiagnosticsSnapshot as D, type FetchFn as F, type HardwareAccelerationHint as H, type MediaContext as M, type OutputAudioCodec as O, type PlaybackSession as P, type StrategyClass as S, type TransportConfig as T, UnifiedPlayer as U, type VideoCodec as V, type MediaInput as a, type ConvertOptions as b, type ConvertResult as c, type TranscodeOptions as d, type AudioTrackInfo as e, type ContainerKind as f, type CreatePlayerOptions as g, type OutputFormat as h, type OutputVideoCodec as i, type PlayerEventMap as j, type PlayerEventName as k, type Plugin as l, type ProgressInfo as m, type StrategyName as n, type SubtitleTrackInfo as o, type TranscodeQuality as p, type VideoTrackInfo as q, createPlayer as r };
@@ -17,7 +17,7 @@ type ContainerKind = "mp4" | "mov" | "mkv" | "webm" | "avi" | "asf" | "flv" | "r
17
17
  /** Video codec families. Strings, not enums, so plugins can extend. */
18
18
  type VideoCodec = "h264" | "h265" | "vp8" | "vp9" | "av1" | "mpeg4" | "wmv3" | "vc1" | "rv10" | "rv20" | "rv30" | "rv40" | "mpeg2" | "mpeg1" | "theora" | (string & {});
19
19
  /** Audio codec families. */
20
- type AudioCodec = "aac" | "mp3" | "opus" | "vorbis" | "flac" | "pcm" | "ac3" | "eac3" | "wmav2" | "wmapro" | "alac" | "cook" | "ra_144" | "ra_288" | "sipr" | "atrac3" | (string & {});
20
+ type AudioCodec = "aac" | "mp3" | "opus" | "vorbis" | "flac" | "pcm" | "ac3" | "eac3" | "wmav2" | "wmapro" | "alac" | "cook" | "ra_144" | "ra_288" | "sipr" | "atrac3" | "dts" | "truehd" | (string & {});
21
21
  interface VideoTrackInfo {
22
22
  id: number;
23
23
  codec: VideoCodec;
@@ -156,7 +156,7 @@ interface Plugin {
156
156
  name: string;
157
157
  canHandle(context: MediaContext): boolean;
158
158
  /** Returns a session if it claims the context, otherwise throws. */
159
- execute(context: MediaContext, target: HTMLVideoElement): Promise<PlaybackSession>;
159
+ execute(context: MediaContext, target: HTMLVideoElement, transport?: TransportConfig): Promise<PlaybackSession>;
160
160
  }
161
161
  /** Player creation options. */
162
162
  interface CreatePlayerOptions {
@@ -196,6 +196,36 @@ interface CreatePlayerOptions {
196
196
  * strategy in the fallback chain on failure or stall.
197
197
  */
198
198
  autoEscalate?: boolean;
199
+ /**
200
+ * Behavior when the browser tab becomes hidden.
201
+ * - `"pause"` (default): auto-pause on hide, auto-resume on visible
202
+ * if the user had been playing. Matches YouTube, Netflix, and
203
+ * native media players. Prevents degraded playback from Chrome's
204
+ * background throttling of requestAnimationFrame and setTimeout.
205
+ * - `"continue"`: keep playing. Playback will degrade anyway due to
206
+ * browser throttling, but useful for consumers who want full
207
+ * control of visibility handling themselves.
208
+ */
209
+ backgroundBehavior?: "pause" | "continue";
210
+ /**
211
+ * Extra {@link RequestInit} merged into every HTTP request the player
212
+ * makes (probe Range requests, subtitle fetches, libav HTTP reader).
213
+ * Headers are merged, not overwritten — so you can add `Authorization`
214
+ * without losing the player's `Range` header.
215
+ */
216
+ requestInit?: RequestInit;
217
+ /**
218
+ * Custom fetch implementation. Defaults to `globalThis.fetch`. Useful
219
+ * for interceptors, logging, or environments without a global fetch.
220
+ */
221
+ fetchFn?: FetchFn;
222
+ }
223
+ /** Signature-compatible with `globalThis.fetch`. */
224
+ type FetchFn = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
225
+ /** Internal transport config bundle. Not part of the public API. */
226
+ interface TransportConfig {
227
+ requestInit?: RequestInit;
228
+ fetchFn?: FetchFn;
199
229
  }
200
230
  /** Events emitted by {@link UnifiedPlayer}. Strongly typed. */
201
231
  interface PlayerEventMap {
@@ -236,6 +266,24 @@ interface ConvertOptions {
236
266
  onProgress?: (info: ProgressInfo) => void;
237
267
  /** When true, reject on any uncertain codec/container combo. Default: `false` (best-effort). */
238
268
  strict?: boolean;
269
+ /**
270
+ * Write output progressively to a `WritableStream` instead of accumulating
271
+ * in memory. Use with the File System Access API (`showSaveFilePicker()`) to
272
+ * transcode files larger than available memory.
273
+ *
274
+ * When set, the returned `ConvertResult.blob` will be an empty Blob (the
275
+ * real data went to the stream). The caller is responsible for closing the
276
+ * stream after the returned promise resolves.
277
+ *
278
+ * @example
279
+ * ```ts
280
+ * const handle = await showSaveFilePicker({ suggestedName: "output.mp4" });
281
+ * const writable = await handle.createWritable();
282
+ * const result = await transcode(file, { outputStream: writable });
283
+ * await writable.close();
284
+ * ```
285
+ */
286
+ outputStream?: WritableStream;
239
287
  }
240
288
  /** Progress information passed to {@link ConvertOptions.onProgress}. */
241
289
  interface ProgressInfo {
@@ -325,8 +373,12 @@ declare class UnifiedPlayer {
325
373
  private lastProgressPosition;
326
374
  private errorListener;
327
375
  private endedListener;
376
+ private userIntent;
377
+ private autoPausedForVisibility;
378
+ private visibilityListener;
328
379
  private switchingPromise;
329
380
  private subtitleResources;
381
+ private readonly transport;
330
382
  /**
331
383
  * @internal Use {@link createPlayer} or {@link UnifiedPlayer.create} instead.
332
384
  */
@@ -354,6 +406,13 @@ declare class UnifiedPlayer {
354
406
  play(): Promise<void>;
355
407
  /** Pause playback. No-op if the player is not ready or already paused. */
356
408
  pause(): void;
409
+ /**
410
+ * Handle browser tab visibility changes. On hide: pause if the user
411
+ * had been playing. On show: resume if we were the one who paused.
412
+ * Skips when `backgroundBehavior: "continue"` is set (listener isn't
413
+ * installed in that case).
414
+ */
415
+ private onVisibilityChange;
357
416
  /** Seek to the given time in seconds. Throws if the player is not ready. */
358
417
  seek(time: number): Promise<void>;
359
418
  /** Switch the active audio track by track ID. Throws if the player is not ready. */
@@ -371,4 +430,4 @@ declare class UnifiedPlayer {
371
430
  }
372
431
  declare function createPlayer(options: CreatePlayerOptions): Promise<UnifiedPlayer>;
373
432
 
374
- export { type AudioCodec as A, type Classification as C, type DiagnosticsSnapshot as D, type HardwareAccelerationHint as H, type MediaContext as M, type OutputAudioCodec as O, type PlaybackSession as P, type StrategyClass as S, type TranscodeOptions as T, UnifiedPlayer as U, type VideoCodec as V, type MediaInput as a, type ConvertOptions as b, type ConvertResult as c, type AudioTrackInfo as d, type ContainerKind as e, type CreatePlayerOptions as f, type OutputFormat as g, type OutputVideoCodec as h, type PlayerEventMap as i, type PlayerEventName as j, type Plugin as k, type ProgressInfo as l, type StrategyName as m, type SubtitleTrackInfo as n, type TranscodeQuality as o, type VideoTrackInfo as p, createPlayer as q };
433
+ export { type AudioCodec as A, type Classification as C, type DiagnosticsSnapshot as D, type FetchFn as F, type HardwareAccelerationHint as H, type MediaContext as M, type OutputAudioCodec as O, type PlaybackSession as P, type StrategyClass as S, type TransportConfig as T, UnifiedPlayer as U, type VideoCodec as V, type MediaInput as a, type ConvertOptions as b, type ConvertResult as c, type TranscodeOptions as d, type AudioTrackInfo as e, type ContainerKind as f, type CreatePlayerOptions as g, type OutputFormat as h, type OutputVideoCodec as i, type PlayerEventMap as j, type PlayerEventName as k, type Plugin as l, type ProgressInfo as m, type StrategyName as n, type SubtitleTrackInfo as o, type TranscodeQuality as p, type VideoTrackInfo as q, createPlayer as r };