@kenzuya/mediabunny 1.26.0 → 1.28.6

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 (238) hide show
  1. package/README.md +1 -1
  2. package/dist/bundles/{mediabunny.mjs → mediabunny.js} +21963 -21390
  3. package/dist/bundles/mediabunny.min.js +490 -0
  4. package/dist/modules/shared/mp3-misc.d.ts.map +1 -1
  5. package/dist/modules/src/adts/adts-demuxer.d.ts +6 -6
  6. package/dist/modules/src/adts/adts-demuxer.d.ts.map +1 -1
  7. package/dist/modules/src/adts/adts-muxer.d.ts +4 -4
  8. package/dist/modules/src/adts/adts-muxer.d.ts.map +1 -1
  9. package/dist/modules/src/adts/adts-reader.d.ts +1 -1
  10. package/dist/modules/src/adts/adts-reader.d.ts.map +1 -1
  11. package/dist/modules/src/avi/avi-demuxer.d.ts +44 -0
  12. package/dist/modules/src/avi/avi-demuxer.d.ts.map +1 -0
  13. package/dist/modules/src/avi/avi-misc.d.ts +88 -0
  14. package/dist/modules/src/avi/avi-misc.d.ts.map +1 -0
  15. package/dist/modules/src/avi/avi-muxer.d.ts +45 -0
  16. package/dist/modules/src/avi/avi-muxer.d.ts.map +1 -0
  17. package/dist/modules/src/avi/riff-writer.d.ts +26 -0
  18. package/dist/modules/src/avi/riff-writer.d.ts.map +1 -0
  19. package/dist/modules/src/codec-data.d.ts +8 -3
  20. package/dist/modules/src/codec-data.d.ts.map +1 -1
  21. package/dist/modules/src/codec.d.ts +10 -10
  22. package/dist/modules/src/codec.d.ts.map +1 -1
  23. package/dist/modules/src/conversion.d.ts +33 -16
  24. package/dist/modules/src/conversion.d.ts.map +1 -1
  25. package/dist/modules/src/custom-coder.d.ts +8 -8
  26. package/dist/modules/src/custom-coder.d.ts.map +1 -1
  27. package/dist/modules/src/demuxer.d.ts +3 -3
  28. package/dist/modules/src/demuxer.d.ts.map +1 -1
  29. package/dist/modules/src/encode.d.ts +8 -8
  30. package/dist/modules/src/encode.d.ts.map +1 -1
  31. package/dist/modules/src/flac/flac-demuxer.d.ts +7 -7
  32. package/dist/modules/src/flac/flac-demuxer.d.ts.map +1 -1
  33. package/dist/modules/src/flac/flac-misc.d.ts +3 -3
  34. package/dist/modules/src/flac/flac-misc.d.ts.map +1 -1
  35. package/dist/modules/src/flac/flac-muxer.d.ts +5 -5
  36. package/dist/modules/src/flac/flac-muxer.d.ts.map +1 -1
  37. package/dist/modules/src/id3.d.ts +3 -3
  38. package/dist/modules/src/id3.d.ts.map +1 -1
  39. package/dist/modules/src/index.d.ts +20 -20
  40. package/dist/modules/src/index.d.ts.map +1 -1
  41. package/dist/modules/src/input-format.d.ts +22 -0
  42. package/dist/modules/src/input-format.d.ts.map +1 -1
  43. package/dist/modules/src/input-track.d.ts +8 -8
  44. package/dist/modules/src/input-track.d.ts.map +1 -1
  45. package/dist/modules/src/input.d.ts +12 -12
  46. package/dist/modules/src/isobmff/isobmff-boxes.d.ts +2 -2
  47. package/dist/modules/src/isobmff/isobmff-boxes.d.ts.map +1 -1
  48. package/dist/modules/src/isobmff/isobmff-demuxer.d.ts +12 -12
  49. package/dist/modules/src/isobmff/isobmff-demuxer.d.ts.map +1 -1
  50. package/dist/modules/src/isobmff/isobmff-misc.d.ts.map +1 -1
  51. package/dist/modules/src/isobmff/isobmff-muxer.d.ts +11 -11
  52. package/dist/modules/src/isobmff/isobmff-muxer.d.ts.map +1 -1
  53. package/dist/modules/src/isobmff/isobmff-reader.d.ts +2 -2
  54. package/dist/modules/src/isobmff/isobmff-reader.d.ts.map +1 -1
  55. package/dist/modules/src/matroska/ebml.d.ts +3 -3
  56. package/dist/modules/src/matroska/ebml.d.ts.map +1 -1
  57. package/dist/modules/src/matroska/matroska-demuxer.d.ts +13 -13
  58. package/dist/modules/src/matroska/matroska-demuxer.d.ts.map +1 -1
  59. package/dist/modules/src/matroska/matroska-input.d.ts +33 -0
  60. package/dist/modules/src/matroska/matroska-input.d.ts.map +1 -0
  61. package/dist/modules/src/matroska/matroska-misc.d.ts.map +1 -1
  62. package/dist/modules/src/matroska/matroska-muxer.d.ts +5 -5
  63. package/dist/modules/src/matroska/matroska-muxer.d.ts.map +1 -1
  64. package/dist/modules/src/media-sink.d.ts +5 -5
  65. package/dist/modules/src/media-sink.d.ts.map +1 -1
  66. package/dist/modules/src/media-source.d.ts +22 -4
  67. package/dist/modules/src/media-source.d.ts.map +1 -1
  68. package/dist/modules/src/metadata.d.ts +2 -2
  69. package/dist/modules/src/metadata.d.ts.map +1 -1
  70. package/dist/modules/src/misc.d.ts +5 -4
  71. package/dist/modules/src/misc.d.ts.map +1 -1
  72. package/dist/modules/src/mp3/mp3-demuxer.d.ts +7 -7
  73. package/dist/modules/src/mp3/mp3-demuxer.d.ts.map +1 -1
  74. package/dist/modules/src/mp3/mp3-muxer.d.ts +4 -4
  75. package/dist/modules/src/mp3/mp3-muxer.d.ts.map +1 -1
  76. package/dist/modules/src/mp3/mp3-reader.d.ts +2 -2
  77. package/dist/modules/src/mp3/mp3-reader.d.ts.map +1 -1
  78. package/dist/modules/src/mp3/mp3-writer.d.ts +1 -1
  79. package/dist/modules/src/mp3/mp3-writer.d.ts.map +1 -1
  80. package/dist/modules/src/muxer.d.ts +4 -4
  81. package/dist/modules/src/muxer.d.ts.map +1 -1
  82. package/dist/modules/src/ogg/ogg-demuxer.d.ts +7 -7
  83. package/dist/modules/src/ogg/ogg-demuxer.d.ts.map +1 -1
  84. package/dist/modules/src/ogg/ogg-misc.d.ts +1 -1
  85. package/dist/modules/src/ogg/ogg-misc.d.ts.map +1 -1
  86. package/dist/modules/src/ogg/ogg-muxer.d.ts +5 -5
  87. package/dist/modules/src/ogg/ogg-muxer.d.ts.map +1 -1
  88. package/dist/modules/src/ogg/ogg-reader.d.ts +1 -1
  89. package/dist/modules/src/ogg/ogg-reader.d.ts.map +1 -1
  90. package/dist/modules/src/output-format.d.ts +51 -6
  91. package/dist/modules/src/output-format.d.ts.map +1 -1
  92. package/dist/modules/src/output.d.ts +13 -13
  93. package/dist/modules/src/output.d.ts.map +1 -1
  94. package/dist/modules/src/packet.d.ts +1 -1
  95. package/dist/modules/src/packet.d.ts.map +1 -1
  96. package/dist/modules/src/pcm.d.ts.map +1 -1
  97. package/dist/modules/src/reader.d.ts +2 -2
  98. package/dist/modules/src/reader.d.ts.map +1 -1
  99. package/dist/modules/src/sample.d.ts +57 -15
  100. package/dist/modules/src/sample.d.ts.map +1 -1
  101. package/dist/modules/src/source.d.ts +3 -3
  102. package/dist/modules/src/source.d.ts.map +1 -1
  103. package/dist/modules/src/subtitles.d.ts +1 -1
  104. package/dist/modules/src/subtitles.d.ts.map +1 -1
  105. package/dist/modules/src/target.d.ts +2 -2
  106. package/dist/modules/src/target.d.ts.map +1 -1
  107. package/dist/modules/src/tsconfig.tsbuildinfo +1 -1
  108. package/dist/modules/src/wave/riff-writer.d.ts +1 -1
  109. package/dist/modules/src/wave/riff-writer.d.ts.map +1 -1
  110. package/dist/modules/src/wave/wave-demuxer.d.ts +6 -6
  111. package/dist/modules/src/wave/wave-demuxer.d.ts.map +1 -1
  112. package/dist/modules/src/wave/wave-muxer.d.ts +4 -4
  113. package/dist/modules/src/wave/wave-muxer.d.ts.map +1 -1
  114. package/dist/modules/src/writer.d.ts +1 -1
  115. package/dist/modules/src/writer.d.ts.map +1 -1
  116. package/dist/packages/eac3/eac3.wasm +0 -0
  117. package/dist/packages/eac3/mediabunny-eac3.js +1058 -0
  118. package/dist/packages/eac3/mediabunny-eac3.min.js +44 -0
  119. package/dist/packages/mp3-encoder/mediabunny-mp3-encoder.js +694 -0
  120. package/dist/packages/mp3-encoder/mediabunny-mp3-encoder.min.js +58 -0
  121. package/dist/packages/mpeg4/mediabunny-mpeg4.js +1198 -0
  122. package/dist/packages/mpeg4/mediabunny-mpeg4.min.js +44 -0
  123. package/dist/packages/mpeg4/xvid.wasm +0 -0
  124. package/package.json +18 -57
  125. package/dist/bundles/mediabunny.cjs +0 -26140
  126. package/dist/bundles/mediabunny.min.cjs +0 -147
  127. package/dist/bundles/mediabunny.min.mjs +0 -146
  128. package/dist/mediabunny.d.ts +0 -3319
  129. package/dist/modules/shared/mp3-misc.js +0 -147
  130. package/dist/modules/src/adts/adts-demuxer.js +0 -239
  131. package/dist/modules/src/adts/adts-muxer.js +0 -80
  132. package/dist/modules/src/adts/adts-reader.js +0 -63
  133. package/dist/modules/src/codec-data.js +0 -1730
  134. package/dist/modules/src/codec.js +0 -869
  135. package/dist/modules/src/conversion.js +0 -1459
  136. package/dist/modules/src/custom-coder.js +0 -117
  137. package/dist/modules/src/demuxer.js +0 -12
  138. package/dist/modules/src/encode.js +0 -442
  139. package/dist/modules/src/flac/flac-demuxer.js +0 -504
  140. package/dist/modules/src/flac/flac-misc.js +0 -135
  141. package/dist/modules/src/flac/flac-muxer.js +0 -222
  142. package/dist/modules/src/id3.js +0 -848
  143. package/dist/modules/src/index.js +0 -28
  144. package/dist/modules/src/input-format.js +0 -480
  145. package/dist/modules/src/input-track.js +0 -372
  146. package/dist/modules/src/input.js +0 -188
  147. package/dist/modules/src/isobmff/isobmff-boxes.js +0 -1480
  148. package/dist/modules/src/isobmff/isobmff-demuxer.js +0 -2618
  149. package/dist/modules/src/isobmff/isobmff-misc.js +0 -20
  150. package/dist/modules/src/isobmff/isobmff-muxer.js +0 -966
  151. package/dist/modules/src/isobmff/isobmff-reader.js +0 -72
  152. package/dist/modules/src/matroska/ebml.js +0 -653
  153. package/dist/modules/src/matroska/matroska-demuxer.js +0 -2133
  154. package/dist/modules/src/matroska/matroska-misc.js +0 -20
  155. package/dist/modules/src/matroska/matroska-muxer.js +0 -1017
  156. package/dist/modules/src/media-sink.js +0 -1736
  157. package/dist/modules/src/media-source.js +0 -1825
  158. package/dist/modules/src/metadata.js +0 -193
  159. package/dist/modules/src/misc.js +0 -623
  160. package/dist/modules/src/mp3/mp3-demuxer.js +0 -285
  161. package/dist/modules/src/mp3/mp3-muxer.js +0 -123
  162. package/dist/modules/src/mp3/mp3-reader.js +0 -26
  163. package/dist/modules/src/mp3/mp3-writer.js +0 -78
  164. package/dist/modules/src/muxer.js +0 -50
  165. package/dist/modules/src/node.d.ts +0 -9
  166. package/dist/modules/src/node.d.ts.map +0 -1
  167. package/dist/modules/src/node.js +0 -9
  168. package/dist/modules/src/ogg/ogg-demuxer.js +0 -763
  169. package/dist/modules/src/ogg/ogg-misc.js +0 -78
  170. package/dist/modules/src/ogg/ogg-muxer.js +0 -353
  171. package/dist/modules/src/ogg/ogg-reader.js +0 -65
  172. package/dist/modules/src/output-format.js +0 -527
  173. package/dist/modules/src/output.js +0 -300
  174. package/dist/modules/src/packet.js +0 -182
  175. package/dist/modules/src/pcm.js +0 -85
  176. package/dist/modules/src/reader.js +0 -236
  177. package/dist/modules/src/sample.js +0 -1056
  178. package/dist/modules/src/source.js +0 -1182
  179. package/dist/modules/src/subtitles.js +0 -575
  180. package/dist/modules/src/target.js +0 -140
  181. package/dist/modules/src/wave/riff-writer.js +0 -30
  182. package/dist/modules/src/wave/wave-demuxer.js +0 -447
  183. package/dist/modules/src/wave/wave-muxer.js +0 -318
  184. package/dist/modules/src/writer.js +0 -370
  185. package/src/adts/adts-demuxer.ts +0 -331
  186. package/src/adts/adts-muxer.ts +0 -111
  187. package/src/adts/adts-reader.ts +0 -85
  188. package/src/codec-data.ts +0 -2078
  189. package/src/codec.ts +0 -1092
  190. package/src/conversion.ts +0 -2112
  191. package/src/custom-coder.ts +0 -197
  192. package/src/demuxer.ts +0 -24
  193. package/src/encode.ts +0 -739
  194. package/src/flac/flac-demuxer.ts +0 -730
  195. package/src/flac/flac-misc.ts +0 -164
  196. package/src/flac/flac-muxer.ts +0 -320
  197. package/src/id3.ts +0 -925
  198. package/src/index.ts +0 -221
  199. package/src/input-format.ts +0 -541
  200. package/src/input-track.ts +0 -529
  201. package/src/input.ts +0 -235
  202. package/src/isobmff/isobmff-boxes.ts +0 -1719
  203. package/src/isobmff/isobmff-demuxer.ts +0 -3190
  204. package/src/isobmff/isobmff-misc.ts +0 -29
  205. package/src/isobmff/isobmff-muxer.ts +0 -1348
  206. package/src/isobmff/isobmff-reader.ts +0 -91
  207. package/src/matroska/ebml.ts +0 -730
  208. package/src/matroska/matroska-demuxer.ts +0 -2481
  209. package/src/matroska/matroska-misc.ts +0 -29
  210. package/src/matroska/matroska-muxer.ts +0 -1276
  211. package/src/media-sink.ts +0 -2179
  212. package/src/media-source.ts +0 -2243
  213. package/src/metadata.ts +0 -320
  214. package/src/misc.ts +0 -798
  215. package/src/mp3/mp3-demuxer.ts +0 -383
  216. package/src/mp3/mp3-muxer.ts +0 -166
  217. package/src/mp3/mp3-reader.ts +0 -34
  218. package/src/mp3/mp3-writer.ts +0 -120
  219. package/src/muxer.ts +0 -88
  220. package/src/node.ts +0 -11
  221. package/src/ogg/ogg-demuxer.ts +0 -1053
  222. package/src/ogg/ogg-misc.ts +0 -116
  223. package/src/ogg/ogg-muxer.ts +0 -497
  224. package/src/ogg/ogg-reader.ts +0 -93
  225. package/src/output-format.ts +0 -945
  226. package/src/output.ts +0 -488
  227. package/src/packet.ts +0 -263
  228. package/src/pcm.ts +0 -112
  229. package/src/reader.ts +0 -323
  230. package/src/sample.ts +0 -1461
  231. package/src/source.ts +0 -1688
  232. package/src/subtitles.ts +0 -711
  233. package/src/target.ts +0 -204
  234. package/src/tsconfig.json +0 -16
  235. package/src/wave/riff-writer.ts +0 -36
  236. package/src/wave/wave-demuxer.ts +0 -529
  237. package/src/wave/wave-muxer.ts +0 -371
  238. package/src/writer.ts +0 -490
