avbridge 2.2.1 → 2.5.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 (165) hide show
  1. package/CHANGELOG.md +153 -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-2IJ66NTD.cjs +212 -0
  14. package/dist/chunk-2IJ66NTD.cjs.map +1 -0
  15. package/dist/{chunk-ILKDNBSE.js → chunk-2XW2O3YI.cjs} +55 -10
  16. package/dist/chunk-2XW2O3YI.cjs.map +1 -0
  17. package/dist/chunk-5KVLE6YI.js +167 -0
  18. package/dist/chunk-5KVLE6YI.js.map +1 -0
  19. package/dist/chunk-5YAWWKA3.js +18 -0
  20. package/dist/chunk-5YAWWKA3.js.map +1 -0
  21. package/dist/chunk-CPJLFFCC.js +189 -0
  22. package/dist/chunk-CPJLFFCC.js.map +1 -0
  23. package/dist/chunk-CPZ7PXAM.cjs +240 -0
  24. package/dist/chunk-CPZ7PXAM.cjs.map +1 -0
  25. package/dist/{chunk-WD2ZNQA7.js → chunk-DCSOQH2N.js} +7 -4
  26. package/dist/chunk-DCSOQH2N.js.map +1 -0
  27. package/dist/{chunk-HZLQNKFN.cjs → chunk-E76AMWI4.js} +40 -15
  28. package/dist/chunk-E76AMWI4.js.map +1 -0
  29. package/dist/chunk-F3LQJKXK.cjs +20 -0
  30. package/dist/chunk-F3LQJKXK.cjs.map +1 -0
  31. package/dist/chunk-IAYKFGFG.js +200 -0
  32. package/dist/chunk-IAYKFGFG.js.map +1 -0
  33. package/dist/{chunk-DMWARSEF.js → chunk-KY2GPCT7.js} +788 -697
  34. package/dist/chunk-KY2GPCT7.js.map +1 -0
  35. package/dist/chunk-LUFA47FP.js +19 -0
  36. package/dist/chunk-LUFA47FP.js.map +1 -0
  37. package/dist/chunk-NNVOHKXJ.cjs +204 -0
  38. package/dist/chunk-NNVOHKXJ.cjs.map +1 -0
  39. package/dist/chunk-Q2VUO52Z.cjs +374 -0
  40. package/dist/chunk-Q2VUO52Z.cjs.map +1 -0
  41. package/dist/chunk-QDJLQR53.cjs +22 -0
  42. package/dist/chunk-QDJLQR53.cjs.map +1 -0
  43. package/dist/chunk-S4WAZC2T.cjs +173 -0
  44. package/dist/chunk-S4WAZC2T.cjs.map +1 -0
  45. package/dist/chunk-SMH6IOP2.js +368 -0
  46. package/dist/chunk-SMH6IOP2.js.map +1 -0
  47. package/dist/chunk-SR3MPV4D.js +237 -0
  48. package/dist/chunk-SR3MPV4D.js.map +1 -0
  49. package/dist/{chunk-UF2N5L63.cjs → chunk-TBW26OPP.cjs} +800 -710
  50. package/dist/chunk-TBW26OPP.cjs.map +1 -0
  51. package/dist/chunk-X2K3GIWE.js +235 -0
  52. package/dist/chunk-X2K3GIWE.js.map +1 -0
  53. package/dist/{chunk-L4NPOJ36.cjs → chunk-Z33SBWL5.cjs} +7 -4
  54. package/dist/chunk-Z33SBWL5.cjs.map +1 -0
  55. package/dist/chunk-ZCUXHW55.cjs +242 -0
  56. package/dist/chunk-ZCUXHW55.cjs.map +1 -0
  57. package/dist/element-browser.js +1282 -503
  58. package/dist/element-browser.js.map +1 -1
  59. package/dist/element.cjs +59 -5
  60. package/dist/element.cjs.map +1 -1
  61. package/dist/element.d.cts +39 -1
  62. package/dist/element.d.ts +39 -1
  63. package/dist/element.js +58 -4
  64. package/dist/element.js.map +1 -1
  65. package/dist/index.cjs +605 -327
  66. package/dist/index.cjs.map +1 -1
  67. package/dist/index.d.cts +48 -4
  68. package/dist/index.d.ts +48 -4
  69. package/dist/index.js +528 -319
  70. package/dist/index.js.map +1 -1
  71. package/dist/libav-demux-H2GS46GH.cjs +27 -0
  72. package/dist/{libav-http-reader-NQJVY273.js.map → libav-demux-H2GS46GH.cjs.map} +1 -1
  73. package/dist/libav-demux-OWZ4T2YW.js +6 -0
  74. package/dist/{libav-http-reader-FPYDBMYK.cjs.map → libav-demux-OWZ4T2YW.js.map} +1 -1
  75. package/dist/libav-http-reader-AZLE7YFS.cjs +16 -0
  76. package/dist/libav-http-reader-AZLE7YFS.cjs.map +1 -0
  77. package/dist/libav-http-reader-WXG3Z7AI.js +3 -0
  78. package/dist/libav-http-reader-WXG3Z7AI.js.map +1 -0
  79. package/dist/{libav-import-GST2AMPL.cjs → libav-import-2ZVKV2E7.cjs} +2 -2
  80. package/dist/{libav-import-GST2AMPL.cjs.map → libav-import-2ZVKV2E7.cjs.map} +1 -1
  81. package/dist/{libav-import-2JURFHEW.js → libav-import-6MGLCXVQ.js} +2 -2
  82. package/dist/{libav-import-2JURFHEW.js.map → libav-import-6MGLCXVQ.js.map} +1 -1
  83. package/dist/{player-U2NPmFvA.d.cts → player-B6WB74RD.d.cts} +62 -3
  84. package/dist/{player-U2NPmFvA.d.ts → player-B6WB74RD.d.ts} +62 -3
  85. package/dist/player.cjs +5631 -0
  86. package/dist/player.cjs.map +1 -0
  87. package/dist/player.d.cts +699 -0
  88. package/dist/player.d.ts +699 -0
  89. package/dist/player.js +5629 -0
  90. package/dist/player.js.map +1 -0
  91. package/dist/remux-OBSMIENG.cjs +35 -0
  92. package/dist/remux-OBSMIENG.cjs.map +1 -0
  93. package/dist/remux-WBYIZBBX.js +10 -0
  94. package/dist/remux-WBYIZBBX.js.map +1 -0
  95. package/dist/source-4TZ6KMNV.js +4 -0
  96. package/dist/{source-FFZ7TW2B.js.map → source-4TZ6KMNV.js.map} +1 -1
  97. package/dist/source-7YLO6E7X.cjs +29 -0
  98. package/dist/{source-CN43EI7Z.cjs.map → source-7YLO6E7X.cjs.map} +1 -1
  99. package/dist/source-MTX5ELUZ.js +4 -0
  100. package/dist/source-MTX5ELUZ.js.map +1 -0
  101. package/dist/source-VFLXLOCN.cjs +29 -0
  102. package/dist/source-VFLXLOCN.cjs.map +1 -0
  103. package/dist/subtitles-4T74JRGT.js +4 -0
  104. package/dist/subtitles-4T74JRGT.js.map +1 -0
  105. package/dist/subtitles-QUH4LPI4.cjs +29 -0
  106. package/dist/subtitles-QUH4LPI4.cjs.map +1 -0
  107. package/dist/variant-routing-434STYAB.js +3 -0
  108. package/dist/{variant-routing-JOBWXYKD.js.map → variant-routing-434STYAB.js.map} +1 -1
  109. package/dist/variant-routing-HONNAA6R.cjs +12 -0
  110. package/dist/{variant-routing-GOHB2RZN.cjs.map → variant-routing-HONNAA6R.cjs.map} +1 -1
  111. package/package.json +9 -1
  112. package/src/classify/rules.ts +27 -5
  113. package/src/convert/remux.ts +9 -35
  114. package/src/convert/transcode-libav.ts +691 -0
  115. package/src/convert/transcode.ts +53 -12
  116. package/src/element/avbridge-player.ts +861 -0
  117. package/src/element/avbridge-video.ts +54 -0
  118. package/src/element/player-icons.ts +25 -0
  119. package/src/element/player-styles.ts +472 -0
  120. package/src/errors.ts +53 -0
  121. package/src/index.ts +23 -0
  122. package/src/player-element.ts +18 -0
  123. package/src/player.ts +118 -27
  124. package/src/plugins/builtin.ts +2 -2
  125. package/src/probe/avi.ts +4 -0
  126. package/src/probe/index.ts +40 -10
  127. package/src/strategies/fallback/audio-output.ts +31 -0
  128. package/src/strategies/fallback/decoder.ts +179 -175
  129. package/src/strategies/fallback/index.ts +48 -6
  130. package/src/strategies/fallback/libav-import.ts +9 -1
  131. package/src/strategies/fallback/variant-routing.ts +7 -13
  132. package/src/strategies/fallback/video-renderer.ts +231 -32
  133. package/src/strategies/hybrid/decoder.ts +219 -200
  134. package/src/strategies/hybrid/index.ts +48 -7
  135. package/src/strategies/native.ts +6 -3
  136. package/src/strategies/remux/index.ts +14 -2
  137. package/src/strategies/remux/mse.ts +12 -2
  138. package/src/strategies/remux/pipeline.ts +72 -12
  139. package/src/subtitles/index.ts +7 -3
  140. package/src/subtitles/render.ts +8 -0
  141. package/src/types.ts +53 -1
  142. package/src/util/libav-demux.ts +405 -0
  143. package/src/util/libav-http-reader.ts +5 -1
  144. package/src/util/source.ts +28 -8
  145. package/src/util/transport.ts +26 -0
  146. package/vendor/libav/avbridge/libav-6.8.8.0-avbridge.wasm.mjs +1 -1
  147. package/vendor/libav/avbridge/libav-6.8.8.0-avbridge.wasm.wasm +0 -0
  148. package/dist/avi-6SJLWIWW.cjs.map +0 -1
  149. package/dist/avi-GCGM7OJI.js.map +0 -1
  150. package/dist/chunk-DMWARSEF.js.map +0 -1
  151. package/dist/chunk-HZLQNKFN.cjs.map +0 -1
  152. package/dist/chunk-ILKDNBSE.js.map +0 -1
  153. package/dist/chunk-J5MCMN3S.js +0 -27
  154. package/dist/chunk-J5MCMN3S.js.map +0 -1
  155. package/dist/chunk-L4NPOJ36.cjs.map +0 -1
  156. package/dist/chunk-NZU7W256.cjs +0 -29
  157. package/dist/chunk-NZU7W256.cjs.map +0 -1
  158. package/dist/chunk-UF2N5L63.cjs.map +0 -1
  159. package/dist/chunk-WD2ZNQA7.js.map +0 -1
  160. package/dist/libav-http-reader-FPYDBMYK.cjs +0 -16
  161. package/dist/libav-http-reader-NQJVY273.js +0 -3
  162. package/dist/source-CN43EI7Z.cjs +0 -28
  163. package/dist/source-FFZ7TW2B.js +0 -3
  164. package/dist/variant-routing-GOHB2RZN.cjs +0 -12
  165. package/dist/variant-routing-JOBWXYKD.js +0 -3