@@ -1,730 +0,0 @@
1
- /*!
2
- * Copyright (c) 2025-present, Vanilagy and contributors
3
- *
4
- * This Source Code Form is subject to the terms of the Mozilla Public
5
- * License, v. 2.0. If a copy of the MPL was not distributed with this
6
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
- */
8
-
9
- import { MediaCodec } from '../codec';
10
- import { assertNever, textDecoder, textEncoder } from '../misc';
11
- import { FileSlice, readBytes, Reader, readF32Be, readF64Be, readU8 } from '../reader';
12
- import { Writer } from '../writer';
13
-
14
- export interface EBMLElement {
15
- id: number;
16
- size?: number;
17
- data:
18
- | number
19
- | bigint
20
- | string
21
- | Uint8Array
22
- | EBMLFloat32
23
- | EBMLFloat64
24
- | EBMLSignedInt
25
- | EBMLUnicodeString
26
- | (EBML | null)[];
27
- }
28
-
29
- export type EBML = EBMLElement | Uint8Array | (EBML | null)[];
30
-
31
- /** Wrapper around a number to be able to differentiate it in the writer. */
32
- export class EBMLFloat32 {
33
- value: number;
34
-
35
- constructor(value: number) {
36
- this.value = value;
37
- }
38
- }
39
-
40
- /** Wrapper around a number to be able to differentiate it in the writer. */
41
- export class EBMLFloat64 {
42
- value: number;
43
-
44
- constructor(value: number) {
45
- this.value = value;
46
- }
47
- }
48
-
49
- /** Wrapper around a number to be able to differentiate it in the writer. */
50
- export class EBMLSignedInt {
51
- value: number;
52
-
53
- constructor(value: number) {
54
- this.value = value;
55
- }
56
- }
57
-
58
- export class EBMLUnicodeString {
59
- constructor(public value: string) {}
60
- }
61
-
62
- /** Defines some of the EBML IDs used by Matroska files. */
63
- export enum EBMLId {
64
- EBML = 0x1a45dfa3,
65
- EBMLVersion = 0x4286,
66
- EBMLReadVersion = 0x42f7,
67
- EBMLMaxIDLength = 0x42f2,
68
- EBMLMaxSizeLength = 0x42f3,
69
- DocType = 0x4282,
70
- DocTypeVersion = 0x4287,
71
- DocTypeReadVersion = 0x4285,
72
- Void = 0xec,
73
- Segment = 0x18538067,
74
- SeekHead = 0x114d9b74,
75
- Seek = 0x4dbb,
76
- SeekID = 0x53ab,
77
- SeekPosition = 0x53ac,
78
- Duration = 0x4489,
79
- Info = 0x1549a966,
80
- TimestampScale = 0x2ad7b1,
81
- MuxingApp = 0x4d80,
82
- WritingApp = 0x5741,
83
- Tracks = 0x1654ae6b,
84
- TrackEntry = 0xae,
85
- TrackNumber = 0xd7,
86
- TrackUID = 0x73c5,
87
- TrackType = 0x83,
88
- FlagEnabled = 0xb9,
89
- FlagDefault = 0x88,
90
- FlagForced = 0x55aa,
91
- FlagOriginal = 0x55ae,
92
- FlagHearingImpaired = 0x55ab,
93
- FlagVisualImpaired = 0x55ac,
94
- FlagCommentary = 0x55af,
95
- FlagLacing = 0x9c,
96
- Name = 0x536e,
97
- Language = 0x22b59c,
98
- LanguageBCP47 = 0x22b59d,
99
- CodecID = 0x86,
100
- CodecPrivate = 0x63a2,
101
- CodecDelay = 0x56aa,
102
- SeekPreRoll = 0x56bb,
103
- DefaultDuration = 0x23e383,
104
- Video = 0xe0,
105
- PixelWidth = 0xb0,
106
- PixelHeight = 0xba,
107
- AlphaMode = 0x53c0,
108
- Audio = 0xe1,
109
- SamplingFrequency = 0xb5,
110
- Channels = 0x9f,
111
- BitDepth = 0x6264,
112
- SimpleBlock = 0xa3,
113
- BlockGroup = 0xa0,
114
- Block = 0xa1,
115
- BlockAdditions = 0x75a1,
116
- BlockMore = 0xa6,
117
- BlockAdditional = 0xa5,
118
- BlockAddID = 0xee,
119
- BlockDuration = 0x9b,
120
- ReferenceBlock = 0xfb,
121
- Cluster = 0x1f43b675,
122
- Timestamp = 0xe7,
123
- Cues = 0x1c53bb6b,
124
- CuePoint = 0xbb,
125
- CueTime = 0xb3,
126
- CueTrackPositions = 0xb7,
127
- CueTrack = 0xf7,
128
- CueClusterPosition = 0xf1,
129
- Colour = 0x55b0,
130
- MatrixCoefficients = 0x55b1,
131
- TransferCharacteristics = 0x55ba,
132
- Primaries = 0x55bb,
133
- Range = 0x55b9,
134
- Projection = 0x7670,
135
- ProjectionType = 0x7671,
136
- ProjectionPoseRoll = 0x7675,
137
- Attachments = 0x1941a469,
138
- AttachedFile = 0x61a7,
139
- FileDescription = 0x467e,
140
- FileName = 0x466e,
141
- FileMediaType = 0x4660,
142
- FileData = 0x465c,
143
- FileUID = 0x46ae,
144
- Chapters = 0x1043a770,
145
- Tags = 0x1254c367,
146
- Tag = 0x7373,
147
- Targets = 0x63c0,
148
- TargetTypeValue = 0x68ca,
149
- TargetType = 0x63ca,
150
- TagTrackUID = 0x63c5,
151
- TagEditionUID = 0x63c9,
152
- TagChapterUID = 0x63c4,
153
- TagAttachmentUID = 0x63c6,
154
- SimpleTag = 0x67c8,
155
- TagName = 0x45a3,
156
- TagLanguage = 0x447a,
157
- TagString = 0x4487,
158
- TagBinary = 0x4485,
159
- ContentEncodings = 0x6d80,
160
- ContentEncoding = 0x6240,
161
- ContentEncodingOrder = 0x5031,
162
- ContentEncodingScope = 0x5032,
163
- ContentCompression = 0x5034,
164
- ContentCompAlgo = 0x4254,
165
- ContentCompSettings = 0x4255,
166
- ContentEncryption = 0x5035,
167
- }
168
-
169
- export const LEVEL_0_EBML_IDS: EBMLId[] = [
170
- EBMLId.EBML,
171
- EBMLId.Segment,
172
- ];
173
-
174
- // All the stuff that can appear in a segment, basically
175
- export const LEVEL_1_EBML_IDS: EBMLId[] = [
176
- EBMLId.SeekHead,
177
- EBMLId.Info,
178
- EBMLId.Cluster,
179
- EBMLId.Tracks,
180
- EBMLId.Cues,
181
- EBMLId.Attachments,
182
- EBMLId.Chapters,
183
- EBMLId.Tags,
184
- ];
185
-
186
- export const LEVEL_0_AND_1_EBML_IDS = [
187
- ...LEVEL_0_EBML_IDS,
188
- ...LEVEL_1_EBML_IDS,
189
- ];
190
-
191
- export const measureUnsignedInt = (value: number) => {
192
- if (value < (1 << 8)) {
193
- return 1;
194
- } else if (value < (1 << 16)) {
195
- return 2;
196
- } else if (value < (1 << 24)) {
197
- return 3;
198
- } else if (value < 2 ** 32) {
199
- return 4;
200
- } else if (value < 2 ** 40) {
201
- return 5;
202
- } else {
203
- return 6;
204
- }
205
- };
206
-
207
- export const measureUnsignedBigInt = (value: bigint) => {
208
- if (value < (1n << 8n)) {
209
- return 1;
210
- } else if (value < (1n << 16n)) {
211
- return 2;
212
- } else if (value < (1n << 24n)) {
213
- return 3;
214
- } else if (value < (1n << 32n)) {
215
- return 4;
216
- } else if (value < (1n << 40n)) {
217
- return 5;
218
- } else if (value < (1n << 48n)) {
219
- return 6;
220
- } else if (value < (1n << 56n)) {
221
- return 7;
222
- } else {
223
- return 8;
224
- }
225
- };
226
-
227
- export const measureSignedInt = (value: number) => {
228
- if (value >= -(1 << 6) && value < (1 << 6)) {
229
- return 1;
230
- } else if (value >= -(1 << 13) && value < (1 << 13)) {
231
- return 2;
232
- } else if (value >= -(1 << 20) && value < (1 << 20)) {
233
- return 3;
234
- } else if (value >= -(1 << 27) && value < (1 << 27)) {
235
- return 4;
236
- } else if (value >= -(2 ** 34) && value < 2 ** 34) {
237
- return 5;
238
- } else {
239
- return 6;
240
- }
241
- };
242
-
243
- export const measureVarInt = (value: number) => {
244
- if (value < (1 << 7) - 1) {
245
- /** Top bit is set, leaving 7 bits to hold the integer, but we can't store
246
- * 127 because "all bits set to one" is a reserved value. Same thing for the
247
- * other cases below:
248
- */
249
- return 1;
250
- } else if (value < (1 << 14) - 1) {
251
- return 2;
252
- } else if (value < (1 << 21) - 1) {
253
- return 3;
254
- } else if (value < (1 << 28) - 1) {
255
- return 4;
256
- } else if (value < 2 ** 35 - 1) {
257
- return 5;
258
- } else if (value < 2 ** 42 - 1) {
259
- return 6;
260
- } else {
261
- throw new Error('EBML varint size not supported ' + value);
262
- }
263
- };
264
-
265
- export class EBMLWriter {
266
- helper = new Uint8Array(8);
267
- helperView = new DataView(this.helper.buffer);
268
-
269
- /**
270
- * Stores the position from the start of the file to where EBML elements have been written. This is used to
271
- * rewrite/edit elements that were already added before, and to measure sizes of things.
272
- */
273
- offsets = new WeakMap<EBML, number>();
274
- /** Same as offsets, but stores position where the element's data starts (after ID and size fields). */
275
- dataOffsets = new WeakMap<EBML, number>();
276
-
277
- constructor(private writer: Writer) {}
278
-
279
- writeByte(value: number) {
280
- this.helperView.setUint8(0, value);
281
- this.writer.write(this.helper.subarray(0, 1));
282
- }
283
-
284
- writeFloat32(value: number) {
285
- this.helperView.setFloat32(0, value, false);
286
- this.writer.write(this.helper.subarray(0, 4));
287
- }
288
-
289
- writeFloat64(value: number) {
290
- this.helperView.setFloat64(0, value, false);
291
- this.writer.write(this.helper);
292
- }
293
-
294
- writeUnsignedInt(value: number, width = measureUnsignedInt(value)) {
295
- let pos = 0;
296
-
297
- // Each case falls through:
298
- switch (width) {
299
- case 6:
300
- // Need to use division to access >32 bits of floating point var
301
- this.helperView.setUint8(pos++, (value / 2 ** 40) | 0);
302
- // eslint-disable-next-line no-fallthrough
303
- case 5:
304
- this.helperView.setUint8(pos++, (value / 2 ** 32) | 0);
305
- // eslint-disable-next-line no-fallthrough
306
- case 4:
307
- this.helperView.setUint8(pos++, value >> 24);
308
- // eslint-disable-next-line no-fallthrough
309
- case 3:
310
- this.helperView.setUint8(pos++, value >> 16);
311
- // eslint-disable-next-line no-fallthrough
312
- case 2:
313
- this.helperView.setUint8(pos++, value >> 8);
314
- // eslint-disable-next-line no-fallthrough
315
- case 1:
316
- this.helperView.setUint8(pos++, value);
317
- break;
318
- default:
319
- throw new Error('Bad unsigned int size ' + width);
320
- }
321
-
322
- this.writer.write(this.helper.subarray(0, pos));
323
- }
324
-
325
- writeUnsignedBigInt(value: bigint, width = measureUnsignedBigInt(value)) {
326
- let pos = 0;
327
-
328
- for (let i = width - 1; i >= 0; i--) {
329
- this.helperView.setUint8(pos++, Number((value >> BigInt(i * 8)) & 0xffn));
330
- }
331
-
332
- this.writer.write(this.helper.subarray(0, pos));
333
- }
334
-
335
- writeSignedInt(value: number, width = measureSignedInt(value)) {
336
- if (value < 0) {
337
- // Two's complement stuff
338
- value += 2 ** (width * 8);
339
- }
340
-
341
- this.writeUnsignedInt(value, width);
342
- }
343
-
344
- writeVarInt(value: number, width = measureVarInt(value)) {
345
- let pos = 0;
346
-
347
- switch (width) {
348
- case 1:
349
- this.helperView.setUint8(pos++, (1 << 7) | value);
350
- break;
351
- case 2:
352
- this.helperView.setUint8(pos++, (1 << 6) | (value >> 8));
353
- this.helperView.setUint8(pos++, value);
354
- break;
355
- case 3:
356
- this.helperView.setUint8(pos++, (1 << 5) | (value >> 16));
357
- this.helperView.setUint8(pos++, value >> 8);
358
- this.helperView.setUint8(pos++, value);
359
- break;
360
- case 4:
361
- this.helperView.setUint8(pos++, (1 << 4) | (value >> 24));
362
- this.helperView.setUint8(pos++, value >> 16);
363
- this.helperView.setUint8(pos++, value >> 8);
364
- this.helperView.setUint8(pos++, value);
365
- break;
366
- case 5:
367
- /**
368
- * JavaScript converts its doubles to 32-bit integers for bitwise
369
- * operations, so we need to do a division by 2^32 instead of a
370
- * right-shift of 32 to retain those top 3 bits
371
- */
372
- this.helperView.setUint8(pos++, (1 << 3) | ((value / 2 ** 32) & 0x7));
373
- this.helperView.setUint8(pos++, value >> 24);
374
- this.helperView.setUint8(pos++, value >> 16);
375
- this.helperView.setUint8(pos++, value >> 8);
376
- this.helperView.setUint8(pos++, value);
377
- break;
378
- case 6:
379
- this.helperView.setUint8(pos++, (1 << 2) | ((value / 2 ** 40) & 0x3));
380
- this.helperView.setUint8(pos++, (value / 2 ** 32) | 0);
381
- this.helperView.setUint8(pos++, value >> 24);
382
- this.helperView.setUint8(pos++, value >> 16);
383
- this.helperView.setUint8(pos++, value >> 8);
384
- this.helperView.setUint8(pos++, value);
385
- break;
386
- default:
387
- throw new Error('Bad EBML varint size ' + width);
388
- }
389
-
390
- this.writer.write(this.helper.subarray(0, pos));
391
- }
392
-
393
- writeAsciiString(str: string) {
394
- this.writer.write(new Uint8Array(str.split('').map(x => x.charCodeAt(0))));
395
- }
396
-
397
- writeEBML(data: EBML | null) {
398
- if (data === null) return;
399
-
400
- if (data instanceof Uint8Array) {
401
- this.writer.write(data);
402
- } else if (Array.isArray(data)) {
403
- for (const elem of data) {
404
- this.writeEBML(elem);
405
- }
406
- } else {
407
- this.offsets.set(data, this.writer.getPos());
408
-
409
- this.writeUnsignedInt(data.id); // ID field
410
-
411
- if (Array.isArray(data.data)) {
412
- const sizePos = this.writer.getPos();
413
- const sizeSize = data.size === -1 ? 1 : (data.size ?? 4);
414
-
415
- if (data.size === -1) {
416
- // Write the reserved all-one-bits marker for unknown/unbounded size.
417
- this.writeByte(0xff);
418
- } else {
419
- this.writer.seek(this.writer.getPos() + sizeSize);
420
- }
421
-
422
- const startPos = this.writer.getPos();
423
- this.dataOffsets.set(data, startPos);
424
- this.writeEBML(data.data);
425
-
426
- if (data.size !== -1) {
427
- const size = this.writer.getPos() - startPos;
428
- const endPos = this.writer.getPos();
429
- this.writer.seek(sizePos);
430
- this.writeVarInt(size, sizeSize);
431
- this.writer.seek(endPos);
432
- }
433
- } else if (typeof data.data === 'number') {
434
- const size = data.size ?? measureUnsignedInt(data.data);
435
- this.writeVarInt(size);
436
- this.writeUnsignedInt(data.data, size);
437
- } else if (typeof data.data === 'bigint') {
438
- const size = data.size ?? measureUnsignedBigInt(data.data);
439
- this.writeVarInt(size);
440
- this.writeUnsignedBigInt(data.data, size);
441
- } else if (typeof data.data === 'string') {
442
- this.writeVarInt(data.data.length);
443
- this.writeAsciiString(data.data);
444
- } else if (data.data instanceof Uint8Array) {
445
- this.writeVarInt(data.data.byteLength, data.size);
446
- this.writer.write(data.data);
447
- } else if (data.data instanceof EBMLFloat32) {
448
- this.writeVarInt(4);
449
- this.writeFloat32(data.data.value);
450
- } else if (data.data instanceof EBMLFloat64) {
451
- this.writeVarInt(8);
452
- this.writeFloat64(data.data.value);
453
- } else if (data.data instanceof EBMLSignedInt) {
454
- const size = data.size ?? measureSignedInt(data.data.value);
455
- this.writeVarInt(size);
456
- this.writeSignedInt(data.data.value, size);
457
- } else if (data.data instanceof EBMLUnicodeString) {
458
- const bytes = textEncoder.encode(data.data.value);
459
- this.writeVarInt(bytes.length);
460
- this.writer.write(bytes);
461
- } else {
462
- assertNever(data.data);
463
- }
464
- }
465
- }
466
- }
467
-
468
- export const MAX_VAR_INT_SIZE = 8;
469
- export const MIN_HEADER_SIZE = 2; // 1-byte ID and 1-byte size
470
- export const MAX_HEADER_SIZE = /* #__PURE__ */ 2 * MAX_VAR_INT_SIZE; // 8-byte ID and 8-byte size
471
-
472
- export const readVarIntSize = (slice: FileSlice) => {
473
- const firstByte = readU8(slice);
474
- slice.skip(-1);
475
-
476
- if (firstByte === 0) {
477
- return null; // Invalid VINT
478
- }
479
-
480
- let width = 1;
481
- let mask = 0x80;
482
- while ((firstByte & mask) === 0) {
483
- width++;
484
- mask >>= 1;
485
- }
486
-
487
- return width;
488
- };
489
-
490
- export const readVarInt = (slice: FileSlice) => {
491
- // Read the first byte to determine the width of the variable-length integer
492
- const firstByte = readU8(slice);
493
-
494
- if (firstByte === 0) {
495
- return null; // Invalid VINT
496
- }
497
-
498
- // Find the position of VINT_MARKER, which determines the width
499
- let width = 1;
500
- let mask = 1 << 7;
501
- while ((firstByte & mask) === 0) {
502
- width++;
503
- mask >>= 1;
504
- }
505
-
506
- // First byte's value needs the marker bit cleared
507
- let value = firstByte & (mask - 1);
508
-
509
- // Read remaining bytes
510
- for (let i = 1; i < width; i++) {
511
- value *= 1 << 8;
512
- value += readU8(slice);
513
- }
514
-
515
- return value;
516
- };
517
-
518
- export const readUnsignedInt = (slice: FileSlice, width: number) => {
519
- if (width < 1 || width > 8) {
520
- throw new Error('Bad unsigned int size ' + width);
521
- }
522
-
523
- let value = 0;
524
-
525
- // Read bytes from most significant to least significant
526
- for (let i = 0; i < width; i++) {
527
- value *= 1 << 8;
528
- value += readU8(slice);
529
- }
530
-
531
- return value;
532
- };
533
-
534
- export const readUnsignedBigInt = (slice: FileSlice, width: number) => {
535
- if (width < 1) {
536
- throw new Error('Bad unsigned int size ' + width);
537
- }
538
-
539
- let value = 0n;
540
-
541
- for (let i = 0; i < width; i++) {
542
- value <<= 8n;
543
- value += BigInt(readU8(slice));
544
- }
545
-
546
- return value;
547
- };
548
-
549
- export const readSignedInt = (slice: FileSlice, width: number) => {
550
- let value = readUnsignedInt(slice, width);
551
-
552
- // If the highest bit is set, convert from two's complement
553
- if (value & (1 << (width * 8 - 1))) {
554
- value -= 2 ** (width * 8);
555
- }
556
-
557
- return value;
558
- };
559
-
560
- export const readElementId = (slice: FileSlice) => {
561
- const size = readVarIntSize(slice);
562
- if (size === null) {
563
- return null;
564
- }
565
-
566
- const id = readUnsignedInt(slice, size);
567
- return id;
568
- };
569
-
570
- export const readElementSize = (slice: FileSlice) => {
571
- let size: number | null = readU8(slice);
572
-
573
- if (size === 0xff) {
574
- size = null;
575
- } else {
576
- slice.skip(-1);
577
- size = readVarInt(slice);
578
-
579
- // In some (livestreamed) files, this is the value of the size field. While this technically is just a very
580
- // large number, it is intended to behave like the reserved size 0xFF, meaning the size is undefined. We
581
- // catch the number here. Note that it cannot be perfectly represented as a double, but the comparison works
582
- // nonetheless.
583
- // eslint-disable-next-line no-loss-of-precision
584
- if (size === 0x00ffffffffffffff) {
585
- size = null;
586
- }
587
- }
588
-
589
- return size;
590
- };
591
-
592
- export const readElementHeader = (slice: FileSlice) => {
593
- const id = readElementId(slice);
594
- if (id === null) {
595
- return null;
596
- }
597
-
598
- const size = readElementSize(slice);
599
-
600
- return { id, size };
601
- };
602
-
603
- export const readAsciiString = (slice: FileSlice, length: number) => {
604
- const bytes = readBytes(slice, length);
605
-
606
- // Actual string length might be shorter due to null terminators
607
- let strLength = 0;
608
- while (strLength < length && bytes[strLength] !== 0) {
609
- strLength += 1;
610
- }
611
-
612
- return String.fromCharCode(...bytes.subarray(0, strLength));
613
- };
614
-
615
- export const readUnicodeString = (slice: FileSlice, length: number) => {
616
- const bytes = readBytes(slice, length);
617
-
618
- // Actual string length might be shorter due to null terminators
619
- let strLength = 0;
620
- while (strLength < length && bytes[strLength] !== 0) {
621
- strLength += 1;
622
- }
623
-
624
- return textDecoder.decode(bytes.subarray(0, strLength));
625
- };
626
-
627
- export const readFloat = (slice: FileSlice, width: number) => {
628
- if (width === 0) {
629
- return 0;
630
- }
631
-
632
- if (width !== 4 && width !== 8) {
633
- throw new Error('Bad float size ' + width);
634
- }
635
-
636
- return width === 4 ? readF32Be(slice) : readF64Be(slice);
637
- };
638
-
639
- /** Returns the byte offset in the file of the next element with a matching ID. */
640
- export const searchForNextElementId = async (
641
- reader: Reader,
642
- startPos: number,
643
- ids: EBMLId[],
644
- until: number | null,
645
- ): Promise<{ pos: number; found: boolean }> => {
646
- const idsSet = new Set(ids);
647
- let currentPos = startPos;
648
-
649
- while (until === null || currentPos < until) {
650
- let slice = reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
651
- if (slice instanceof Promise) slice = await slice;
652
- if (!slice) break;
653
-
654
- const elementHeader = readElementHeader(slice);
655
- if (!elementHeader) {
656
- break;
657
- }
658
-
659
- if (idsSet.has(elementHeader.id)) {
660
- return { pos: currentPos, found: true };
661
- }
662
-
663
- assertDefinedSize(elementHeader.size);
664
-
665
- currentPos = slice.filePos + elementHeader.size;
666
- }
667
-
668
- return { pos: (until !== null && until > currentPos) ? until : currentPos, found: false };
669
- };
670
-
671
- /** Searches for the next occurrence of an element ID using a naive byte-wise search. */
672
- export const resync = async (reader: Reader, startPos: number, ids: EBMLId[], until: number) => {
673
- const CHUNK_SIZE = 2 ** 16; // So we don't need to grab thousands of slices
674
- const idsSet = new Set(ids);
675
- let currentPos = startPos;
676
-
677
- while (currentPos < until) {
678
- let slice = reader.requestSliceRange(currentPos, 0, Math.min(CHUNK_SIZE, until - currentPos));
679
- if (slice instanceof Promise) slice = await slice;
680
- if (!slice) break;
681
- if (slice.length < MAX_VAR_INT_SIZE) break;
682
-
683
- for (let i = 0; i < slice.length - MAX_VAR_INT_SIZE; i++) {
684
- slice.filePos = currentPos;
685
-
686
- const elementId = readElementId(slice);
687
- if (elementId !== null && idsSet.has(elementId)) {
688
- return currentPos;
689
- }
690
-
691
- currentPos++;
692
- }
693
- }
694
-
695
- return null;
696
- };
697
-
698
- export const CODEC_STRING_MAP: Partial<Record<MediaCodec, string>> = {
699
- 'avc': 'V_MPEG4/ISO/AVC',
700
- 'hevc': 'V_MPEGH/ISO/HEVC',
701
- 'vp8': 'V_VP8',
702
- 'vp9': 'V_VP9',
703
- 'av1': 'V_AV1',
704
-
705
- 'aac': 'A_AAC',
706
- 'mp3': 'A_MPEG/L3',
707
- 'opus': 'A_OPUS',
708
- 'vorbis': 'A_VORBIS',
709
- 'flac': 'A_FLAC',
710
- 'pcm-u8': 'A_PCM/INT/LIT',
711
- 'pcm-s16': 'A_PCM/INT/LIT',
712
- 'pcm-s16be': 'A_PCM/INT/BIG',
713
- 'pcm-s24': 'A_PCM/INT/LIT',
714
- 'pcm-s24be': 'A_PCM/INT/BIG',
715
- 'pcm-s32': 'A_PCM/INT/LIT',
716
- 'pcm-s32be': 'A_PCM/INT/BIG',
717
- 'pcm-f32': 'A_PCM/FLOAT/IEEE',
718
- 'pcm-f64': 'A_PCM/FLOAT/IEEE',
719
-
720
- 'webvtt': 'S_TEXT/WEBVTT',
721
- 'srt': 'S_TEXT/UTF8',
722
- 'ass': 'S_TEXT/ASS',
723
- 'ssa': 'S_TEXT/SSA',
724
- };
725
-
726
- export function assertDefinedSize(size: number | null): asserts size is number {
727
- if (size === null) {
728
- throw new Error('Undefined element size is used in a place where it is not supported.');
729
- }
730
- };