@@ -102,9 +102,13 @@ export async function prepareLibavInput(
102
102
  libav: LibavLikeWithBlob,
103
103
  filename: string,
104
104
  source: import("./source.js").NormalizedSource,
105
+ transport?: import("../types.js").TransportConfig,
105
106
  ): Promise<LibavInputHandle> {
106
107
  if (source.kind === "url") {
107
- const handle = await attachLibavHttpReader(libav, filename, source.url);
108
+ const handle = await attachLibavHttpReader(libav, filename, source.url, {
109
+ requestInit: transport?.requestInit,
110
+ fetchFn: transport?.fetchFn,
111
+ });
108
112
  return {
109
113
  filename,
110
114
  transport: "http-range",
@@ -1,4 +1,6 @@
1
- import type { ContainerKind, MediaInput } from "../types.js";
1
+ import type { ContainerKind, MediaInput, TransportConfig } from "../types.js";
2
+ import { mergeFetchInit, fetchWith } from "./transport.js";
3
+ import { AvbridgeError, ERR_PROBE_FETCH_FAILED } from "../errors.js";
2
4
 
3
5
  /**
4
6
  * Bytes needed by the sniffer to identify every container we recognize.
@@ -59,7 +61,10 @@ export function isInMemorySource(source: NormalizedSource): source is Extract<No
59
61
  *
60
62
  * For non-URL inputs, the bytes are already in memory and we just wrap them.
61
63
  */
62
- export async function normalizeSource(source: MediaInput): Promise<NormalizedSource> {
64
+ export async function normalizeSource(
65
+ source: MediaInput,
66
+ transport?: TransportConfig,
67
+ ): Promise<NormalizedSource> {
63
68
  if (source instanceof File) {
64
69
  return {
65
70
  kind: "blob",
@@ -82,7 +87,7 @@ export async function normalizeSource(source: MediaInput): Promise<NormalizedSou
82
87
  }
83
88
  if (typeof source === "string" || source instanceof URL) {
84
89
  const url = source instanceof URL ? source.toString() : source;
85
- return await fetchUrlForSniff(url, source);
90
+ return await fetchUrlForSniff(url, source, transport);
86
91
  }
87
92
  throw new TypeError("unsupported source type");
88
93
  }
@@ -93,20 +98,35 @@ export async function normalizeSource(source: MediaInput): Promise<NormalizedSou
93
98
  * we only read the first 32 KB and abort the rest of the response so we
94
99
  * don't accidentally buffer a large file.
95
100
  */
96
- async function fetchUrlForSniff(url: string, originalSource: MediaInput): Promise<NormalizedSource> {
101
+ async function fetchUrlForSniff(
102
+ url: string,
103
+ originalSource: MediaInput,
104
+ transport?: TransportConfig,
105
+ ): Promise<NormalizedSource> {
97
106
  const name = url.split("/").pop()?.split("?")[0] ?? undefined;
107
+ const doFetch = fetchWith(transport);
98
108
 
99
109
  // First attempt: Range request for the sniff window.
100
110
  let res: Response;
101
111
  try {
102
- res = await fetch(url, {
112
+ res = await doFetch(url, mergeFetchInit(transport?.requestInit, {
103
113
  headers: { Range: `bytes=0-${URL_SNIFF_RANGE_BYTES - 1}` },
104
- });
114
+ })!);
105
115
  } catch (err) {
106
- throw new Error(`failed to fetch source ${url}: ${(err as Error).message}`);
116
+ throw new AvbridgeError(
117
+ ERR_PROBE_FETCH_FAILED,
118
+ `Failed to fetch source ${url}: ${(err as Error).message}`,
119
+ "Check that the URL is reachable and CORS is configured. If the source requires authentication, pass requestInit with credentials/headers.",
120
+ );
107
121
  }
108
122
  if (!res.ok && res.status !== 206) {
109
- throw new Error(`failed to fetch source ${url}: ${res.status} ${res.statusText}`);
123
+ throw new AvbridgeError(
124
+ ERR_PROBE_FETCH_FAILED,
125
+ `Failed to fetch source ${url}: ${res.status} ${res.statusText}`,
126
+ res.status === 403 || res.status === 401
127
+ ? "The server rejected the request. Pass requestInit with the required Authorization header or credentials."
128
+ : "Check that the URL is correct and the server is reachable.",
129
+ );
110
130
  }
111
131
 
112
132
  // Determine the total file size from Content-Range (preferred) or Content-Length.
@@ -0,0 +1,26 @@
1
+ import type { FetchFn, TransportConfig } from "../types.js";
2
+
3
+ /**
4
+ * Merge two RequestInit objects. Headers are merged (not overwritten) so
5
+ * the caller's auth headers coexist with the player's Range headers.
6
+ * Other fields (credentials, mode, signal, etc.) in `extra` override `base`.
7
+ */
8
+ export function mergeFetchInit(
9
+ base: RequestInit | undefined,
10
+ extra: RequestInit | undefined,
11
+ ): RequestInit | undefined {
12
+ if (!base && !extra) return undefined;
13
+ return {
14
+ ...base,
15
+ ...extra,
16
+ headers: {
17
+ ...(base?.headers as Record<string, string> | undefined ?? {}),
18
+ ...(extra?.headers as Record<string, string> | undefined ?? {}),
19
+ },
20
+ };
21
+ }
22
+
23
+ /** Return the fetch function from a TransportConfig, falling back to globalThis.fetch. */
24
+ export function fetchWith(transport?: TransportConfig): FetchFn {
25
+ return transport?.fetchFn ?? globalThis.fetch;
26
+ }