@svta/cml-iso-bmff 1.0.0-alpha.2 → 1.0.0-alpha.4
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/dist/index.d.ts +485 -273
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1471 -1318
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,18 +15,14 @@ function createWriterConfig(config) {
|
|
|
15
15
|
const CONTAINERS = [
|
|
16
16
|
"dinf",
|
|
17
17
|
"edts",
|
|
18
|
-
"enca",
|
|
19
|
-
"encv",
|
|
20
18
|
"grpl",
|
|
21
19
|
"mdia",
|
|
22
20
|
"meco",
|
|
23
|
-
"meta",
|
|
24
21
|
"mfra",
|
|
25
22
|
"minf",
|
|
26
23
|
"moof",
|
|
27
24
|
"moov",
|
|
28
25
|
"mvex",
|
|
29
|
-
"prsl",
|
|
30
26
|
"schi",
|
|
31
27
|
"sinf",
|
|
32
28
|
"stbl",
|
|
@@ -150,8 +146,11 @@ var IsoBoxWriteView = class {
|
|
|
150
146
|
this.writeUint(0, 1);
|
|
151
147
|
};
|
|
152
148
|
this.writeBytes = (data) => {
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
if (!Array.isArray(data)) data = [data];
|
|
150
|
+
for (const bytes of data) {
|
|
151
|
+
new Uint8Array(this.dataView.buffer).set(bytes, this.cursor);
|
|
152
|
+
this.cursor += bytes.length;
|
|
153
|
+
}
|
|
155
154
|
};
|
|
156
155
|
this.writeArray = (data, type$1, size$1, length) => {
|
|
157
156
|
const write = type$1 === UINT ? this.writeUint : type$1 === TEMPLATE ? this.writeTemplate : this.writeInt;
|
|
@@ -213,7 +212,43 @@ var IsoBoxWriteView = class {
|
|
|
213
212
|
};
|
|
214
213
|
|
|
215
214
|
//#endregion
|
|
216
|
-
//#region src/
|
|
215
|
+
//#region src/utils/writeBoxes.ts
|
|
216
|
+
/**
|
|
217
|
+
* Write boxes to an array of Uint8Arrays.
|
|
218
|
+
*
|
|
219
|
+
* @param boxes - The boxes to write
|
|
220
|
+
* @param config - The configuration for the writer
|
|
221
|
+
*
|
|
222
|
+
* @returns The written boxes
|
|
223
|
+
*
|
|
224
|
+
* @internal
|
|
225
|
+
*/
|
|
226
|
+
function writeBoxes(boxes, config) {
|
|
227
|
+
return Array.from(boxes, (box) => writeBox(box, config));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
//#endregion
|
|
231
|
+
//#region src/utils/writeChildBoxes.ts
|
|
232
|
+
/**
|
|
233
|
+
* Write child boxes
|
|
234
|
+
*
|
|
235
|
+
* @param boxes - The boxes to write
|
|
236
|
+
* @param config - The configuration for the writer
|
|
237
|
+
*
|
|
238
|
+
* @returns The byte arrays and total size of the written boxes
|
|
239
|
+
*
|
|
240
|
+
* @internal
|
|
241
|
+
*/
|
|
242
|
+
function writeChildBoxes(boxes, config) {
|
|
243
|
+
const bytes = writeBoxes(boxes, config);
|
|
244
|
+
return {
|
|
245
|
+
bytes,
|
|
246
|
+
size: bytes.reduce((size, byte) => size + byte.byteLength, 0)
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
//#endregion
|
|
251
|
+
//#region src/utils/writeContainerBox.ts
|
|
217
252
|
/**
|
|
218
253
|
* Write a ContainerBox to an IsoBmffWriter.
|
|
219
254
|
*
|
|
@@ -223,24 +258,20 @@ var IsoBoxWriteView = class {
|
|
|
223
258
|
* @param box - The ContainerBox to write
|
|
224
259
|
*
|
|
225
260
|
* @returns An IsoBmffWriter containing the encoded box
|
|
261
|
+
*
|
|
262
|
+
* @internal
|
|
226
263
|
*/
|
|
227
264
|
function writeContainerBox(box, config) {
|
|
228
|
-
const children = [];
|
|
229
265
|
const headerSize = 8;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const view = writeIsoBox(childBox, config);
|
|
233
|
-
childrenSize += view.byteLength;
|
|
234
|
-
children.push(view);
|
|
235
|
-
}
|
|
236
|
-
const totalSize = headerSize + childrenSize;
|
|
266
|
+
const { bytes, size } = writeChildBoxes(box.boxes, config);
|
|
267
|
+
const totalSize = headerSize + size;
|
|
237
268
|
const writer = new IsoBoxWriteView(box.type, totalSize);
|
|
238
|
-
|
|
269
|
+
writer.writeBytes(bytes);
|
|
239
270
|
return writer;
|
|
240
271
|
}
|
|
241
272
|
|
|
242
273
|
//#endregion
|
|
243
|
-
//#region src/
|
|
274
|
+
//#region src/utils/writeBox.ts
|
|
244
275
|
/**
|
|
245
276
|
* Write a box to a Uint8Array.
|
|
246
277
|
*
|
|
@@ -254,12 +285,10 @@ function writeBox(box, config) {
|
|
|
254
285
|
let view = null;
|
|
255
286
|
if ("type" in box) {
|
|
256
287
|
const { type } = box;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
else if ("view" in box) view = box.view;
|
|
262
|
-
}
|
|
288
|
+
const writer = config.writers?.[type];
|
|
289
|
+
if (writer) view = writer(box, config);
|
|
290
|
+
else if (isContainer(box)) view = writeContainerBox(box, config);
|
|
291
|
+
else if ("view" in box) view = box.view;
|
|
263
292
|
if (!view) throw new Error(`No writer found for box type: ${type}`);
|
|
264
293
|
}
|
|
265
294
|
if ("buffer" in box) view = box;
|
|
@@ -273,7 +302,8 @@ function writeBox(box, config) {
|
|
|
273
302
|
* Write an ISO box to a Uint8Array.
|
|
274
303
|
*
|
|
275
304
|
* @param box - The box to write
|
|
276
|
-
* @param
|
|
305
|
+
* @param config - The configuration for the writer
|
|
306
|
+
*
|
|
277
307
|
* @returns The written box
|
|
278
308
|
*
|
|
279
309
|
* @public
|
|
@@ -334,1854 +364,1961 @@ function createIsoBoxReadableStream(boxes, config = {}) {
|
|
|
334
364
|
}
|
|
335
365
|
|
|
336
366
|
//#endregion
|
|
337
|
-
//#region src/
|
|
367
|
+
//#region src/traverseIsoBoxes.ts
|
|
338
368
|
/**
|
|
339
|
-
*
|
|
369
|
+
* Traverse ISO boxes
|
|
340
370
|
*
|
|
341
|
-
* @param
|
|
371
|
+
* @param boxes - The boxes to traverse
|
|
372
|
+
* @param config - Configuration options for traversal
|
|
342
373
|
*
|
|
343
|
-
* @returns A
|
|
374
|
+
* @returns A generator of boxes
|
|
375
|
+
*
|
|
376
|
+
* @example
|
|
377
|
+
* {@includeCode ../test/traverseIsoBoxes.test.ts#example}
|
|
344
378
|
*
|
|
345
379
|
* @public
|
|
346
380
|
*/
|
|
347
|
-
function
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
381
|
+
function* traverseIsoBoxes(boxes, config) {
|
|
382
|
+
const depthFirst = config?.depthFirst ?? true;
|
|
383
|
+
const maxDepth = config?.maxDepth ?? Infinity;
|
|
384
|
+
if (maxDepth < 0 || typeof maxDepth !== "number" || Number.isNaN(maxDepth)) return;
|
|
385
|
+
const queue = [[boxes, 0]];
|
|
386
|
+
while (queue.length > 0) {
|
|
387
|
+
const item = queue.shift();
|
|
388
|
+
if (!item) continue;
|
|
389
|
+
const [children, depth] = item;
|
|
390
|
+
for (const child of children) {
|
|
391
|
+
yield child;
|
|
392
|
+
if (depth >= maxDepth) continue;
|
|
393
|
+
if (isContainer(child) && child.boxes) {
|
|
394
|
+
const next = child.boxes;
|
|
395
|
+
if (depthFirst) yield* traverseIsoBoxes(next, {
|
|
396
|
+
depthFirst,
|
|
397
|
+
maxDepth: maxDepth - 1
|
|
398
|
+
});
|
|
399
|
+
else queue.push([next, depth + 1]);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
353
403
|
}
|
|
354
404
|
|
|
355
405
|
//#endregion
|
|
356
|
-
//#region src/
|
|
406
|
+
//#region src/filterIsoBoxes.ts
|
|
357
407
|
/**
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
* @param view - The IsoView to read data from
|
|
408
|
+
* Filters boxes in the tree that satisfy the provided testing function.
|
|
361
409
|
*
|
|
362
|
-
*
|
|
410
|
+
* This function traverses the entire box structure (including nested boxes)
|
|
411
|
+
* and returns all boxes for which the callback returns true.
|
|
363
412
|
*
|
|
364
|
-
* @
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const { readArray, readUint: readUint$1, readInt: readInt$1, readTemplate: readTemplate$1, readData: readData$1 } = view;
|
|
368
|
-
return {
|
|
369
|
-
type: "avc1",
|
|
370
|
-
reserved1: readArray(UINT, 1, 6),
|
|
371
|
-
dataReferenceIndex: readUint$1(2),
|
|
372
|
-
preDefined1: readUint$1(2),
|
|
373
|
-
reserved2: readUint$1(2),
|
|
374
|
-
preDefined2: readArray(UINT, 4, 3),
|
|
375
|
-
width: readUint$1(2),
|
|
376
|
-
height: readUint$1(2),
|
|
377
|
-
horizresolution: readTemplate$1(4),
|
|
378
|
-
vertresolution: readTemplate$1(4),
|
|
379
|
-
reserved3: readUint$1(4),
|
|
380
|
-
frameCount: readUint$1(2),
|
|
381
|
-
compressorName: readArray(UINT, 1, 32),
|
|
382
|
-
depth: readUint$1(2),
|
|
383
|
-
preDefined3: readInt$1(2),
|
|
384
|
-
config: readData$1(-1)
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
//#endregion
|
|
389
|
-
//#region src/readers/readAvc2.ts
|
|
390
|
-
/**
|
|
391
|
-
* Parse a VisualSampleEntryBox from an IsoView
|
|
413
|
+
* @param boxes - The boxes to search through
|
|
414
|
+
* @param callback - A function that accepts a box and returns true if it matches
|
|
415
|
+
* @param config - Configuration options for traversal
|
|
392
416
|
*
|
|
393
|
-
* @
|
|
417
|
+
* @returns An array of boxes that satisfy the callback
|
|
394
418
|
*
|
|
395
|
-
* @
|
|
419
|
+
* @example
|
|
420
|
+
* {@includeCode ../test/filterIsoBoxes.test.ts#example}
|
|
396
421
|
*
|
|
397
422
|
* @public
|
|
398
423
|
*/
|
|
399
|
-
function
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
};
|
|
424
|
+
function filterIsoBoxes(boxes, callback, config) {
|
|
425
|
+
const result = [];
|
|
426
|
+
for (const box of traverseIsoBoxes(boxes, config)) if (callback(box)) result.push(box);
|
|
427
|
+
return result;
|
|
404
428
|
}
|
|
405
429
|
|
|
406
430
|
//#endregion
|
|
407
|
-
//#region src/
|
|
431
|
+
//#region src/findIsoBox.ts
|
|
408
432
|
/**
|
|
409
|
-
*
|
|
433
|
+
* Finds the first box in the tree that satisfies the provided testing function.
|
|
410
434
|
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
* @returns A parsed VisualSampleEntryBox
|
|
435
|
+
* This function traverses the entire box structure (including nested boxes)
|
|
436
|
+
* and returns the first box for which the callback returns true.
|
|
414
437
|
*
|
|
415
|
-
* @
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
return {
|
|
419
|
-
...readAvc1(view),
|
|
420
|
-
type: "avc3"
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
//#endregion
|
|
425
|
-
//#region src/readers/readAvc4.ts
|
|
426
|
-
/**
|
|
427
|
-
* Parse a VisualSampleEntryBox from an IsoView
|
|
438
|
+
* @param boxes - The boxes to search through
|
|
439
|
+
* @param callback - A function that accepts a box and returns true if it matches
|
|
440
|
+
* @param config - Configuration options for traversal
|
|
428
441
|
*
|
|
429
|
-
* @
|
|
442
|
+
* @returns The first box that satisfies the callback, or null if none is found
|
|
430
443
|
*
|
|
431
|
-
* @
|
|
444
|
+
* @example
|
|
445
|
+
* {@includeCode ../test/findIsoBox.test.ts#example}
|
|
432
446
|
*
|
|
433
447
|
* @public
|
|
434
448
|
*/
|
|
435
|
-
function
|
|
436
|
-
return
|
|
437
|
-
|
|
438
|
-
type: "avc4"
|
|
439
|
-
};
|
|
449
|
+
function findIsoBox(boxes, callback, config) {
|
|
450
|
+
for (const box of traverseIsoBoxes(boxes, config)) if (callback(box)) return box;
|
|
451
|
+
return null;
|
|
440
452
|
}
|
|
441
453
|
|
|
442
454
|
//#endregion
|
|
443
|
-
//#region src/
|
|
455
|
+
//#region src/fields/DATA.ts
|
|
444
456
|
/**
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
* @param view - The IsoView to read data from
|
|
448
|
-
*
|
|
449
|
-
* @returns A parsed CompositionTimeToSampleBox
|
|
457
|
+
* The data field type
|
|
450
458
|
*
|
|
451
459
|
* @public
|
|
452
460
|
*/
|
|
453
|
-
|
|
454
|
-
const { version, flags } = view.readFullBox();
|
|
455
|
-
const read = version === 1 ? view.readInt : view.readUint;
|
|
456
|
-
const entryCount = view.readUint(4);
|
|
457
|
-
return {
|
|
458
|
-
type: "ctts",
|
|
459
|
-
version,
|
|
460
|
-
flags,
|
|
461
|
-
entryCount,
|
|
462
|
-
entries: view.readEntries(entryCount, () => ({
|
|
463
|
-
sampleCount: view.readUint(4),
|
|
464
|
-
sampleOffset: read(4)
|
|
465
|
-
}))
|
|
466
|
-
};
|
|
467
|
-
}
|
|
461
|
+
const DATA = "data";
|
|
468
462
|
|
|
469
463
|
//#endregion
|
|
470
|
-
//#region src/
|
|
464
|
+
//#region src/fields/INT.ts
|
|
471
465
|
/**
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
* @param view - The IsoView to read data from
|
|
475
|
-
*
|
|
476
|
-
* @returns A parsed DataReferenceBox
|
|
466
|
+
* The integer field type
|
|
477
467
|
*
|
|
478
468
|
* @public
|
|
479
469
|
*/
|
|
480
|
-
|
|
481
|
-
const { version, flags } = view.readFullBox();
|
|
482
|
-
const entryCount = view.readUint(4);
|
|
483
|
-
return {
|
|
484
|
-
type: "dref",
|
|
485
|
-
version,
|
|
486
|
-
flags,
|
|
487
|
-
entryCount,
|
|
488
|
-
entries: view.readBoxes(entryCount)
|
|
489
|
-
};
|
|
490
|
-
}
|
|
470
|
+
const INT = "int";
|
|
491
471
|
|
|
492
472
|
//#endregion
|
|
493
|
-
//#region src/
|
|
473
|
+
//#region src/fields/STRING.ts
|
|
494
474
|
/**
|
|
495
|
-
*
|
|
496
|
-
*
|
|
497
|
-
* @param view - The IsoView to read data from
|
|
498
|
-
*
|
|
499
|
-
* @returns A parsed ExtendedLanguageBox
|
|
475
|
+
* The string field type
|
|
500
476
|
*
|
|
501
477
|
* @public
|
|
502
478
|
*/
|
|
503
|
-
|
|
504
|
-
return {
|
|
505
|
-
type: "elng",
|
|
506
|
-
...view.readFullBox(),
|
|
507
|
-
extendedLanguage: view.readUtf8(-1)
|
|
508
|
-
};
|
|
509
|
-
}
|
|
479
|
+
const STRING = "string";
|
|
510
480
|
|
|
511
481
|
//#endregion
|
|
512
|
-
//#region src/
|
|
482
|
+
//#region src/fields/UTF8.ts
|
|
513
483
|
/**
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
* @param view - The IsoView to read data from
|
|
517
|
-
*
|
|
518
|
-
* @returns A parsed Box
|
|
484
|
+
* The UTF8 field type
|
|
519
485
|
*
|
|
520
486
|
* @public
|
|
521
487
|
*/
|
|
522
|
-
|
|
523
|
-
const { version, flags } = view.readFullBox();
|
|
524
|
-
const size = version === 1 ? 8 : 4;
|
|
525
|
-
const entryCount = view.readUint(4);
|
|
526
|
-
return {
|
|
527
|
-
type: "elst",
|
|
528
|
-
version,
|
|
529
|
-
flags,
|
|
530
|
-
entryCount,
|
|
531
|
-
entries: view.readEntries(entryCount, () => ({
|
|
532
|
-
segmentDuration: view.readUint(size),
|
|
533
|
-
mediaTime: view.readInt(size),
|
|
534
|
-
mediaRateInteger: view.readInt(2),
|
|
535
|
-
mediaRateFraction: view.readInt(2)
|
|
536
|
-
}))
|
|
537
|
-
};
|
|
538
|
-
}
|
|
488
|
+
const UTF8 = "utf8";
|
|
539
489
|
|
|
540
490
|
//#endregion
|
|
541
|
-
//#region src/
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
* @param view - The IsoView to read data from
|
|
546
|
-
*
|
|
547
|
-
* @returns A parsed EventMessageBox
|
|
548
|
-
*
|
|
549
|
-
* @public
|
|
550
|
-
*/
|
|
551
|
-
function readEmsg(view) {
|
|
552
|
-
const { readUint: readUint$1, readString: readString$1, readData: readData$1 } = view;
|
|
553
|
-
const result = {
|
|
554
|
-
type: "emsg",
|
|
555
|
-
...view.readFullBox()
|
|
556
|
-
};
|
|
557
|
-
if (result.version == 1) {
|
|
558
|
-
result.timescale = readUint$1(4);
|
|
559
|
-
result.presentationTime = readUint$1(8);
|
|
560
|
-
result.eventDuration = readUint$1(4);
|
|
561
|
-
result.id = readUint$1(4);
|
|
562
|
-
result.schemeIdUri = readString$1(-1);
|
|
563
|
-
result.value = readString$1(-1);
|
|
564
|
-
} else {
|
|
565
|
-
result.schemeIdUri = readString$1(-1);
|
|
566
|
-
result.value = readString$1(-1);
|
|
567
|
-
result.timescale = readUint$1(4);
|
|
568
|
-
result.presentationTimeDelta = readUint$1(4);
|
|
569
|
-
result.eventDuration = readUint$1(4);
|
|
570
|
-
result.id = readUint$1(4);
|
|
571
|
-
}
|
|
572
|
-
result.messageData = readData$1(-1);
|
|
573
|
-
return result;
|
|
491
|
+
//#region src/utils/readData.ts
|
|
492
|
+
function readData(dataView, offset, size) {
|
|
493
|
+
const length = size > 0 ? size : dataView.byteLength - (offset - dataView.byteOffset);
|
|
494
|
+
return new Uint8Array(dataView.buffer, offset, Math.max(length, 0));
|
|
574
495
|
}
|
|
575
496
|
|
|
576
497
|
//#endregion
|
|
577
|
-
//#region src/
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
samplerate: readTemplate$1(4),
|
|
599
|
-
esds: readData$1(-1)
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
//#endregion
|
|
604
|
-
//#region src/readers/readEnca.ts
|
|
605
|
-
/**
|
|
606
|
-
* Parse an AudioSampleEntry from an IsoView
|
|
607
|
-
*
|
|
608
|
-
* @param view - The IsoView to read data from
|
|
609
|
-
*
|
|
610
|
-
* @returns A parsed AudioSampleEntry
|
|
611
|
-
*
|
|
612
|
-
* @public
|
|
613
|
-
*/
|
|
614
|
-
function readEnca(view) {
|
|
615
|
-
return {
|
|
616
|
-
...readMp4a(view),
|
|
617
|
-
type: "enca"
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
//#endregion
|
|
622
|
-
//#region src/readers/readEncv.ts
|
|
623
|
-
/**
|
|
624
|
-
* Parse a VisualSampleEntryBox from an IsoView
|
|
625
|
-
*
|
|
626
|
-
* @param view - The IsoView to read data from
|
|
627
|
-
*
|
|
628
|
-
* @returns A parsed VisualSampleEntryBox
|
|
629
|
-
*
|
|
630
|
-
* @public
|
|
631
|
-
*/
|
|
632
|
-
function readEncv(view) {
|
|
633
|
-
return {
|
|
634
|
-
...readAvc1(view),
|
|
635
|
-
type: "encv"
|
|
636
|
-
};
|
|
498
|
+
//#region src/utils/readInt.ts
|
|
499
|
+
function readInt(dataView, offset, size) {
|
|
500
|
+
let result = NaN;
|
|
501
|
+
const cursor = offset - dataView.byteOffset;
|
|
502
|
+
switch (size) {
|
|
503
|
+
case 1:
|
|
504
|
+
result = dataView.getInt8(cursor);
|
|
505
|
+
break;
|
|
506
|
+
case 2:
|
|
507
|
+
result = dataView.getInt16(cursor);
|
|
508
|
+
break;
|
|
509
|
+
case 4:
|
|
510
|
+
result = dataView.getInt32(cursor);
|
|
511
|
+
break;
|
|
512
|
+
case 8:
|
|
513
|
+
const s1 = dataView.getInt32(cursor);
|
|
514
|
+
const s2 = dataView.getInt32(cursor + 4);
|
|
515
|
+
result = s1 * Math.pow(2, 32) + s2;
|
|
516
|
+
break;
|
|
517
|
+
}
|
|
518
|
+
return result;
|
|
637
519
|
}
|
|
638
520
|
|
|
639
521
|
//#endregion
|
|
640
|
-
//#region src/
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
522
|
+
//#region src/utils/readUint.ts
|
|
523
|
+
function readUint(dataView, offset, size) {
|
|
524
|
+
const cursor = offset - dataView.byteOffset;
|
|
525
|
+
let value = NaN;
|
|
526
|
+
let s1;
|
|
527
|
+
let s2;
|
|
528
|
+
switch (size) {
|
|
529
|
+
case 1:
|
|
530
|
+
value = dataView.getUint8(cursor);
|
|
531
|
+
break;
|
|
532
|
+
case 2:
|
|
533
|
+
value = dataView.getUint16(cursor);
|
|
534
|
+
break;
|
|
535
|
+
case 3:
|
|
536
|
+
s1 = dataView.getUint16(cursor);
|
|
537
|
+
s2 = dataView.getUint8(cursor + 2);
|
|
538
|
+
value = (s1 << 8) + s2;
|
|
539
|
+
break;
|
|
540
|
+
case 4:
|
|
541
|
+
value = dataView.getUint32(cursor);
|
|
542
|
+
break;
|
|
543
|
+
case 8:
|
|
544
|
+
s1 = dataView.getUint32(cursor);
|
|
545
|
+
s2 = dataView.getUint32(cursor + 4);
|
|
546
|
+
value = s1 * Math.pow(2, 32) + s2;
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
return value;
|
|
655
550
|
}
|
|
656
551
|
|
|
657
552
|
//#endregion
|
|
658
|
-
//#region src/
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
* @public
|
|
667
|
-
*/
|
|
668
|
-
function readFrma(view) {
|
|
669
|
-
return {
|
|
670
|
-
type: "frma",
|
|
671
|
-
dataFormat: view.readUint(4)
|
|
672
|
-
};
|
|
553
|
+
//#region src/utils/readString.ts
|
|
554
|
+
function readString(dataView, offset, length) {
|
|
555
|
+
let str = "";
|
|
556
|
+
for (let c = 0; c < length; c++) {
|
|
557
|
+
const char = readUint(dataView, offset + c, 1);
|
|
558
|
+
str += String.fromCharCode(char);
|
|
559
|
+
}
|
|
560
|
+
return str;
|
|
673
561
|
}
|
|
674
562
|
|
|
675
563
|
//#endregion
|
|
676
|
-
//#region src/
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
* @public
|
|
681
|
-
*/
|
|
682
|
-
const STRING = "string";
|
|
683
|
-
|
|
684
|
-
//#endregion
|
|
685
|
-
//#region src/readers/readFtyp.ts
|
|
686
|
-
/**
|
|
687
|
-
* Parse a FileTypeBox from an IsoView
|
|
688
|
-
*
|
|
689
|
-
* @param view - The IsoView to read data from
|
|
690
|
-
*
|
|
691
|
-
* @returns A parsed FileTypeBox
|
|
692
|
-
*
|
|
693
|
-
* @public
|
|
694
|
-
*/
|
|
695
|
-
function readFtyp(view) {
|
|
696
|
-
const size = 4;
|
|
697
|
-
const majorBrand = view.readString(4);
|
|
698
|
-
const minorVersion = view.readUint(4);
|
|
699
|
-
const length = view.bytesRemaining / size;
|
|
700
|
-
return {
|
|
701
|
-
type: "ftyp",
|
|
702
|
-
majorBrand,
|
|
703
|
-
minorVersion,
|
|
704
|
-
compatibleBrands: view.readArray(STRING, size, length)
|
|
705
|
-
};
|
|
564
|
+
//#region src/utils/readTemplate.ts
|
|
565
|
+
function readTemplate(dataView, offset, size) {
|
|
566
|
+
const half = size / 2;
|
|
567
|
+
return readUint(dataView, offset, half) + readUint(dataView, offset + half, half) / Math.pow(2, half);
|
|
706
568
|
}
|
|
707
569
|
|
|
708
570
|
//#endregion
|
|
709
|
-
//#region src/
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
return {
|
|
721
|
-
type: "hdlr",
|
|
722
|
-
...view.readFullBox(),
|
|
723
|
-
preDefined: view.readUint(4),
|
|
724
|
-
handlerType: view.readString(4),
|
|
725
|
-
reserved: view.readArray(UINT, 4, 3),
|
|
726
|
-
name: view.readString(-1)
|
|
727
|
-
};
|
|
571
|
+
//#region src/utils/readTerminatedString.ts
|
|
572
|
+
function readTerminatedString(dataView, offset) {
|
|
573
|
+
let str = "";
|
|
574
|
+
let cursor = offset;
|
|
575
|
+
while (cursor - dataView.byteOffset < dataView.byteLength) {
|
|
576
|
+
const char = readUint(dataView, cursor, 1);
|
|
577
|
+
if (char === 0) break;
|
|
578
|
+
str += String.fromCharCode(char);
|
|
579
|
+
cursor++;
|
|
580
|
+
}
|
|
581
|
+
return str;
|
|
728
582
|
}
|
|
729
583
|
|
|
730
584
|
//#endregion
|
|
731
|
-
//#region src/
|
|
585
|
+
//#region src/utils/readUtf8String.ts
|
|
732
586
|
/**
|
|
733
|
-
*
|
|
734
|
-
*
|
|
735
|
-
* @param view - The IsoView to read data from
|
|
587
|
+
* Reads a UTF-8 string from a data view.
|
|
736
588
|
*
|
|
737
|
-
* @
|
|
589
|
+
* @param dataView - The data view to read from.
|
|
590
|
+
* @param offset - The offset to start reading from.
|
|
591
|
+
* @returns The UTF-8 string.
|
|
738
592
|
*
|
|
739
|
-
* @
|
|
593
|
+
* @internal
|
|
740
594
|
*/
|
|
741
|
-
function
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
type: "hev1"
|
|
745
|
-
};
|
|
595
|
+
function readUtf8String(dataView, offset) {
|
|
596
|
+
const length = dataView.byteLength - (offset - dataView.byteOffset);
|
|
597
|
+
return length > 0 ? decodeText(new DataView(dataView.buffer, offset, length), { encoding: UTF_8 }) : "";
|
|
746
598
|
}
|
|
747
599
|
|
|
748
600
|
//#endregion
|
|
749
|
-
//#region src/
|
|
601
|
+
//#region src/utils/readUtf8TerminatedString.ts
|
|
750
602
|
/**
|
|
751
|
-
*
|
|
752
|
-
*
|
|
753
|
-
* @param view - The IsoView to read data from
|
|
603
|
+
* Reads a UTF-8 terminated string from a data view.
|
|
754
604
|
*
|
|
755
|
-
* @
|
|
605
|
+
* @param dataView - The data view to read from.
|
|
606
|
+
* @param offset - The offset to start reading from.
|
|
607
|
+
* @returns The UTF-8 terminated string.
|
|
756
608
|
*
|
|
757
|
-
* @
|
|
609
|
+
* @internal
|
|
758
610
|
*/
|
|
759
|
-
function
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
611
|
+
function readUtf8TerminatedString(dataView, offset) {
|
|
612
|
+
const length = dataView.byteLength - (offset - dataView.byteOffset);
|
|
613
|
+
let data = "";
|
|
614
|
+
if (length > 0) {
|
|
615
|
+
const view = new DataView(dataView.buffer, offset, length);
|
|
616
|
+
let l = 0;
|
|
617
|
+
for (; l < length; l++) if (view.getUint8(l) === 0) break;
|
|
618
|
+
data = decodeText(new DataView(dataView.buffer, offset, l), { encoding: UTF_8 });
|
|
619
|
+
}
|
|
620
|
+
return data;
|
|
764
621
|
}
|
|
765
622
|
|
|
766
623
|
//#endregion
|
|
767
|
-
//#region src/
|
|
624
|
+
//#region src/IsoBoxReadView.ts
|
|
768
625
|
/**
|
|
769
|
-
*
|
|
770
|
-
*
|
|
771
|
-
* @param view - The IsoView to read data from
|
|
772
|
-
*
|
|
773
|
-
* @returns A parsed WebVTTCueIdBox
|
|
626
|
+
* ISO BMFF data view. Similar to DataView, but with additional methods for reading ISO BMFF data.
|
|
627
|
+
* It implements the iterator protocol, so it can be used in a for...of loop.
|
|
774
628
|
*
|
|
775
629
|
* @public
|
|
776
630
|
*/
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
631
|
+
var IsoBoxReadView = class IsoBoxReadView {
|
|
632
|
+
/**
|
|
633
|
+
* Creates a new IsoView instance. Similar to DataView, but with additional
|
|
634
|
+
* methods for reading ISO BMFF data. It implements the iterator protocol,
|
|
635
|
+
* so it can be used in a for...of loop.
|
|
636
|
+
*
|
|
637
|
+
* @param raw - The raw data to view.
|
|
638
|
+
* @param config - The configuration for the IsoView.
|
|
639
|
+
*/
|
|
640
|
+
constructor(raw, config) {
|
|
641
|
+
this.truncated = false;
|
|
642
|
+
this.slice = (offset, size) => {
|
|
643
|
+
const isoView = new IsoBoxReadView(new DataView(this.dataView.buffer, offset, size), this.config);
|
|
644
|
+
const headerSize = this.offset - offset;
|
|
645
|
+
const bodySize = size - headerSize;
|
|
646
|
+
this.offset += bodySize;
|
|
647
|
+
isoView.jump(headerSize);
|
|
648
|
+
return isoView;
|
|
649
|
+
};
|
|
650
|
+
this.read = (type, size = 0) => {
|
|
651
|
+
const { dataView, offset } = this;
|
|
652
|
+
let result;
|
|
653
|
+
let cursor = size;
|
|
654
|
+
switch (type) {
|
|
655
|
+
case UINT:
|
|
656
|
+
result = readUint(dataView, offset, size);
|
|
657
|
+
break;
|
|
658
|
+
case INT:
|
|
659
|
+
result = readInt(dataView, offset, size);
|
|
660
|
+
break;
|
|
661
|
+
case TEMPLATE:
|
|
662
|
+
result = readTemplate(dataView, offset, size);
|
|
663
|
+
break;
|
|
664
|
+
case STRING:
|
|
665
|
+
if (size === -1) {
|
|
666
|
+
result = readTerminatedString(dataView, offset);
|
|
667
|
+
cursor = result.length + 1;
|
|
668
|
+
} else result = readString(dataView, offset, size);
|
|
669
|
+
break;
|
|
670
|
+
case DATA:
|
|
671
|
+
result = readData(dataView, offset, size);
|
|
672
|
+
cursor = result.length;
|
|
673
|
+
break;
|
|
674
|
+
case UTF8:
|
|
675
|
+
if (size === -1) {
|
|
676
|
+
result = readUtf8TerminatedString(dataView, offset);
|
|
677
|
+
cursor = result.length + 1;
|
|
678
|
+
} else result = readUtf8String(dataView, offset);
|
|
679
|
+
break;
|
|
680
|
+
default: result = -1;
|
|
681
|
+
}
|
|
682
|
+
this.offset += cursor;
|
|
683
|
+
return result;
|
|
684
|
+
};
|
|
685
|
+
this.readUint = (size) => {
|
|
686
|
+
return this.read(UINT, size);
|
|
687
|
+
};
|
|
688
|
+
this.readInt = (size) => {
|
|
689
|
+
return this.read(INT, size);
|
|
690
|
+
};
|
|
691
|
+
this.readString = (size) => {
|
|
692
|
+
return this.read(STRING, size);
|
|
693
|
+
};
|
|
694
|
+
this.readTemplate = (size) => {
|
|
695
|
+
return this.read(TEMPLATE, size);
|
|
696
|
+
};
|
|
697
|
+
this.readData = (size) => {
|
|
698
|
+
return this.read(DATA, size);
|
|
699
|
+
};
|
|
700
|
+
this.readUtf8 = (size) => {
|
|
701
|
+
return this.read(UTF8, size);
|
|
702
|
+
};
|
|
703
|
+
this.readFullBox = () => {
|
|
704
|
+
return {
|
|
705
|
+
version: this.readUint(1),
|
|
706
|
+
flags: this.readUint(3)
|
|
707
|
+
};
|
|
708
|
+
};
|
|
709
|
+
this.readArray = (type, size, length) => {
|
|
710
|
+
const value = [];
|
|
711
|
+
for (let i = 0; i < length; i++) value.push(this.read(type, size));
|
|
712
|
+
return value;
|
|
713
|
+
};
|
|
714
|
+
this.jump = (size) => {
|
|
715
|
+
this.offset += size;
|
|
716
|
+
};
|
|
717
|
+
this.readBox = () => {
|
|
718
|
+
const { dataView, offset } = this;
|
|
719
|
+
let cursor = 0;
|
|
720
|
+
const size = readUint(dataView, offset, 4);
|
|
721
|
+
const type = readString(dataView, offset + 4, 4);
|
|
722
|
+
const box = {
|
|
723
|
+
size,
|
|
724
|
+
type
|
|
725
|
+
};
|
|
726
|
+
cursor += 8;
|
|
727
|
+
if (box.size === 1) {
|
|
728
|
+
box.largesize = readUint(dataView, offset + cursor, 8);
|
|
729
|
+
cursor += 8;
|
|
730
|
+
}
|
|
731
|
+
const actualSize = box.size === 0 ? this.bytesRemaining : box.largesize ?? box.size;
|
|
732
|
+
if (this.cursor + actualSize > dataView.byteLength) {
|
|
733
|
+
this.truncated = true;
|
|
734
|
+
throw new Error("Truncated box");
|
|
735
|
+
}
|
|
736
|
+
this.jump(cursor);
|
|
737
|
+
if (type === "uuid") box.usertype = this.readArray("uint", 1, 16);
|
|
738
|
+
box.view = this.slice(offset, actualSize);
|
|
739
|
+
return box;
|
|
740
|
+
};
|
|
741
|
+
this.readBoxes = (length = -1) => {
|
|
742
|
+
const result = [];
|
|
743
|
+
for (const box of this) {
|
|
744
|
+
result.push(box);
|
|
745
|
+
if (length > 0 && result.length >= length) break;
|
|
746
|
+
}
|
|
747
|
+
return result;
|
|
748
|
+
};
|
|
749
|
+
this.readEntries = (length, map) => {
|
|
750
|
+
const result = [];
|
|
751
|
+
for (let i = 0; i < length; i++) result.push(map());
|
|
752
|
+
return result;
|
|
753
|
+
};
|
|
754
|
+
this.dataView = raw instanceof ArrayBuffer ? new DataView(raw) : raw instanceof DataView ? raw : new DataView(raw.buffer, raw.byteOffset, raw.byteLength);
|
|
755
|
+
this.offset = this.dataView.byteOffset;
|
|
756
|
+
this.config = config || {};
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* The buffer of the data view.
|
|
760
|
+
*/
|
|
761
|
+
get buffer() {
|
|
762
|
+
return this.dataView.buffer;
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* The byte offset of the data view.
|
|
766
|
+
*/
|
|
767
|
+
get byteOffset() {
|
|
768
|
+
return this.dataView.byteOffset;
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* The byte length of the data view.
|
|
772
|
+
*/
|
|
773
|
+
get byteLength() {
|
|
774
|
+
return this.dataView.byteLength;
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* The current byteoffset in the data view.
|
|
778
|
+
*/
|
|
779
|
+
get cursor() {
|
|
780
|
+
return this.offset - this.dataView.byteOffset;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Whether the end of the data view has been reached.
|
|
784
|
+
*/
|
|
785
|
+
get done() {
|
|
786
|
+
return this.cursor >= this.dataView.byteLength || this.truncated;
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* The number of bytes remaining in the data view.
|
|
790
|
+
*/
|
|
791
|
+
get bytesRemaining() {
|
|
792
|
+
return this.dataView.byteLength - this.cursor;
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
* Iterates over the boxes in the data view.
|
|
796
|
+
*
|
|
797
|
+
* @returns A generator of boxes.
|
|
798
|
+
*/
|
|
799
|
+
*[Symbol.iterator]() {
|
|
800
|
+
const { readers = {} } = this.config;
|
|
801
|
+
while (!this.done) try {
|
|
802
|
+
const box = this.readBox();
|
|
803
|
+
const { type, view } = box;
|
|
804
|
+
const parser = readers[type] || readers[type.trim()];
|
|
805
|
+
if (parser) Object.assign(box, parser(view));
|
|
806
|
+
if (isContainer(box) && !box.boxes) {
|
|
807
|
+
const boxes = [];
|
|
808
|
+
for (const child of view) boxes.push(child);
|
|
809
|
+
box.boxes = boxes;
|
|
810
|
+
}
|
|
811
|
+
yield box;
|
|
812
|
+
} catch (error) {
|
|
813
|
+
if (error instanceof Error && error.message === "Truncated box") break;
|
|
814
|
+
throw error;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
|
|
819
|
+
//#endregion
|
|
820
|
+
//#region src/readIsoBoxes.ts
|
|
821
|
+
function readIsoBoxes(raw, config) {
|
|
822
|
+
const boxes = [];
|
|
823
|
+
for (const box of new IsoBoxReadView(raw, config)) boxes.push(box);
|
|
824
|
+
return boxes;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
//#endregion
|
|
828
|
+
//#region src/writeIsoBoxes.ts
|
|
829
|
+
/**
|
|
830
|
+
* Writes ISO boxes to a readable stream.
|
|
790
831
|
*
|
|
791
|
-
* @
|
|
832
|
+
* @param boxes - The boxes to write
|
|
833
|
+
* @param config - The configuration for the readable stream
|
|
834
|
+
*
|
|
835
|
+
* @returns A readable stream of the written boxes
|
|
836
|
+
*
|
|
837
|
+
* @example
|
|
838
|
+
* {@includeCode ../test/writeIsoBoxes.test.ts#example}
|
|
792
839
|
*
|
|
793
840
|
* @public
|
|
794
841
|
*/
|
|
795
|
-
function
|
|
796
|
-
return
|
|
797
|
-
type: "imda",
|
|
798
|
-
imdaIdentifier: view.readUint(4),
|
|
799
|
-
data: view.readData(-1)
|
|
800
|
-
};
|
|
842
|
+
function writeIsoBoxes(boxes, config) {
|
|
843
|
+
return writeBoxes(boxes, createWriterConfig(config));
|
|
801
844
|
}
|
|
802
845
|
|
|
803
846
|
//#endregion
|
|
804
|
-
//#region src/readers/
|
|
847
|
+
//#region src/readers/readAudioSampleEntryBox.ts
|
|
805
848
|
/**
|
|
806
|
-
* Parse a
|
|
849
|
+
* Parse a AudioSampleEntryBox from an IsoView
|
|
807
850
|
*
|
|
851
|
+
* @param type - The type of AudioSampleEntryBox to read
|
|
808
852
|
* @param view - The IsoView to read data from
|
|
809
853
|
*
|
|
810
|
-
* @returns A parsed
|
|
854
|
+
* @returns A parsed AudioSampleEntryBox
|
|
811
855
|
*
|
|
812
856
|
* @public
|
|
813
857
|
*/
|
|
814
|
-
function
|
|
858
|
+
function readAudioSampleEntryBox(type, view) {
|
|
859
|
+
const { readArray, readUint: readUint$1, readTemplate: readTemplate$1, readBoxes } = view;
|
|
815
860
|
return {
|
|
816
|
-
type
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
861
|
+
type,
|
|
862
|
+
reserved1: readArray(UINT, 1, 6),
|
|
863
|
+
dataReferenceIndex: readUint$1(2),
|
|
864
|
+
reserved2: readArray(UINT, 4, 2),
|
|
865
|
+
channelcount: readUint$1(2),
|
|
866
|
+
samplesize: readUint$1(2),
|
|
867
|
+
preDefined: readUint$1(2),
|
|
868
|
+
reserved3: readUint$1(2),
|
|
869
|
+
samplerate: readTemplate$1(4),
|
|
870
|
+
boxes: readBoxes()
|
|
820
871
|
};
|
|
821
872
|
}
|
|
822
873
|
|
|
823
874
|
//#endregion
|
|
824
|
-
//#region src/readers/
|
|
875
|
+
//#region src/readers/createAudioSampleEntryReader.ts
|
|
825
876
|
/**
|
|
826
|
-
*
|
|
877
|
+
* Creates a reader function for AudioSampleEntryBox with a custom type.
|
|
827
878
|
*
|
|
828
|
-
*
|
|
879
|
+
* This utility allows reading audio sample entry boxes with types that
|
|
880
|
+
* aren't in the standard AudioSampleEntryType union (e.g., 'mp4a', 'enca').
|
|
829
881
|
*
|
|
830
|
-
* @
|
|
882
|
+
* @param type - The 4-character box type
|
|
883
|
+
*
|
|
884
|
+
* @returns A reader function that can be passed to readIsoBoxes
|
|
885
|
+
*
|
|
886
|
+
* @example
|
|
887
|
+
* ```ts
|
|
888
|
+
* const boxes = readIsoBoxes(data, {
|
|
889
|
+
* readers: {
|
|
890
|
+
* 'ac-3': createAudioSampleEntryReader('ac-3'),
|
|
891
|
+
* 'ec-3': createAudioSampleEntryReader('ec-3'),
|
|
892
|
+
* }
|
|
893
|
+
* })
|
|
894
|
+
* ```
|
|
831
895
|
*
|
|
832
896
|
* @public
|
|
833
897
|
*/
|
|
834
|
-
function
|
|
835
|
-
|
|
836
|
-
return {
|
|
837
|
-
type: "labl",
|
|
838
|
-
version,
|
|
839
|
-
flags,
|
|
840
|
-
isGroupLabel: (flags & 1) !== 0,
|
|
841
|
-
labelId: view.readUint(2),
|
|
842
|
-
language: view.readUtf8(-1),
|
|
843
|
-
label: view.readUtf8(-1)
|
|
844
|
-
};
|
|
898
|
+
function createAudioSampleEntryReader(type) {
|
|
899
|
+
return (view) => readAudioSampleEntryBox(type, view);
|
|
845
900
|
}
|
|
846
901
|
|
|
847
902
|
//#endregion
|
|
848
|
-
//#region src/readers/
|
|
903
|
+
//#region src/readers/readVisualSampleEntryBox.ts
|
|
849
904
|
/**
|
|
850
|
-
* Parse a
|
|
905
|
+
* Parse a VisualSampleEntryBox from an IsoView
|
|
851
906
|
*
|
|
907
|
+
* @param type - The type of VisualSampleEntryBox to read
|
|
852
908
|
* @param view - The IsoView to read data from
|
|
853
909
|
*
|
|
854
|
-
* @returns A parsed
|
|
910
|
+
* @returns A parsed VisualSampleEntryBox
|
|
855
911
|
*
|
|
856
912
|
* @public
|
|
857
913
|
*/
|
|
858
|
-
function
|
|
914
|
+
function readVisualSampleEntryBox(type, view) {
|
|
915
|
+
const { readArray, readUint: readUint$1, readInt: readInt$1, readTemplate: readTemplate$1, readBoxes } = view;
|
|
859
916
|
return {
|
|
860
|
-
type
|
|
861
|
-
|
|
917
|
+
type,
|
|
918
|
+
reserved1: readArray(UINT, 1, 6),
|
|
919
|
+
dataReferenceIndex: readUint$1(2),
|
|
920
|
+
preDefined1: readUint$1(2),
|
|
921
|
+
reserved2: readUint$1(2),
|
|
922
|
+
preDefined2: readArray(UINT, 4, 3),
|
|
923
|
+
width: readUint$1(2),
|
|
924
|
+
height: readUint$1(2),
|
|
925
|
+
horizresolution: readTemplate$1(4),
|
|
926
|
+
vertresolution: readTemplate$1(4),
|
|
927
|
+
reserved3: readUint$1(4),
|
|
928
|
+
frameCount: readUint$1(2),
|
|
929
|
+
compressorName: readArray(UINT, 1, 32),
|
|
930
|
+
depth: readUint$1(2),
|
|
931
|
+
preDefined3: readInt$1(2),
|
|
932
|
+
boxes: readBoxes()
|
|
862
933
|
};
|
|
863
934
|
}
|
|
864
935
|
|
|
865
936
|
//#endregion
|
|
866
|
-
//#region src/readers/
|
|
937
|
+
//#region src/readers/createVisualSampleEntryReader.ts
|
|
867
938
|
/**
|
|
868
|
-
*
|
|
939
|
+
* Creates a reader function for VisualSampleEntryBox with a custom type.
|
|
869
940
|
*
|
|
870
|
-
*
|
|
941
|
+
* This utility allows reading visual sample entry boxes with types that
|
|
942
|
+
* aren't in the standard VisualSampleEntryType union (e.g., 'avc1', 'hvc1').
|
|
871
943
|
*
|
|
872
|
-
* @
|
|
944
|
+
* @param type - The 4-character box type
|
|
945
|
+
*
|
|
946
|
+
* @returns A reader function that can be passed to readIsoBoxes
|
|
947
|
+
*
|
|
948
|
+
* @example
|
|
949
|
+
* ```ts
|
|
950
|
+
* const boxes = readIsoBoxes(data, {
|
|
951
|
+
* readers: {
|
|
952
|
+
* 'vp09': createVisualSampleEntryReader('vp09'),
|
|
953
|
+
* 'av01': createVisualSampleEntryReader('av01'),
|
|
954
|
+
* }
|
|
955
|
+
* })
|
|
956
|
+
* ```
|
|
873
957
|
*
|
|
874
958
|
* @public
|
|
875
959
|
*/
|
|
876
|
-
function
|
|
877
|
-
|
|
878
|
-
const creationTime = view.readUint(version == 1 ? 8 : 4);
|
|
879
|
-
const modificationTime = view.readUint(version == 1 ? 8 : 4);
|
|
880
|
-
const timescale = view.readUint(4);
|
|
881
|
-
const duration = view.readUint(version == 1 ? 8 : 4);
|
|
882
|
-
const lang = view.readUint(2);
|
|
883
|
-
return {
|
|
884
|
-
type: "mdhd",
|
|
885
|
-
version,
|
|
886
|
-
flags,
|
|
887
|
-
creationTime,
|
|
888
|
-
modificationTime,
|
|
889
|
-
timescale,
|
|
890
|
-
duration,
|
|
891
|
-
language: String.fromCharCode((lang >> 10 & 31) + 96, (lang >> 5 & 31) + 96, (lang & 31) + 96),
|
|
892
|
-
preDefined: view.readUint(2)
|
|
893
|
-
};
|
|
960
|
+
function createVisualSampleEntryReader(type) {
|
|
961
|
+
return (view) => readVisualSampleEntryBox(type, view);
|
|
894
962
|
}
|
|
895
963
|
|
|
896
964
|
//#endregion
|
|
897
|
-
//#region src/readers/
|
|
965
|
+
//#region src/readers/readArdi.ts
|
|
898
966
|
/**
|
|
899
|
-
* Parse a
|
|
967
|
+
* Parse a AudioRenderingIndicationBox from an IsoView
|
|
900
968
|
*
|
|
901
969
|
* @param view - The IsoView to read data from
|
|
902
970
|
*
|
|
903
|
-
* @returns A parsed
|
|
971
|
+
* @returns A parsed AudioRenderingIndicationBox
|
|
904
972
|
*
|
|
905
973
|
* @public
|
|
906
974
|
*/
|
|
907
|
-
function
|
|
908
|
-
const { version, flags } = view.readFullBox();
|
|
975
|
+
function readArdi(view) {
|
|
909
976
|
return {
|
|
910
|
-
type: "
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
fragmentDuration: view.readUint(version === 1 ? 8 : 4)
|
|
977
|
+
type: "ardi",
|
|
978
|
+
...view.readFullBox(),
|
|
979
|
+
audioRenderingIndication: view.readUint(1)
|
|
914
980
|
};
|
|
915
981
|
}
|
|
916
982
|
|
|
917
983
|
//#endregion
|
|
918
|
-
//#region src/readers/
|
|
984
|
+
//#region src/readers/readAvc1.ts
|
|
919
985
|
/**
|
|
920
|
-
* Parse a
|
|
986
|
+
* Parse a VisualSampleEntryBox from an IsoView
|
|
921
987
|
*
|
|
922
988
|
* @param view - The IsoView to read data from
|
|
923
989
|
*
|
|
924
|
-
* @returns A parsed
|
|
990
|
+
* @returns A parsed VisualSampleEntryBox
|
|
925
991
|
*
|
|
926
992
|
* @public
|
|
927
993
|
*/
|
|
928
|
-
function
|
|
929
|
-
return
|
|
930
|
-
type: "meta",
|
|
931
|
-
...view.readFullBox(),
|
|
932
|
-
boxes: view.readBoxes()
|
|
933
|
-
};
|
|
994
|
+
function readAvc1(view) {
|
|
995
|
+
return readVisualSampleEntryBox("avc1", view);
|
|
934
996
|
}
|
|
935
997
|
|
|
936
998
|
//#endregion
|
|
937
|
-
//#region src/readers/
|
|
999
|
+
//#region src/readers/readAvc2.ts
|
|
938
1000
|
/**
|
|
939
|
-
* Parse a
|
|
1001
|
+
* Parse a VisualSampleEntryBox from an IsoView
|
|
940
1002
|
*
|
|
941
1003
|
* @param view - The IsoView to read data from
|
|
942
1004
|
*
|
|
943
|
-
* @returns A parsed
|
|
1005
|
+
* @returns A parsed VisualSampleEntryBox
|
|
944
1006
|
*
|
|
945
1007
|
* @public
|
|
946
1008
|
*/
|
|
947
|
-
function
|
|
948
|
-
return
|
|
949
|
-
type: "mfhd",
|
|
950
|
-
...view.readFullBox(),
|
|
951
|
-
sequenceNumber: view.readUint(4)
|
|
952
|
-
};
|
|
1009
|
+
function readAvc2(view) {
|
|
1010
|
+
return readVisualSampleEntryBox("avc2", view);
|
|
953
1011
|
}
|
|
954
1012
|
|
|
955
1013
|
//#endregion
|
|
956
|
-
//#region src/readers/
|
|
1014
|
+
//#region src/readers/readAvc3.ts
|
|
957
1015
|
/**
|
|
958
|
-
* Parse a
|
|
1016
|
+
* Parse a VisualSampleEntryBox from an IsoView
|
|
959
1017
|
*
|
|
960
1018
|
* @param view - The IsoView to read data from
|
|
961
1019
|
*
|
|
962
|
-
* @returns A parsed
|
|
1020
|
+
* @returns A parsed VisualSampleEntryBox
|
|
963
1021
|
*
|
|
964
1022
|
* @public
|
|
965
1023
|
*/
|
|
966
|
-
function
|
|
967
|
-
return
|
|
968
|
-
type: "mfro",
|
|
969
|
-
...view.readFullBox(),
|
|
970
|
-
mfraSize: view.readUint(4)
|
|
971
|
-
};
|
|
1024
|
+
function readAvc3(view) {
|
|
1025
|
+
return readVisualSampleEntryBox("avc3", view);
|
|
972
1026
|
}
|
|
973
1027
|
|
|
974
1028
|
//#endregion
|
|
975
|
-
//#region src/readers/
|
|
1029
|
+
//#region src/readers/readAvc4.ts
|
|
976
1030
|
/**
|
|
977
|
-
* Parse a
|
|
1031
|
+
* Parse a VisualSampleEntryBox from an IsoView
|
|
978
1032
|
*
|
|
979
1033
|
* @param view - The IsoView to read data from
|
|
980
1034
|
*
|
|
981
|
-
* @returns A parsed
|
|
1035
|
+
* @returns A parsed VisualSampleEntryBox
|
|
982
1036
|
*
|
|
983
1037
|
* @public
|
|
984
1038
|
*/
|
|
985
|
-
function
|
|
986
|
-
|
|
987
|
-
const { version, flags } = view.readFullBox();
|
|
988
|
-
const size = version == 1 ? 8 : 4;
|
|
989
|
-
return {
|
|
990
|
-
type: "mvhd",
|
|
991
|
-
version,
|
|
992
|
-
flags,
|
|
993
|
-
creationTime: readUint$1(size),
|
|
994
|
-
modificationTime: readUint$1(size),
|
|
995
|
-
timescale: readUint$1(4),
|
|
996
|
-
duration: readUint$1(size),
|
|
997
|
-
rate: readTemplate$1(4),
|
|
998
|
-
volume: readTemplate$1(2),
|
|
999
|
-
reserved1: readUint$1(2),
|
|
1000
|
-
reserved2: readArray(UINT, 4, 2),
|
|
1001
|
-
matrix: readArray(TEMPLATE, 4, 9),
|
|
1002
|
-
preDefined: readArray(UINT, 4, 6),
|
|
1003
|
-
nextTrackId: readUint$1(4)
|
|
1004
|
-
};
|
|
1039
|
+
function readAvc4(view) {
|
|
1040
|
+
return readVisualSampleEntryBox("avc4", view);
|
|
1005
1041
|
}
|
|
1006
1042
|
|
|
1007
1043
|
//#endregion
|
|
1008
|
-
//#region src/readers/
|
|
1044
|
+
//#region src/readers/readCtts.ts
|
|
1009
1045
|
/**
|
|
1010
|
-
* Parse a
|
|
1046
|
+
* Parse a CompositionTimeToSampleBox from an IsoView
|
|
1011
1047
|
*
|
|
1012
1048
|
* @param view - The IsoView to read data from
|
|
1013
1049
|
*
|
|
1014
|
-
* @returns A parsed
|
|
1050
|
+
* @returns A parsed CompositionTimeToSampleBox
|
|
1015
1051
|
*
|
|
1016
1052
|
* @public
|
|
1017
1053
|
*/
|
|
1018
|
-
function
|
|
1054
|
+
function readCtts(view) {
|
|
1055
|
+
const { version, flags } = view.readFullBox();
|
|
1056
|
+
const read = version === 1 ? view.readInt : view.readUint;
|
|
1057
|
+
const entryCount = view.readUint(4);
|
|
1019
1058
|
return {
|
|
1020
|
-
type: "
|
|
1021
|
-
|
|
1059
|
+
type: "ctts",
|
|
1060
|
+
version,
|
|
1061
|
+
flags,
|
|
1062
|
+
entryCount,
|
|
1063
|
+
entries: view.readEntries(entryCount, () => ({
|
|
1064
|
+
sampleCount: view.readUint(4),
|
|
1065
|
+
sampleOffset: read(4)
|
|
1066
|
+
}))
|
|
1022
1067
|
};
|
|
1023
1068
|
}
|
|
1024
1069
|
|
|
1025
1070
|
//#endregion
|
|
1026
|
-
//#region src/readers/
|
|
1071
|
+
//#region src/readers/readDref.ts
|
|
1027
1072
|
/**
|
|
1028
|
-
* Parse a
|
|
1073
|
+
* Parse a DataReferenceBox from an IsoView
|
|
1029
1074
|
*
|
|
1030
1075
|
* @param view - The IsoView to read data from
|
|
1031
1076
|
*
|
|
1032
|
-
* @returns A parsed
|
|
1077
|
+
* @returns A parsed DataReferenceBox
|
|
1033
1078
|
*
|
|
1034
1079
|
* @public
|
|
1035
1080
|
*/
|
|
1036
|
-
function
|
|
1081
|
+
function readDref(view) {
|
|
1037
1082
|
const { version, flags } = view.readFullBox();
|
|
1083
|
+
const entryCount = view.readUint(4);
|
|
1038
1084
|
return {
|
|
1039
|
-
type: "
|
|
1085
|
+
type: "dref",
|
|
1040
1086
|
version,
|
|
1041
1087
|
flags,
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
ntpTimestampFrac: view.readUint(4),
|
|
1045
|
-
mediaTime: view.readUint(version === 1 ? 8 : 4)
|
|
1088
|
+
entryCount,
|
|
1089
|
+
entries: view.readBoxes(entryCount)
|
|
1046
1090
|
};
|
|
1047
1091
|
}
|
|
1048
1092
|
|
|
1049
1093
|
//#endregion
|
|
1050
|
-
//#region src/readers/
|
|
1094
|
+
//#region src/readers/readElng.ts
|
|
1051
1095
|
/**
|
|
1052
|
-
* Parse a
|
|
1096
|
+
* Parse a ExtendedLanguageBox from an IsoView
|
|
1053
1097
|
*
|
|
1054
1098
|
* @param view - The IsoView to read data from
|
|
1055
1099
|
*
|
|
1056
|
-
* @returns A parsed
|
|
1100
|
+
* @returns A parsed ExtendedLanguageBox
|
|
1057
1101
|
*
|
|
1058
1102
|
* @public
|
|
1059
1103
|
*/
|
|
1060
|
-
function
|
|
1061
|
-
const { version, flags } = view.readFullBox();
|
|
1062
|
-
const groupId = view.readUint(4);
|
|
1063
|
-
const numEntitiesInGroup = view.readUint(4);
|
|
1104
|
+
function readElng(view) {
|
|
1064
1105
|
return {
|
|
1065
|
-
type: "
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
groupId,
|
|
1069
|
-
numEntitiesInGroup,
|
|
1070
|
-
entities: view.readEntries(numEntitiesInGroup, () => ({ entityId: view.readUint(4) })),
|
|
1071
|
-
preselectionTag: flags & 4096 ? view.readUtf8(-1) : void 0,
|
|
1072
|
-
selectionPriority: flags & 8192 ? view.readUint(1) : void 0,
|
|
1073
|
-
interleavingTag: flags & 16384 ? view.readUtf8(-1) : void 0
|
|
1106
|
+
type: "elng",
|
|
1107
|
+
...view.readFullBox(),
|
|
1108
|
+
extendedLanguage: view.readUtf8(-1)
|
|
1074
1109
|
};
|
|
1075
1110
|
}
|
|
1076
1111
|
|
|
1077
1112
|
//#endregion
|
|
1078
|
-
//#region src/readers/
|
|
1113
|
+
//#region src/readers/readElst.ts
|
|
1079
1114
|
/**
|
|
1080
|
-
* Parse a
|
|
1115
|
+
* Parse a Box from an IsoView
|
|
1081
1116
|
*
|
|
1082
1117
|
* @param view - The IsoView to read data from
|
|
1083
1118
|
*
|
|
1084
|
-
* @returns A parsed
|
|
1119
|
+
* @returns A parsed Box
|
|
1085
1120
|
*
|
|
1086
1121
|
* @public
|
|
1087
1122
|
*/
|
|
1088
|
-
function
|
|
1089
|
-
const { readUint: readUint$1, readArray } = view;
|
|
1123
|
+
function readElst(view) {
|
|
1090
1124
|
const { version, flags } = view.readFullBox();
|
|
1091
|
-
const
|
|
1092
|
-
|
|
1093
|
-
let kid = [];
|
|
1094
|
-
if (version > 0) {
|
|
1095
|
-
kidCount = readUint$1(4);
|
|
1096
|
-
kid = readArray(UINT, 1, kidCount);
|
|
1097
|
-
}
|
|
1098
|
-
const dataSize = readUint$1(4);
|
|
1099
|
-
const data = readArray(UINT, 1, dataSize);
|
|
1125
|
+
const size = version === 1 ? 8 : 4;
|
|
1126
|
+
const entryCount = view.readUint(4);
|
|
1100
1127
|
return {
|
|
1101
|
-
type: "
|
|
1128
|
+
type: "elst",
|
|
1102
1129
|
version,
|
|
1103
1130
|
flags,
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1131
|
+
entryCount,
|
|
1132
|
+
entries: view.readEntries(entryCount, () => ({
|
|
1133
|
+
segmentDuration: view.readUint(size),
|
|
1134
|
+
mediaTime: view.readInt(size),
|
|
1135
|
+
mediaRateInteger: view.readInt(2),
|
|
1136
|
+
mediaRateFraction: view.readInt(2)
|
|
1137
|
+
}))
|
|
1109
1138
|
};
|
|
1110
1139
|
}
|
|
1111
1140
|
|
|
1112
1141
|
//#endregion
|
|
1113
|
-
//#region src/readers/
|
|
1142
|
+
//#region src/readers/readEmsg.ts
|
|
1114
1143
|
/**
|
|
1115
|
-
* Parse
|
|
1144
|
+
* Parse an EventMessageBox from an IsoView
|
|
1116
1145
|
*
|
|
1117
1146
|
* @param view - The IsoView to read data from
|
|
1118
1147
|
*
|
|
1119
|
-
* @returns A parsed
|
|
1148
|
+
* @returns A parsed EventMessageBox
|
|
1120
1149
|
*
|
|
1121
1150
|
* @public
|
|
1122
1151
|
*/
|
|
1123
|
-
function
|
|
1124
|
-
const {
|
|
1125
|
-
|
|
1126
|
-
type: "
|
|
1127
|
-
|
|
1128
|
-
flags,
|
|
1129
|
-
schemeType: view.readUint(4),
|
|
1130
|
-
schemeVersion: view.readUint(4),
|
|
1131
|
-
schemeUri: flags & 1 ? view.readString(-1) : void 0
|
|
1152
|
+
function readEmsg(view) {
|
|
1153
|
+
const { readUint: readUint$1, readString: readString$1, readData: readData$1 } = view;
|
|
1154
|
+
const result = {
|
|
1155
|
+
type: "emsg",
|
|
1156
|
+
...view.readFullBox()
|
|
1132
1157
|
};
|
|
1158
|
+
if (result.version == 1) {
|
|
1159
|
+
result.timescale = readUint$1(4);
|
|
1160
|
+
result.presentationTime = readUint$1(8);
|
|
1161
|
+
result.eventDuration = readUint$1(4);
|
|
1162
|
+
result.id = readUint$1(4);
|
|
1163
|
+
result.schemeIdUri = readString$1(-1);
|
|
1164
|
+
result.value = readString$1(-1);
|
|
1165
|
+
} else {
|
|
1166
|
+
result.schemeIdUri = readString$1(-1);
|
|
1167
|
+
result.value = readString$1(-1);
|
|
1168
|
+
result.timescale = readUint$1(4);
|
|
1169
|
+
result.presentationTimeDelta = readUint$1(4);
|
|
1170
|
+
result.eventDuration = readUint$1(4);
|
|
1171
|
+
result.id = readUint$1(4);
|
|
1172
|
+
}
|
|
1173
|
+
result.messageData = readData$1(-1);
|
|
1174
|
+
return result;
|
|
1133
1175
|
}
|
|
1134
1176
|
|
|
1135
1177
|
//#endregion
|
|
1136
|
-
//#region src/readers/
|
|
1178
|
+
//#region src/readers/readEnca.ts
|
|
1137
1179
|
/**
|
|
1138
|
-
* Parse
|
|
1180
|
+
* Parse an AudioSampleEntry from an IsoView
|
|
1139
1181
|
*
|
|
1140
1182
|
* @param view - The IsoView to read data from
|
|
1141
1183
|
*
|
|
1142
|
-
* @returns A parsed
|
|
1184
|
+
* @returns A parsed AudioSampleEntry
|
|
1143
1185
|
*
|
|
1144
1186
|
* @public
|
|
1145
1187
|
*/
|
|
1146
|
-
function
|
|
1147
|
-
return
|
|
1148
|
-
type: "sdtp",
|
|
1149
|
-
...view.readFullBox(),
|
|
1150
|
-
sampleDependencyTable: view.readArray(UINT, 1, view.bytesRemaining)
|
|
1151
|
-
};
|
|
1188
|
+
function readEnca(view) {
|
|
1189
|
+
return readAudioSampleEntryBox("enca", view);
|
|
1152
1190
|
}
|
|
1153
1191
|
|
|
1154
1192
|
//#endregion
|
|
1155
|
-
//#region src/readers/
|
|
1193
|
+
//#region src/readers/readEncv.ts
|
|
1156
1194
|
/**
|
|
1157
|
-
* Parse a
|
|
1195
|
+
* Parse a VisualSampleEntryBox from an IsoView
|
|
1158
1196
|
*
|
|
1159
1197
|
* @param view - The IsoView to read data from
|
|
1160
1198
|
*
|
|
1161
|
-
* @returns A parsed
|
|
1199
|
+
* @returns A parsed VisualSampleEntryBox
|
|
1162
1200
|
*
|
|
1163
1201
|
* @public
|
|
1164
1202
|
*/
|
|
1165
|
-
function
|
|
1166
|
-
|
|
1167
|
-
const { version, flags } = view.readFullBox();
|
|
1168
|
-
const size = version === 1 ? 8 : 4;
|
|
1169
|
-
const referenceId = readUint$1(4);
|
|
1170
|
-
const timescale = readUint$1(4);
|
|
1171
|
-
const earliestPresentationTime = readUint$1(size);
|
|
1172
|
-
const firstOffset = readUint$1(size);
|
|
1173
|
-
const reserved = readUint$1(2);
|
|
1174
|
-
const referenceCount = readUint$1(2);
|
|
1175
|
-
return {
|
|
1176
|
-
type: "sidx",
|
|
1177
|
-
version,
|
|
1178
|
-
flags,
|
|
1179
|
-
referenceId,
|
|
1180
|
-
timescale,
|
|
1181
|
-
earliestPresentationTime,
|
|
1182
|
-
firstOffset,
|
|
1183
|
-
reserved,
|
|
1184
|
-
references: view.readEntries(referenceCount, () => {
|
|
1185
|
-
const entry = {};
|
|
1186
|
-
entry.reference = readUint$1(4);
|
|
1187
|
-
entry.subsegmentDuration = readUint$1(4);
|
|
1188
|
-
entry.sap = readUint$1(4);
|
|
1189
|
-
entry.referenceType = entry.reference >> 31 & 1;
|
|
1190
|
-
entry.referencedSize = entry.reference & 2147483647;
|
|
1191
|
-
entry.startsWithSap = entry.sap >> 31 & 1;
|
|
1192
|
-
entry.sapType = entry.sap >> 28 & 7;
|
|
1193
|
-
entry.sapDeltaTime = entry.sap & 268435455;
|
|
1194
|
-
return entry;
|
|
1195
|
-
})
|
|
1196
|
-
};
|
|
1203
|
+
function readEncv(view) {
|
|
1204
|
+
return readVisualSampleEntryBox("encv", view);
|
|
1197
1205
|
}
|
|
1198
1206
|
|
|
1199
1207
|
//#endregion
|
|
1200
|
-
//#region src/readers/
|
|
1208
|
+
//#region src/readers/readFree.ts
|
|
1201
1209
|
/**
|
|
1202
|
-
* Parse a
|
|
1210
|
+
* Parse a Box from an IsoView
|
|
1203
1211
|
*
|
|
1204
1212
|
* @param view - The IsoView to read data from
|
|
1205
1213
|
*
|
|
1206
|
-
* @returns A parsed
|
|
1214
|
+
* @returns A parsed Box
|
|
1207
1215
|
*
|
|
1208
1216
|
* @public
|
|
1209
1217
|
*/
|
|
1210
|
-
function
|
|
1218
|
+
function readFree(view) {
|
|
1211
1219
|
return {
|
|
1212
|
-
|
|
1213
|
-
|
|
1220
|
+
type: "free",
|
|
1221
|
+
data: view.readData(-1)
|
|
1214
1222
|
};
|
|
1215
1223
|
}
|
|
1216
1224
|
|
|
1217
1225
|
//#endregion
|
|
1218
|
-
//#region src/readers/
|
|
1226
|
+
//#region src/readers/readFrma.ts
|
|
1219
1227
|
/**
|
|
1220
|
-
* Parse
|
|
1228
|
+
* Parse an OriginalFormatBox from an IsoView
|
|
1221
1229
|
*
|
|
1222
1230
|
* @param view - The IsoView to read data from
|
|
1223
1231
|
*
|
|
1224
|
-
* @returns A parsed
|
|
1232
|
+
* @returns A parsed OriginalFormatBox
|
|
1225
1233
|
*
|
|
1226
1234
|
* @public
|
|
1227
1235
|
*/
|
|
1228
|
-
function
|
|
1236
|
+
function readFrma(view) {
|
|
1229
1237
|
return {
|
|
1230
|
-
type: "
|
|
1231
|
-
|
|
1232
|
-
balance: view.readUint(2),
|
|
1233
|
-
reserved: view.readUint(2)
|
|
1238
|
+
type: "frma",
|
|
1239
|
+
dataFormat: view.readUint(4)
|
|
1234
1240
|
};
|
|
1235
1241
|
}
|
|
1236
1242
|
|
|
1237
1243
|
//#endregion
|
|
1238
|
-
//#region src/readers/
|
|
1244
|
+
//#region src/readers/readFtyp.ts
|
|
1239
1245
|
/**
|
|
1240
|
-
* Parse a
|
|
1246
|
+
* Parse a FileTypeBox from an IsoView
|
|
1241
1247
|
*
|
|
1242
1248
|
* @param view - The IsoView to read data from
|
|
1243
1249
|
*
|
|
1244
|
-
* @returns A parsed
|
|
1250
|
+
* @returns A parsed FileTypeBox
|
|
1245
1251
|
*
|
|
1246
1252
|
* @public
|
|
1247
1253
|
*/
|
|
1248
|
-
function
|
|
1249
|
-
const
|
|
1250
|
-
const
|
|
1254
|
+
function readFtyp(view) {
|
|
1255
|
+
const size = 4;
|
|
1256
|
+
const majorBrand = view.readString(4);
|
|
1257
|
+
const minorVersion = view.readUint(4);
|
|
1258
|
+
const length = view.bytesRemaining / size;
|
|
1251
1259
|
return {
|
|
1252
|
-
type: "
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
subsegments: view.readEntries(subsegmentCount, () => {
|
|
1257
|
-
const rangesCount = view.readUint(4);
|
|
1258
|
-
return {
|
|
1259
|
-
rangesCount,
|
|
1260
|
-
ranges: view.readEntries(rangesCount, () => ({
|
|
1261
|
-
level: view.readUint(1),
|
|
1262
|
-
rangeSize: view.readUint(3)
|
|
1263
|
-
}))
|
|
1264
|
-
};
|
|
1265
|
-
})
|
|
1260
|
+
type: "ftyp",
|
|
1261
|
+
majorBrand,
|
|
1262
|
+
minorVersion,
|
|
1263
|
+
compatibleBrands: view.readArray(STRING, size, length)
|
|
1266
1264
|
};
|
|
1267
1265
|
}
|
|
1268
1266
|
|
|
1269
1267
|
//#endregion
|
|
1270
|
-
//#region src/readers/
|
|
1268
|
+
//#region src/readers/readHdlr.ts
|
|
1271
1269
|
/**
|
|
1272
|
-
* Parse a
|
|
1270
|
+
* Parse a HandlerReferenceBox from an IsoView
|
|
1273
1271
|
*
|
|
1274
1272
|
* @param view - The IsoView to read data from
|
|
1275
1273
|
*
|
|
1276
|
-
* @returns A parsed
|
|
1274
|
+
* @returns A parsed HandlerReferenceBox
|
|
1277
1275
|
*
|
|
1278
1276
|
* @public
|
|
1279
1277
|
*/
|
|
1280
|
-
function
|
|
1278
|
+
function readHdlr(view) {
|
|
1281
1279
|
return {
|
|
1282
|
-
type: "
|
|
1283
|
-
...view.readFullBox()
|
|
1280
|
+
type: "hdlr",
|
|
1281
|
+
...view.readFullBox(),
|
|
1282
|
+
preDefined: view.readUint(4),
|
|
1283
|
+
handlerType: view.readString(4),
|
|
1284
|
+
reserved: view.readArray(UINT, 4, 3),
|
|
1285
|
+
name: view.readString(-1)
|
|
1284
1286
|
};
|
|
1285
1287
|
}
|
|
1286
1288
|
|
|
1287
1289
|
//#endregion
|
|
1288
|
-
//#region src/readers/
|
|
1290
|
+
//#region src/readers/readHev1.ts
|
|
1289
1291
|
/**
|
|
1290
|
-
* Parse a
|
|
1292
|
+
* Parse a VisualSampleEntryBox from an IsoView
|
|
1291
1293
|
*
|
|
1292
1294
|
* @param view - The IsoView to read data from
|
|
1293
1295
|
*
|
|
1294
|
-
* @returns A parsed
|
|
1296
|
+
* @returns A parsed VisualSampleEntryBox
|
|
1295
1297
|
*
|
|
1296
1298
|
* @public
|
|
1297
1299
|
*/
|
|
1298
|
-
function
|
|
1299
|
-
|
|
1300
|
-
const entryCount = view.readUint(4);
|
|
1301
|
-
return {
|
|
1302
|
-
type: "stsd",
|
|
1303
|
-
version,
|
|
1304
|
-
flags,
|
|
1305
|
-
entryCount,
|
|
1306
|
-
entries: view.readBoxes(entryCount)
|
|
1307
|
-
};
|
|
1300
|
+
function readHev1(view) {
|
|
1301
|
+
return readVisualSampleEntryBox("hev1", view);
|
|
1308
1302
|
}
|
|
1309
1303
|
|
|
1310
1304
|
//#endregion
|
|
1311
|
-
//#region src/readers/
|
|
1305
|
+
//#region src/readers/readHvc1.ts
|
|
1312
1306
|
/**
|
|
1313
|
-
* Parse a
|
|
1307
|
+
* Parse a VisualSampleEntryBox from an IsoView
|
|
1314
1308
|
*
|
|
1315
1309
|
* @param view - The IsoView to read data from
|
|
1316
1310
|
*
|
|
1317
|
-
* @returns A parsed
|
|
1311
|
+
* @returns A parsed VisualSampleEntryBox
|
|
1318
1312
|
*
|
|
1319
1313
|
* @public
|
|
1320
1314
|
*/
|
|
1321
|
-
function
|
|
1322
|
-
|
|
1323
|
-
const entryCount = view.readUint(4);
|
|
1324
|
-
return {
|
|
1325
|
-
type: "stss",
|
|
1326
|
-
version,
|
|
1327
|
-
flags,
|
|
1328
|
-
entryCount,
|
|
1329
|
-
entries: view.readEntries(entryCount, () => ({ sampleNumber: view.readUint(4) }))
|
|
1330
|
-
};
|
|
1315
|
+
function readHvc1(view) {
|
|
1316
|
+
return readVisualSampleEntryBox("hvc1", view);
|
|
1331
1317
|
}
|
|
1332
1318
|
|
|
1333
1319
|
//#endregion
|
|
1334
|
-
//#region src/readers/
|
|
1320
|
+
//#region src/readers/readIden.ts
|
|
1335
1321
|
/**
|
|
1336
|
-
* Parse a
|
|
1322
|
+
* Parse a WebVTTCueIdBox from an IsoView
|
|
1337
1323
|
*
|
|
1338
1324
|
* @param view - The IsoView to read data from
|
|
1339
1325
|
*
|
|
1340
|
-
* @returns A parsed
|
|
1326
|
+
* @returns A parsed WebVTTCueIdBox
|
|
1341
1327
|
*
|
|
1342
1328
|
* @public
|
|
1343
1329
|
*/
|
|
1344
|
-
function
|
|
1330
|
+
function readIden(view) {
|
|
1345
1331
|
return {
|
|
1346
|
-
type: "
|
|
1347
|
-
|
|
1332
|
+
type: "iden",
|
|
1333
|
+
cueId: view.readUtf8(-1)
|
|
1348
1334
|
};
|
|
1349
1335
|
}
|
|
1350
1336
|
|
|
1351
1337
|
//#endregion
|
|
1352
|
-
//#region src/readers/
|
|
1338
|
+
//#region src/readers/readImda.ts
|
|
1353
1339
|
/**
|
|
1354
|
-
* Parse a
|
|
1340
|
+
* Parse a IdentifiedMediaDataBox from an IsoView
|
|
1355
1341
|
*
|
|
1356
1342
|
* @param view - The IsoView to read data from
|
|
1357
1343
|
*
|
|
1358
|
-
* @returns A parsed
|
|
1344
|
+
* @returns A parsed IdentifiedMediaDataBox
|
|
1359
1345
|
*
|
|
1360
1346
|
* @public
|
|
1361
1347
|
*/
|
|
1362
|
-
function
|
|
1363
|
-
const { version, flags } = view.readFullBox();
|
|
1364
|
-
const entryCount = view.readUint(4);
|
|
1348
|
+
function readImda(view) {
|
|
1365
1349
|
return {
|
|
1366
|
-
type: "
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
entryCount,
|
|
1370
|
-
entries: view.readEntries(entryCount, () => ({
|
|
1371
|
-
sampleCount: view.readUint(4),
|
|
1372
|
-
sampleDelta: view.readUint(4)
|
|
1373
|
-
}))
|
|
1350
|
+
type: "imda",
|
|
1351
|
+
imdaIdentifier: view.readUint(4),
|
|
1352
|
+
data: view.readData(-1)
|
|
1374
1353
|
};
|
|
1375
1354
|
}
|
|
1376
1355
|
|
|
1377
1356
|
//#endregion
|
|
1378
|
-
//#region src/readers/
|
|
1357
|
+
//#region src/readers/readKind.ts
|
|
1379
1358
|
/**
|
|
1380
|
-
* Parse a
|
|
1359
|
+
* Parse a TrackKinBox from an IsoView
|
|
1381
1360
|
*
|
|
1382
1361
|
* @param view - The IsoView to read data from
|
|
1383
1362
|
*
|
|
1384
|
-
* @returns A parsed
|
|
1363
|
+
* @returns A parsed TrackKindBox
|
|
1385
1364
|
*
|
|
1386
1365
|
* @public
|
|
1387
1366
|
*/
|
|
1388
|
-
function
|
|
1367
|
+
function readKind(view) {
|
|
1389
1368
|
return {
|
|
1390
|
-
|
|
1391
|
-
|
|
1369
|
+
type: "kind",
|
|
1370
|
+
...view.readFullBox(),
|
|
1371
|
+
schemeUri: view.readUtf8(-1),
|
|
1372
|
+
value: view.readUtf8(-1)
|
|
1392
1373
|
};
|
|
1393
1374
|
}
|
|
1394
1375
|
|
|
1395
1376
|
//#endregion
|
|
1396
|
-
//#region src/readers/
|
|
1377
|
+
//#region src/readers/readLabl.ts
|
|
1397
1378
|
/**
|
|
1398
|
-
* Parse a
|
|
1379
|
+
* Parse a LabelBox from an IsoView
|
|
1399
1380
|
*
|
|
1400
1381
|
* @param view - The IsoView to read data from
|
|
1401
1382
|
*
|
|
1402
|
-
* @returns A parsed
|
|
1383
|
+
* @returns A parsed LabelBox
|
|
1403
1384
|
*
|
|
1404
1385
|
* @public
|
|
1405
1386
|
*/
|
|
1406
|
-
function
|
|
1387
|
+
function readLabl(view) {
|
|
1407
1388
|
const { version, flags } = view.readFullBox();
|
|
1408
|
-
const entryCount = view.readUint(4);
|
|
1409
1389
|
return {
|
|
1410
|
-
type: "
|
|
1390
|
+
type: "labl",
|
|
1411
1391
|
version,
|
|
1412
1392
|
flags,
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
return {
|
|
1418
|
-
sampleDelta,
|
|
1419
|
-
subsampleCount,
|
|
1420
|
-
subsamples: view.readEntries(subsampleCount, () => ({
|
|
1421
|
-
subsampleSize: view.readUint(version === 1 ? 4 : 2),
|
|
1422
|
-
subsamplePriority: view.readUint(1),
|
|
1423
|
-
discardable: view.readUint(1),
|
|
1424
|
-
codecSpecificParameters: view.readUint(4)
|
|
1425
|
-
}))
|
|
1426
|
-
};
|
|
1427
|
-
})
|
|
1393
|
+
isGroupLabel: (flags & 1) !== 0,
|
|
1394
|
+
labelId: view.readUint(2),
|
|
1395
|
+
language: view.readUtf8(-1),
|
|
1396
|
+
label: view.readUtf8(-1)
|
|
1428
1397
|
};
|
|
1429
1398
|
}
|
|
1430
1399
|
|
|
1431
1400
|
//#endregion
|
|
1432
|
-
//#region src/readers/
|
|
1401
|
+
//#region src/readers/readMdat.ts
|
|
1433
1402
|
/**
|
|
1434
|
-
* Parse a
|
|
1403
|
+
* Parse a MediaDataBox from an IsoView
|
|
1435
1404
|
*
|
|
1436
1405
|
* @param view - The IsoView to read data from
|
|
1437
1406
|
*
|
|
1438
|
-
* @returns A parsed
|
|
1407
|
+
* @returns A parsed MediaDataBox
|
|
1439
1408
|
*
|
|
1440
1409
|
* @public
|
|
1441
1410
|
*/
|
|
1442
|
-
function
|
|
1411
|
+
function readMdat(view) {
|
|
1443
1412
|
return {
|
|
1444
|
-
type: "
|
|
1445
|
-
|
|
1446
|
-
defaultIsEncrypted: view.readUint(3),
|
|
1447
|
-
defaultIvSize: view.readUint(1),
|
|
1448
|
-
defaultKid: view.readArray(UINT, 1, 16)
|
|
1413
|
+
type: "mdat",
|
|
1414
|
+
data: view.readData(-1)
|
|
1449
1415
|
};
|
|
1450
1416
|
}
|
|
1451
1417
|
|
|
1452
1418
|
//#endregion
|
|
1453
|
-
//#region src/readers/
|
|
1419
|
+
//#region src/readers/readMdhd.ts
|
|
1454
1420
|
/**
|
|
1455
|
-
* Parse a
|
|
1421
|
+
* Parse a MediaHeaderBox from an IsoView
|
|
1456
1422
|
*
|
|
1457
1423
|
* @param view - The IsoView to read data from
|
|
1458
1424
|
*
|
|
1459
|
-
* @returns A parsed
|
|
1425
|
+
* @returns A parsed MediaHeaderBox
|
|
1460
1426
|
*
|
|
1461
1427
|
* @public
|
|
1462
1428
|
*/
|
|
1463
|
-
function
|
|
1429
|
+
function readMdhd(view) {
|
|
1464
1430
|
const { version, flags } = view.readFullBox();
|
|
1431
|
+
const creationTime = view.readUint(version == 1 ? 8 : 4);
|
|
1432
|
+
const modificationTime = view.readUint(version == 1 ? 8 : 4);
|
|
1433
|
+
const timescale = view.readUint(4);
|
|
1434
|
+
const duration = view.readUint(version == 1 ? 8 : 4);
|
|
1435
|
+
const lang = view.readUint(2);
|
|
1465
1436
|
return {
|
|
1466
|
-
type: "
|
|
1437
|
+
type: "mdhd",
|
|
1467
1438
|
version,
|
|
1468
1439
|
flags,
|
|
1469
|
-
|
|
1440
|
+
creationTime,
|
|
1441
|
+
modificationTime,
|
|
1442
|
+
timescale,
|
|
1443
|
+
duration,
|
|
1444
|
+
language: String.fromCharCode((lang >> 10 & 31) + 96, (lang >> 5 & 31) + 96, (lang & 31) + 96),
|
|
1445
|
+
preDefined: view.readUint(2)
|
|
1470
1446
|
};
|
|
1471
1447
|
}
|
|
1472
1448
|
|
|
1473
1449
|
//#endregion
|
|
1474
|
-
//#region src/readers/
|
|
1450
|
+
//#region src/readers/readMehd.ts
|
|
1475
1451
|
/**
|
|
1476
|
-
* Parse a
|
|
1452
|
+
* Parse a MovieExtendsHeaderBox from an IsoView
|
|
1477
1453
|
*
|
|
1478
1454
|
* @param view - The IsoView to read data from
|
|
1479
1455
|
*
|
|
1480
|
-
* @returns A parsed
|
|
1456
|
+
* @returns A parsed MovieExtendsHeaderBox
|
|
1481
1457
|
*
|
|
1482
1458
|
* @public
|
|
1483
1459
|
*/
|
|
1484
|
-
function
|
|
1460
|
+
function readMehd(view) {
|
|
1485
1461
|
const { version, flags } = view.readFullBox();
|
|
1486
1462
|
return {
|
|
1487
|
-
type: "
|
|
1463
|
+
type: "mehd",
|
|
1488
1464
|
version,
|
|
1489
1465
|
flags,
|
|
1490
|
-
|
|
1491
|
-
baseDataOffset: flags & 1 ? view.readUint(8) : void 0,
|
|
1492
|
-
sampleDescriptionIndex: flags & 2 ? view.readUint(4) : void 0,
|
|
1493
|
-
defaultSampleDuration: flags & 8 ? view.readUint(4) : void 0,
|
|
1494
|
-
defaultSampleSize: flags & 16 ? view.readUint(4) : void 0,
|
|
1495
|
-
defaultSampleFlags: flags & 32 ? view.readUint(4) : void 0
|
|
1466
|
+
fragmentDuration: view.readUint(version === 1 ? 8 : 4)
|
|
1496
1467
|
};
|
|
1497
1468
|
}
|
|
1498
1469
|
|
|
1499
1470
|
//#endregion
|
|
1500
|
-
//#region src/readers/
|
|
1471
|
+
//#region src/readers/readMeta.ts
|
|
1501
1472
|
/**
|
|
1502
|
-
* Parse a
|
|
1473
|
+
* Parse a MetaBox from an IsoView
|
|
1503
1474
|
*
|
|
1504
1475
|
* @param view - The IsoView to read data from
|
|
1505
1476
|
*
|
|
1506
|
-
* @returns A parsed
|
|
1477
|
+
* @returns A parsed MetaBox
|
|
1507
1478
|
*
|
|
1508
1479
|
* @public
|
|
1509
1480
|
*/
|
|
1510
|
-
function
|
|
1511
|
-
const { version, flags } = view.readFullBox();
|
|
1512
|
-
const trackId = view.readUint(4);
|
|
1513
|
-
const reserved = view.readUint(4);
|
|
1514
|
-
const lengthSizeOfTrafNum = (reserved & 48) >> 4;
|
|
1515
|
-
const lengthSizeOfTrunNum = (reserved & 12) >> 2;
|
|
1516
|
-
const lengthSizeOfSampleNum = reserved & 3;
|
|
1517
|
-
const numberOfEntry = view.readUint(4);
|
|
1481
|
+
function readMeta(view) {
|
|
1518
1482
|
return {
|
|
1519
|
-
type: "
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
trackId,
|
|
1523
|
-
reserved,
|
|
1524
|
-
lengthSizeOfTrafNum,
|
|
1525
|
-
lengthSizeOfTrunNum,
|
|
1526
|
-
lengthSizeOfSampleNum,
|
|
1527
|
-
numberOfEntry,
|
|
1528
|
-
entries: view.readEntries(numberOfEntry, () => ({
|
|
1529
|
-
time: view.readUint(version === 1 ? 8 : 4),
|
|
1530
|
-
moofOffset: view.readUint(version === 1 ? 8 : 4),
|
|
1531
|
-
trafNumber: view.readUint(lengthSizeOfTrafNum + 1),
|
|
1532
|
-
trunNumber: view.readUint(lengthSizeOfTrunNum + 1),
|
|
1533
|
-
sampleNumber: view.readUint(lengthSizeOfSampleNum + 1)
|
|
1534
|
-
}))
|
|
1483
|
+
type: "meta",
|
|
1484
|
+
...view.readFullBox(),
|
|
1485
|
+
boxes: view.readBoxes()
|
|
1535
1486
|
};
|
|
1536
1487
|
}
|
|
1537
1488
|
|
|
1538
1489
|
//#endregion
|
|
1539
|
-
//#region src/readers/
|
|
1490
|
+
//#region src/readers/readMfhd.ts
|
|
1540
1491
|
/**
|
|
1541
|
-
* Parse a
|
|
1492
|
+
* Parse a MovieFragmentHeaderBox from an IsoView
|
|
1542
1493
|
*
|
|
1543
1494
|
* @param view - The IsoView to read data from
|
|
1544
1495
|
*
|
|
1545
|
-
* @returns A parsed
|
|
1496
|
+
* @returns A parsed MovieFragmentHeaderBox
|
|
1546
1497
|
*
|
|
1547
1498
|
* @public
|
|
1548
1499
|
*/
|
|
1549
|
-
function
|
|
1550
|
-
const { version, flags } = view.readFullBox();
|
|
1551
|
-
const size = version === 1 ? 8 : 4;
|
|
1500
|
+
function readMfhd(view) {
|
|
1552
1501
|
return {
|
|
1553
|
-
type: "
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
creationTime: view.readUint(size),
|
|
1557
|
-
modificationTime: view.readUint(size),
|
|
1558
|
-
trackId: view.readUint(4),
|
|
1559
|
-
reserved1: view.readUint(4),
|
|
1560
|
-
duration: view.readUint(size),
|
|
1561
|
-
reserved2: view.readArray(UINT, 4, 2),
|
|
1562
|
-
layer: view.readUint(2),
|
|
1563
|
-
alternateGroup: view.readUint(2),
|
|
1564
|
-
volume: view.readTemplate(2),
|
|
1565
|
-
reserved3: view.readUint(2),
|
|
1566
|
-
matrix: view.readArray(TEMPLATE, 4, 9),
|
|
1567
|
-
width: view.readTemplate(4),
|
|
1568
|
-
height: view.readTemplate(4)
|
|
1502
|
+
type: "mfhd",
|
|
1503
|
+
...view.readFullBox(),
|
|
1504
|
+
sequenceNumber: view.readUint(4)
|
|
1569
1505
|
};
|
|
1570
1506
|
}
|
|
1571
1507
|
|
|
1572
1508
|
//#endregion
|
|
1573
|
-
//#region src/readers/
|
|
1509
|
+
//#region src/readers/readMfro.ts
|
|
1574
1510
|
/**
|
|
1575
|
-
* Parse a
|
|
1511
|
+
* Parse a MovieFragmentRandomAccessBox from an IsoView
|
|
1576
1512
|
*
|
|
1577
1513
|
* @param view - The IsoView to read data from
|
|
1578
1514
|
*
|
|
1579
|
-
* @returns A parsed
|
|
1515
|
+
* @returns A parsed MovieFragmentRandomAccessBox
|
|
1580
1516
|
*
|
|
1581
1517
|
* @public
|
|
1582
1518
|
*/
|
|
1583
|
-
function
|
|
1519
|
+
function readMfro(view) {
|
|
1584
1520
|
return {
|
|
1585
|
-
type: "
|
|
1521
|
+
type: "mfro",
|
|
1586
1522
|
...view.readFullBox(),
|
|
1587
|
-
|
|
1588
|
-
defaultSampleDescriptionIndex: view.readUint(4),
|
|
1589
|
-
defaultSampleDuration: view.readUint(4),
|
|
1590
|
-
defaultSampleSize: view.readUint(4),
|
|
1591
|
-
defaultSampleFlags: view.readUint(4)
|
|
1523
|
+
mfraSize: view.readUint(4)
|
|
1592
1524
|
};
|
|
1593
1525
|
}
|
|
1594
1526
|
|
|
1595
1527
|
//#endregion
|
|
1596
|
-
//#region src/readers/
|
|
1528
|
+
//#region src/readers/readMp4a.ts
|
|
1597
1529
|
/**
|
|
1598
|
-
* Parse
|
|
1530
|
+
* Parse an AudioSampleEntry from an IsoView
|
|
1599
1531
|
*
|
|
1600
1532
|
* @param view - The IsoView to read data from
|
|
1601
1533
|
*
|
|
1602
|
-
* @returns A parsed
|
|
1534
|
+
* @returns A parsed AudioSampleEntry
|
|
1603
1535
|
*
|
|
1604
1536
|
* @public
|
|
1605
1537
|
*/
|
|
1606
|
-
function
|
|
1607
|
-
|
|
1608
|
-
const sampleCount = view.readUint(4);
|
|
1609
|
-
let dataOffset;
|
|
1610
|
-
let firstSampleFlags;
|
|
1611
|
-
if (flags & 1) dataOffset = view.readInt(4);
|
|
1612
|
-
if (flags & 4) firstSampleFlags = view.readUint(4);
|
|
1613
|
-
const samples = view.readEntries(sampleCount, () => {
|
|
1614
|
-
const sample = {};
|
|
1615
|
-
if (flags & 256) sample.sampleDuration = view.readUint(4);
|
|
1616
|
-
if (flags & 512) sample.sampleSize = view.readUint(4);
|
|
1617
|
-
if (flags & 1024) sample.sampleFlags = view.readUint(4);
|
|
1618
|
-
if (flags & 2048) sample.sampleCompositionTimeOffset = version === 1 ? view.readInt(4) : view.readUint(4);
|
|
1619
|
-
return sample;
|
|
1620
|
-
});
|
|
1621
|
-
return {
|
|
1622
|
-
type: "trun",
|
|
1623
|
-
version,
|
|
1624
|
-
flags,
|
|
1625
|
-
sampleCount,
|
|
1626
|
-
dataOffset,
|
|
1627
|
-
firstSampleFlags,
|
|
1628
|
-
samples
|
|
1629
|
-
};
|
|
1538
|
+
function readMp4a(view) {
|
|
1539
|
+
return readAudioSampleEntryBox("mp4a", view);
|
|
1630
1540
|
}
|
|
1631
1541
|
|
|
1632
1542
|
//#endregion
|
|
1633
|
-
//#region src/readers/
|
|
1543
|
+
//#region src/readers/readMvhd.ts
|
|
1634
1544
|
/**
|
|
1635
|
-
* Parse a
|
|
1545
|
+
* Parse a Box from an IsoView
|
|
1636
1546
|
*
|
|
1637
1547
|
* @param view - The IsoView to read data from
|
|
1638
1548
|
*
|
|
1639
|
-
* @returns A parsed
|
|
1549
|
+
* @returns A parsed Box
|
|
1640
1550
|
*
|
|
1641
1551
|
* @public
|
|
1642
1552
|
*/
|
|
1643
|
-
function
|
|
1553
|
+
function readMvhd(view) {
|
|
1554
|
+
const { readUint: readUint$1, readTemplate: readTemplate$1, readArray } = view;
|
|
1555
|
+
const { version, flags } = view.readFullBox();
|
|
1556
|
+
const size = version == 1 ? 8 : 4;
|
|
1644
1557
|
return {
|
|
1645
|
-
type: "
|
|
1646
|
-
|
|
1647
|
-
|
|
1558
|
+
type: "mvhd",
|
|
1559
|
+
version,
|
|
1560
|
+
flags,
|
|
1561
|
+
creationTime: readUint$1(size),
|
|
1562
|
+
modificationTime: readUint$1(size),
|
|
1563
|
+
timescale: readUint$1(4),
|
|
1564
|
+
duration: readUint$1(size),
|
|
1565
|
+
rate: readTemplate$1(4),
|
|
1566
|
+
volume: readTemplate$1(2),
|
|
1567
|
+
reserved1: readUint$1(2),
|
|
1568
|
+
reserved2: readArray(UINT, 4, 2),
|
|
1569
|
+
matrix: readArray(TEMPLATE, 4, 9),
|
|
1570
|
+
preDefined: readArray(UINT, 4, 6),
|
|
1571
|
+
nextTrackId: readUint$1(4)
|
|
1648
1572
|
};
|
|
1649
1573
|
}
|
|
1650
1574
|
|
|
1651
1575
|
//#endregion
|
|
1652
|
-
//#region src/readers/
|
|
1576
|
+
//#region src/readers/readPayl.ts
|
|
1653
1577
|
/**
|
|
1654
|
-
* Parse a
|
|
1578
|
+
* Parse a WebVTTCuePayloadBox from an IsoView
|
|
1655
1579
|
*
|
|
1656
1580
|
* @param view - The IsoView to read data from
|
|
1657
1581
|
*
|
|
1658
|
-
* @returns A parsed
|
|
1582
|
+
* @returns A parsed WebVTTCuePayloadBox
|
|
1659
1583
|
*
|
|
1660
1584
|
* @public
|
|
1661
1585
|
*/
|
|
1662
|
-
function
|
|
1586
|
+
function readPayl(view) {
|
|
1663
1587
|
return {
|
|
1664
|
-
type: "
|
|
1665
|
-
|
|
1666
|
-
name: view.readString(-1),
|
|
1667
|
-
location: view.readString(-1)
|
|
1588
|
+
type: "payl",
|
|
1589
|
+
cueText: view.readUtf8(-1)
|
|
1668
1590
|
};
|
|
1669
1591
|
}
|
|
1670
1592
|
|
|
1671
1593
|
//#endregion
|
|
1672
|
-
//#region src/readers/
|
|
1594
|
+
//#region src/readers/readPrft.ts
|
|
1673
1595
|
/**
|
|
1674
|
-
* Parse a
|
|
1596
|
+
* Parse a ProducerReferenceTimeBox from an IsoView
|
|
1675
1597
|
*
|
|
1676
1598
|
* @param view - The IsoView to read data from
|
|
1677
1599
|
*
|
|
1678
|
-
* @returns A parsed
|
|
1600
|
+
* @returns A parsed ProducerReferenceTimeBox
|
|
1679
1601
|
*
|
|
1680
1602
|
* @public
|
|
1681
1603
|
*/
|
|
1682
|
-
function
|
|
1604
|
+
function readPrft(view) {
|
|
1605
|
+
const { version, flags } = view.readFullBox();
|
|
1683
1606
|
return {
|
|
1684
|
-
type: "
|
|
1685
|
-
|
|
1607
|
+
type: "prft",
|
|
1608
|
+
version,
|
|
1609
|
+
flags,
|
|
1610
|
+
referenceTrackId: view.readUint(4),
|
|
1611
|
+
ntpTimestampSec: view.readUint(4),
|
|
1612
|
+
ntpTimestampFrac: view.readUint(4),
|
|
1613
|
+
mediaTime: view.readUint(version === 1 ? 8 : 4)
|
|
1686
1614
|
};
|
|
1687
1615
|
}
|
|
1688
1616
|
|
|
1689
1617
|
//#endregion
|
|
1690
|
-
//#region src/readers/
|
|
1618
|
+
//#region src/readers/readPrsl.ts
|
|
1691
1619
|
/**
|
|
1692
|
-
* Parse a
|
|
1620
|
+
* Parse a PreselectionGroupBox from an IsoView
|
|
1693
1621
|
*
|
|
1694
1622
|
* @param view - The IsoView to read data from
|
|
1695
1623
|
*
|
|
1696
|
-
* @returns A parsed
|
|
1624
|
+
* @returns A parsed PreselectionGroupBox
|
|
1697
1625
|
*
|
|
1698
1626
|
* @public
|
|
1699
1627
|
*/
|
|
1700
|
-
function
|
|
1628
|
+
function readPrsl(view) {
|
|
1629
|
+
const { version, flags } = view.readFullBox();
|
|
1630
|
+
const groupId = view.readUint(4);
|
|
1631
|
+
const numEntitiesInGroup = view.readUint(4);
|
|
1701
1632
|
return {
|
|
1702
|
-
type: "
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1633
|
+
type: "prsl",
|
|
1634
|
+
version,
|
|
1635
|
+
flags,
|
|
1636
|
+
groupId,
|
|
1637
|
+
numEntitiesInGroup,
|
|
1638
|
+
entities: view.readEntries(numEntitiesInGroup, () => ({ entityId: view.readUint(4) })),
|
|
1639
|
+
preselectionTag: flags & 4096 ? view.readUtf8(-1) : void 0,
|
|
1640
|
+
selectionPriority: flags & 8192 ? view.readUint(1) : void 0,
|
|
1641
|
+
interleavingTag: flags & 16384 ? view.readUtf8(-1) : void 0,
|
|
1642
|
+
boxes: view.readBoxes()
|
|
1706
1643
|
};
|
|
1707
1644
|
}
|
|
1708
1645
|
|
|
1709
1646
|
//#endregion
|
|
1710
|
-
//#region src/readers/
|
|
1647
|
+
//#region src/readers/readPssh.ts
|
|
1711
1648
|
/**
|
|
1712
|
-
* Parse a
|
|
1649
|
+
* Parse a ProtectionSystemSpecificHeaderBox from an IsoView
|
|
1713
1650
|
*
|
|
1714
1651
|
* @param view - The IsoView to read data from
|
|
1715
1652
|
*
|
|
1716
|
-
* @returns A parsed
|
|
1653
|
+
* @returns A parsed ProtectionSystemSpecificHeaderBox
|
|
1717
1654
|
*
|
|
1718
1655
|
* @public
|
|
1719
1656
|
*/
|
|
1720
|
-
function
|
|
1657
|
+
function readPssh(view) {
|
|
1658
|
+
const { readUint: readUint$1, readArray } = view;
|
|
1659
|
+
const { version, flags } = view.readFullBox();
|
|
1660
|
+
const systemId = readArray(UINT, 1, 16);
|
|
1661
|
+
let kidCount = 0;
|
|
1662
|
+
let kid = [];
|
|
1663
|
+
if (version > 0) {
|
|
1664
|
+
kidCount = readUint$1(4);
|
|
1665
|
+
kid = readArray(UINT, 1, kidCount);
|
|
1666
|
+
}
|
|
1667
|
+
const dataSize = readUint$1(4);
|
|
1668
|
+
const data = readArray(UINT, 1, dataSize);
|
|
1721
1669
|
return {
|
|
1722
|
-
type: "
|
|
1723
|
-
|
|
1670
|
+
type: "pssh",
|
|
1671
|
+
version,
|
|
1672
|
+
flags,
|
|
1673
|
+
systemId,
|
|
1674
|
+
kidCount,
|
|
1675
|
+
kid,
|
|
1676
|
+
dataSize,
|
|
1677
|
+
data
|
|
1724
1678
|
};
|
|
1725
1679
|
}
|
|
1726
1680
|
|
|
1727
1681
|
//#endregion
|
|
1728
|
-
//#region src/readers/
|
|
1682
|
+
//#region src/readers/readSchm.ts
|
|
1729
1683
|
/**
|
|
1730
|
-
* Parse a
|
|
1684
|
+
* Parse a SchemeTypeBox from an IsoView
|
|
1731
1685
|
*
|
|
1732
|
-
* @
|
|
1686
|
+
* @param view - The IsoView to read data from
|
|
1687
|
+
*
|
|
1688
|
+
* @returns A parsed SchemeTypeBox
|
|
1733
1689
|
*
|
|
1734
1690
|
* @public
|
|
1735
1691
|
*/
|
|
1736
|
-
function
|
|
1737
|
-
|
|
1692
|
+
function readSchm(view) {
|
|
1693
|
+
const { version, flags } = view.readFullBox();
|
|
1694
|
+
return {
|
|
1695
|
+
type: "schm",
|
|
1696
|
+
version,
|
|
1697
|
+
flags,
|
|
1698
|
+
schemeType: view.readUint(4),
|
|
1699
|
+
schemeVersion: view.readUint(4),
|
|
1700
|
+
schemeUri: flags & 1 ? view.readString(-1) : void 0
|
|
1701
|
+
};
|
|
1738
1702
|
}
|
|
1739
1703
|
|
|
1740
1704
|
//#endregion
|
|
1741
|
-
//#region src/
|
|
1705
|
+
//#region src/readers/readSdtp.ts
|
|
1742
1706
|
/**
|
|
1743
|
-
*
|
|
1707
|
+
* Parse a SampleDependencyTypeBox from an IsoView
|
|
1708
|
+
*
|
|
1709
|
+
* @param view - The IsoView to read data from
|
|
1710
|
+
*
|
|
1711
|
+
* @returns A parsed SampleDependencyTypeBox
|
|
1744
1712
|
*
|
|
1745
1713
|
* @public
|
|
1746
1714
|
*/
|
|
1747
|
-
|
|
1715
|
+
function readSdtp(view) {
|
|
1716
|
+
return {
|
|
1717
|
+
type: "sdtp",
|
|
1718
|
+
...view.readFullBox(),
|
|
1719
|
+
sampleDependencyTable: view.readArray(UINT, 1, view.bytesRemaining)
|
|
1720
|
+
};
|
|
1721
|
+
}
|
|
1748
1722
|
|
|
1749
1723
|
//#endregion
|
|
1750
|
-
//#region src/
|
|
1724
|
+
//#region src/readers/readSidx.ts
|
|
1751
1725
|
/**
|
|
1752
|
-
*
|
|
1726
|
+
* Parse a SegmentIndexBox from an IsoView
|
|
1727
|
+
*
|
|
1728
|
+
* @param view - The IsoView to read data from
|
|
1729
|
+
*
|
|
1730
|
+
* @returns A parsed SegmentIndexBox
|
|
1753
1731
|
*
|
|
1754
1732
|
* @public
|
|
1755
1733
|
*/
|
|
1756
|
-
|
|
1734
|
+
function readSidx(view) {
|
|
1735
|
+
const { readUint: readUint$1 } = view;
|
|
1736
|
+
const { version, flags } = view.readFullBox();
|
|
1737
|
+
const size = version === 1 ? 8 : 4;
|
|
1738
|
+
const referenceId = readUint$1(4);
|
|
1739
|
+
const timescale = readUint$1(4);
|
|
1740
|
+
const earliestPresentationTime = readUint$1(size);
|
|
1741
|
+
const firstOffset = readUint$1(size);
|
|
1742
|
+
const reserved = readUint$1(2);
|
|
1743
|
+
const referenceCount = readUint$1(2);
|
|
1744
|
+
return {
|
|
1745
|
+
type: "sidx",
|
|
1746
|
+
version,
|
|
1747
|
+
flags,
|
|
1748
|
+
referenceId,
|
|
1749
|
+
timescale,
|
|
1750
|
+
earliestPresentationTime,
|
|
1751
|
+
firstOffset,
|
|
1752
|
+
reserved,
|
|
1753
|
+
references: view.readEntries(referenceCount, () => {
|
|
1754
|
+
const entry = {};
|
|
1755
|
+
entry.reference = readUint$1(4);
|
|
1756
|
+
entry.subsegmentDuration = readUint$1(4);
|
|
1757
|
+
entry.sap = readUint$1(4);
|
|
1758
|
+
entry.referenceType = entry.reference >> 31 & 1;
|
|
1759
|
+
entry.referencedSize = entry.reference & 2147483647;
|
|
1760
|
+
entry.startsWithSap = entry.sap >> 31 & 1;
|
|
1761
|
+
entry.sapType = entry.sap >> 28 & 7;
|
|
1762
|
+
entry.sapDeltaTime = entry.sap & 268435455;
|
|
1763
|
+
return entry;
|
|
1764
|
+
})
|
|
1765
|
+
};
|
|
1766
|
+
}
|
|
1757
1767
|
|
|
1758
1768
|
//#endregion
|
|
1759
|
-
//#region src/
|
|
1769
|
+
//#region src/readers/readSkip.ts
|
|
1760
1770
|
/**
|
|
1761
|
-
*
|
|
1771
|
+
* Parse a FreeSpaceBox from an IsoView
|
|
1772
|
+
*
|
|
1773
|
+
* @param view - The IsoView to read data from
|
|
1774
|
+
*
|
|
1775
|
+
* @returns A parsed FreeSpaceBox
|
|
1762
1776
|
*
|
|
1763
1777
|
* @public
|
|
1764
1778
|
*/
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
const length = size > 0 ? size : dataView.byteLength - (offset - dataView.byteOffset);
|
|
1771
|
-
return new Uint8Array(dataView.buffer, offset, Math.max(length, 0));
|
|
1772
|
-
}
|
|
1773
|
-
|
|
1774
|
-
//#endregion
|
|
1775
|
-
//#region src/utils/readInt.ts
|
|
1776
|
-
function readInt(dataView, offset, size) {
|
|
1777
|
-
let result = NaN;
|
|
1778
|
-
const cursor = offset - dataView.byteOffset;
|
|
1779
|
-
switch (size) {
|
|
1780
|
-
case 1:
|
|
1781
|
-
result = dataView.getInt8(cursor);
|
|
1782
|
-
break;
|
|
1783
|
-
case 2:
|
|
1784
|
-
result = dataView.getInt16(cursor);
|
|
1785
|
-
break;
|
|
1786
|
-
case 4:
|
|
1787
|
-
result = dataView.getInt32(cursor);
|
|
1788
|
-
break;
|
|
1789
|
-
case 8:
|
|
1790
|
-
const s1 = dataView.getInt32(cursor);
|
|
1791
|
-
const s2 = dataView.getInt32(cursor + 4);
|
|
1792
|
-
result = s1 * Math.pow(2, 32) + s2;
|
|
1793
|
-
break;
|
|
1794
|
-
}
|
|
1795
|
-
return result;
|
|
1796
|
-
}
|
|
1797
|
-
|
|
1798
|
-
//#endregion
|
|
1799
|
-
//#region src/utils/readUint.ts
|
|
1800
|
-
function readUint(dataView, offset, size) {
|
|
1801
|
-
const cursor = offset - dataView.byteOffset;
|
|
1802
|
-
let value = NaN;
|
|
1803
|
-
let s1;
|
|
1804
|
-
let s2;
|
|
1805
|
-
switch (size) {
|
|
1806
|
-
case 1:
|
|
1807
|
-
value = dataView.getUint8(cursor);
|
|
1808
|
-
break;
|
|
1809
|
-
case 2:
|
|
1810
|
-
value = dataView.getUint16(cursor);
|
|
1811
|
-
break;
|
|
1812
|
-
case 3:
|
|
1813
|
-
s1 = dataView.getUint16(cursor);
|
|
1814
|
-
s2 = dataView.getUint8(cursor + 2);
|
|
1815
|
-
value = (s1 << 8) + s2;
|
|
1816
|
-
break;
|
|
1817
|
-
case 4:
|
|
1818
|
-
value = dataView.getUint32(cursor);
|
|
1819
|
-
break;
|
|
1820
|
-
case 8:
|
|
1821
|
-
s1 = dataView.getUint32(cursor);
|
|
1822
|
-
s2 = dataView.getUint32(cursor + 4);
|
|
1823
|
-
value = s1 * Math.pow(2, 32) + s2;
|
|
1824
|
-
break;
|
|
1825
|
-
}
|
|
1826
|
-
return value;
|
|
1827
|
-
}
|
|
1828
|
-
|
|
1829
|
-
//#endregion
|
|
1830
|
-
//#region src/utils/readString.ts
|
|
1831
|
-
function readString(dataView, offset, length) {
|
|
1832
|
-
let str = "";
|
|
1833
|
-
for (let c = 0; c < length; c++) {
|
|
1834
|
-
const char = readUint(dataView, offset + c, 1);
|
|
1835
|
-
str += String.fromCharCode(char);
|
|
1836
|
-
}
|
|
1837
|
-
return str;
|
|
1838
|
-
}
|
|
1839
|
-
|
|
1840
|
-
//#endregion
|
|
1841
|
-
//#region src/utils/readTemplate.ts
|
|
1842
|
-
function readTemplate(dataView, offset, size) {
|
|
1843
|
-
const half = size / 2;
|
|
1844
|
-
return readUint(dataView, offset, half) + readUint(dataView, offset + half, half) / Math.pow(2, half);
|
|
1845
|
-
}
|
|
1846
|
-
|
|
1847
|
-
//#endregion
|
|
1848
|
-
//#region src/utils/readTerminatedString.ts
|
|
1849
|
-
function readTerminatedString(dataView, offset) {
|
|
1850
|
-
let str = "";
|
|
1851
|
-
let cursor = offset;
|
|
1852
|
-
while (cursor - dataView.byteOffset < dataView.byteLength) {
|
|
1853
|
-
const char = readUint(dataView, cursor, 1);
|
|
1854
|
-
if (char === 0) break;
|
|
1855
|
-
str += String.fromCharCode(char);
|
|
1856
|
-
cursor++;
|
|
1857
|
-
}
|
|
1858
|
-
return str;
|
|
1779
|
+
function readSkip(view) {
|
|
1780
|
+
return {
|
|
1781
|
+
...readFree(view),
|
|
1782
|
+
type: "skip"
|
|
1783
|
+
};
|
|
1859
1784
|
}
|
|
1860
1785
|
|
|
1861
1786
|
//#endregion
|
|
1862
|
-
//#region src/
|
|
1787
|
+
//#region src/readers/readSmhd.ts
|
|
1863
1788
|
/**
|
|
1864
|
-
*
|
|
1789
|
+
* Parse a SoundMediaHeaderBox from an IsoView
|
|
1865
1790
|
*
|
|
1866
|
-
* @param
|
|
1867
|
-
* @param offset - The offset to start reading from.
|
|
1868
|
-
* @returns The UTF-8 string.
|
|
1791
|
+
* @param view - The IsoView to read data from
|
|
1869
1792
|
*
|
|
1870
|
-
* @
|
|
1793
|
+
* @returns A parsed SoundMediaHeaderBox
|
|
1794
|
+
*
|
|
1795
|
+
* @public
|
|
1871
1796
|
*/
|
|
1872
|
-
function
|
|
1873
|
-
|
|
1874
|
-
|
|
1797
|
+
function readSmhd(view) {
|
|
1798
|
+
return {
|
|
1799
|
+
type: "smhd",
|
|
1800
|
+
...view.readFullBox(),
|
|
1801
|
+
balance: view.readUint(2),
|
|
1802
|
+
reserved: view.readUint(2)
|
|
1803
|
+
};
|
|
1875
1804
|
}
|
|
1876
1805
|
|
|
1877
1806
|
//#endregion
|
|
1878
|
-
//#region src/
|
|
1807
|
+
//#region src/readers/readSsix.ts
|
|
1879
1808
|
/**
|
|
1880
|
-
*
|
|
1809
|
+
* Parse a SubsegmentIndexBox from an IsoView
|
|
1881
1810
|
*
|
|
1882
|
-
* @param
|
|
1883
|
-
* @param offset - The offset to start reading from.
|
|
1884
|
-
* @returns The UTF-8 terminated string.
|
|
1811
|
+
* @param view - The IsoView to read data from
|
|
1885
1812
|
*
|
|
1886
|
-
* @
|
|
1813
|
+
* @returns A parsed SubsegmentIndexBox
|
|
1814
|
+
*
|
|
1815
|
+
* @public
|
|
1887
1816
|
*/
|
|
1888
|
-
function
|
|
1889
|
-
const
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1817
|
+
function readSsix(view) {
|
|
1818
|
+
const { version, flags } = view.readFullBox();
|
|
1819
|
+
const subsegmentCount = view.readUint(4);
|
|
1820
|
+
return {
|
|
1821
|
+
type: "ssix",
|
|
1822
|
+
version,
|
|
1823
|
+
flags,
|
|
1824
|
+
subsegmentCount,
|
|
1825
|
+
subsegments: view.readEntries(subsegmentCount, () => {
|
|
1826
|
+
const rangesCount = view.readUint(4);
|
|
1827
|
+
return {
|
|
1828
|
+
rangesCount,
|
|
1829
|
+
ranges: view.readEntries(rangesCount, () => ({
|
|
1830
|
+
level: view.readUint(1),
|
|
1831
|
+
rangeSize: view.readUint(3)
|
|
1832
|
+
}))
|
|
1833
|
+
};
|
|
1834
|
+
})
|
|
1835
|
+
};
|
|
1898
1836
|
}
|
|
1899
1837
|
|
|
1900
1838
|
//#endregion
|
|
1901
|
-
//#region src/
|
|
1839
|
+
//#region src/readers/readSthd.ts
|
|
1902
1840
|
/**
|
|
1903
|
-
*
|
|
1904
|
-
*
|
|
1841
|
+
* Parse a SubtitleMediaHeaderBox from an IsoView
|
|
1842
|
+
*
|
|
1843
|
+
* @param view - The IsoView to read data from
|
|
1844
|
+
*
|
|
1845
|
+
* @returns A parsed SubtitleMediaHeaderBox
|
|
1905
1846
|
*
|
|
1906
1847
|
* @public
|
|
1907
1848
|
*/
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1849
|
+
function readSthd(view) {
|
|
1850
|
+
return {
|
|
1851
|
+
type: "sthd",
|
|
1852
|
+
...view.readFullBox()
|
|
1853
|
+
};
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
//#endregion
|
|
1857
|
+
//#region src/readers/readStsd.ts
|
|
1858
|
+
/**
|
|
1859
|
+
* Parse a SampleDescriptionBox from an IsoView
|
|
1860
|
+
*
|
|
1861
|
+
* @param view - The IsoView to read data from
|
|
1862
|
+
*
|
|
1863
|
+
* @returns A parsed SampleDescriptionBox
|
|
1864
|
+
*
|
|
1865
|
+
* @public
|
|
1866
|
+
*/
|
|
1867
|
+
function readStsd(view) {
|
|
1868
|
+
const { version, flags } = view.readFullBox();
|
|
1869
|
+
const entryCount = view.readUint(4);
|
|
1870
|
+
return {
|
|
1871
|
+
type: "stsd",
|
|
1872
|
+
version,
|
|
1873
|
+
flags,
|
|
1874
|
+
entryCount,
|
|
1875
|
+
entries: view.readBoxes(entryCount)
|
|
1876
|
+
};
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
//#endregion
|
|
1880
|
+
//#region src/readers/readStss.ts
|
|
1881
|
+
/**
|
|
1882
|
+
* Parse a SyncSampleBox from an IsoView
|
|
1883
|
+
*
|
|
1884
|
+
* @param view - The IsoView to read data from
|
|
1885
|
+
*
|
|
1886
|
+
* @returns A parsed SyncSampleBox
|
|
1887
|
+
*
|
|
1888
|
+
* @public
|
|
1889
|
+
*/
|
|
1890
|
+
function readStss(view) {
|
|
1891
|
+
const { version, flags } = view.readFullBox();
|
|
1892
|
+
const entryCount = view.readUint(4);
|
|
1893
|
+
return {
|
|
1894
|
+
type: "stss",
|
|
1895
|
+
version,
|
|
1896
|
+
flags,
|
|
1897
|
+
entryCount,
|
|
1898
|
+
entries: view.readEntries(entryCount, () => ({ sampleNumber: view.readUint(4) }))
|
|
1899
|
+
};
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
//#endregion
|
|
1903
|
+
//#region src/readers/readSttg.ts
|
|
1904
|
+
/**
|
|
1905
|
+
* Parse a WebVTTSettingsBox from an IsoView
|
|
1906
|
+
*
|
|
1907
|
+
* @param view - The IsoView to read data from
|
|
1908
|
+
*
|
|
1909
|
+
* @returns A parsed WebVTTSettingsBox
|
|
1910
|
+
*
|
|
1911
|
+
* @public
|
|
1912
|
+
*/
|
|
1913
|
+
function readSttg(view) {
|
|
1914
|
+
return {
|
|
1915
|
+
type: "sttg",
|
|
1916
|
+
settings: view.readUtf8(-1)
|
|
1917
|
+
};
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
//#endregion
|
|
1921
|
+
//#region src/readers/readStts.ts
|
|
1922
|
+
/**
|
|
1923
|
+
* Parse a DecodingTimeToSampleBox from an IsoView
|
|
1924
|
+
*
|
|
1925
|
+
* @param view - The IsoView to read data from
|
|
1926
|
+
*
|
|
1927
|
+
* @returns A parsed DecodingTimeToSampleBox
|
|
1928
|
+
*
|
|
1929
|
+
* @public
|
|
1930
|
+
*/
|
|
1931
|
+
function readStts(view) {
|
|
1932
|
+
const { version, flags } = view.readFullBox();
|
|
1933
|
+
const entryCount = view.readUint(4);
|
|
1934
|
+
return {
|
|
1935
|
+
type: "stts",
|
|
1936
|
+
version,
|
|
1937
|
+
flags,
|
|
1938
|
+
entryCount,
|
|
1939
|
+
entries: view.readEntries(entryCount, () => ({
|
|
1940
|
+
sampleCount: view.readUint(4),
|
|
1941
|
+
sampleDelta: view.readUint(4)
|
|
1942
|
+
}))
|
|
1943
|
+
};
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
//#endregion
|
|
1947
|
+
//#region src/readers/readStyp.ts
|
|
1948
|
+
/**
|
|
1949
|
+
* Parse a SegmentTypeBox from an IsoView
|
|
1950
|
+
*
|
|
1951
|
+
* @param view - The IsoView to read data from
|
|
1952
|
+
*
|
|
1953
|
+
* @returns A parsed SegmentTypeBox
|
|
1954
|
+
*
|
|
1955
|
+
* @public
|
|
1956
|
+
*/
|
|
1957
|
+
function readStyp(view) {
|
|
1958
|
+
return {
|
|
1959
|
+
...readFtyp(view),
|
|
1960
|
+
type: "styp"
|
|
1961
|
+
};
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
//#endregion
|
|
1965
|
+
//#region src/readers/readSubs.ts
|
|
1966
|
+
/**
|
|
1967
|
+
* Parse a SubSampleInformationBox from an IsoView
|
|
1968
|
+
*
|
|
1969
|
+
* @param view - The IsoView to read data from
|
|
1970
|
+
*
|
|
1971
|
+
* @returns A parsed SubSampleInformationBox
|
|
1972
|
+
*
|
|
1973
|
+
* @public
|
|
1974
|
+
*/
|
|
1975
|
+
function readSubs(view) {
|
|
1976
|
+
const { version, flags } = view.readFullBox();
|
|
1977
|
+
const entryCount = view.readUint(4);
|
|
1978
|
+
return {
|
|
1979
|
+
type: "subs",
|
|
1980
|
+
version,
|
|
1981
|
+
flags,
|
|
1982
|
+
entryCount,
|
|
1983
|
+
entries: view.readEntries(entryCount, () => {
|
|
1984
|
+
const sampleDelta = view.readUint(4);
|
|
1985
|
+
const subsampleCount = view.readUint(2);
|
|
1981
1986
|
return {
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
};
|
|
1991
|
-
this.jump = (size) => {
|
|
1992
|
-
this.offset += size;
|
|
1993
|
-
};
|
|
1994
|
-
this.readBox = () => {
|
|
1995
|
-
const { dataView, offset } = this;
|
|
1996
|
-
let cursor = 0;
|
|
1997
|
-
const size = readUint(dataView, offset, 4);
|
|
1998
|
-
const type = readString(dataView, offset + 4, 4);
|
|
1999
|
-
const box = {
|
|
2000
|
-
size,
|
|
2001
|
-
type
|
|
1987
|
+
sampleDelta,
|
|
1988
|
+
subsampleCount,
|
|
1989
|
+
subsamples: view.readEntries(subsampleCount, () => ({
|
|
1990
|
+
subsampleSize: view.readUint(version === 1 ? 4 : 2),
|
|
1991
|
+
subsamplePriority: view.readUint(1),
|
|
1992
|
+
discardable: view.readUint(1),
|
|
1993
|
+
codecSpecificParameters: view.readUint(4)
|
|
1994
|
+
}))
|
|
2002
1995
|
};
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
}
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
}
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
1996
|
+
})
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
//#endregion
|
|
2001
|
+
//#region src/readers/readTenc.ts
|
|
2002
|
+
/**
|
|
2003
|
+
* Parse a TrackEncryptionBox from an IsoView
|
|
2004
|
+
*
|
|
2005
|
+
* @param view - The IsoView to read data from
|
|
2006
|
+
*
|
|
2007
|
+
* @returns A parsed TrackEncryptionBox
|
|
2008
|
+
*
|
|
2009
|
+
* @public
|
|
2010
|
+
*/
|
|
2011
|
+
function readTenc(view) {
|
|
2012
|
+
return {
|
|
2013
|
+
type: "tenc",
|
|
2014
|
+
...view.readFullBox(),
|
|
2015
|
+
defaultIsEncrypted: view.readUint(3),
|
|
2016
|
+
defaultIvSize: view.readUint(1),
|
|
2017
|
+
defaultKid: view.readArray(UINT, 1, 16)
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
//#endregion
|
|
2022
|
+
//#region src/readers/readTfdt.ts
|
|
2023
|
+
/**
|
|
2024
|
+
* Parse a TrackFragmentDecodeTimeBox from an IsoView
|
|
2025
|
+
*
|
|
2026
|
+
* @param view - The IsoView to read data from
|
|
2027
|
+
*
|
|
2028
|
+
* @returns A parsed TrackFragmentDecodeTimeBox
|
|
2029
|
+
*
|
|
2030
|
+
* @public
|
|
2031
|
+
*/
|
|
2032
|
+
function readTfdt(view) {
|
|
2033
|
+
const { version, flags } = view.readFullBox();
|
|
2034
|
+
return {
|
|
2035
|
+
type: "tfdt",
|
|
2036
|
+
version,
|
|
2037
|
+
flags,
|
|
2038
|
+
baseMediaDecodeTime: view.readUint(version == 1 ? 8 : 4)
|
|
2039
|
+
};
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
//#endregion
|
|
2043
|
+
//#region src/readers/readTfhd.ts
|
|
2044
|
+
/**
|
|
2045
|
+
* Parse a TrackFragmentHeaderBox from an IsoView
|
|
2046
|
+
*
|
|
2047
|
+
* @param view - The IsoView to read data from
|
|
2048
|
+
*
|
|
2049
|
+
* @returns A parsed TrackFragmentHeaderBox
|
|
2050
|
+
*
|
|
2051
|
+
* @public
|
|
2052
|
+
*/
|
|
2053
|
+
function readTfhd(view) {
|
|
2054
|
+
const { version, flags } = view.readFullBox();
|
|
2055
|
+
return {
|
|
2056
|
+
type: "tfhd",
|
|
2057
|
+
version,
|
|
2058
|
+
flags,
|
|
2059
|
+
trackId: view.readUint(4),
|
|
2060
|
+
baseDataOffset: flags & 1 ? view.readUint(8) : void 0,
|
|
2061
|
+
sampleDescriptionIndex: flags & 2 ? view.readUint(4) : void 0,
|
|
2062
|
+
defaultSampleDuration: flags & 8 ? view.readUint(4) : void 0,
|
|
2063
|
+
defaultSampleSize: flags & 16 ? view.readUint(4) : void 0,
|
|
2064
|
+
defaultSampleFlags: flags & 32 ? view.readUint(4) : void 0
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
//#endregion
|
|
2069
|
+
//#region src/readers/readTfra.ts
|
|
2070
|
+
/**
|
|
2071
|
+
* Parse a TrackFragmentRandomAccessBox from an IsoView
|
|
2072
|
+
*
|
|
2073
|
+
* @param view - The IsoView to read data from
|
|
2074
|
+
*
|
|
2075
|
+
* @returns A parsed TrackFragmentRandomAccessBox
|
|
2076
|
+
*
|
|
2077
|
+
* @public
|
|
2078
|
+
*/
|
|
2079
|
+
function readTfra(view) {
|
|
2080
|
+
const { version, flags } = view.readFullBox();
|
|
2081
|
+
const trackId = view.readUint(4);
|
|
2082
|
+
const reserved = view.readUint(4);
|
|
2083
|
+
const lengthSizeOfTrafNum = (reserved & 48) >> 4;
|
|
2084
|
+
const lengthSizeOfTrunNum = (reserved & 12) >> 2;
|
|
2085
|
+
const lengthSizeOfSampleNum = reserved & 3;
|
|
2086
|
+
const numberOfEntry = view.readUint(4);
|
|
2087
|
+
return {
|
|
2088
|
+
type: "tfra",
|
|
2089
|
+
version,
|
|
2090
|
+
flags,
|
|
2091
|
+
trackId,
|
|
2092
|
+
reserved,
|
|
2093
|
+
lengthSizeOfTrafNum,
|
|
2094
|
+
lengthSizeOfTrunNum,
|
|
2095
|
+
lengthSizeOfSampleNum,
|
|
2096
|
+
numberOfEntry,
|
|
2097
|
+
entries: view.readEntries(numberOfEntry, () => ({
|
|
2098
|
+
time: view.readUint(version === 1 ? 8 : 4),
|
|
2099
|
+
moofOffset: view.readUint(version === 1 ? 8 : 4),
|
|
2100
|
+
trafNumber: view.readUint(lengthSizeOfTrafNum + 1),
|
|
2101
|
+
trunNumber: view.readUint(lengthSizeOfTrunNum + 1),
|
|
2102
|
+
sampleNumber: view.readUint(lengthSizeOfSampleNum + 1)
|
|
2103
|
+
}))
|
|
2104
|
+
};
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
//#endregion
|
|
2108
|
+
//#region src/readers/readTkhd.ts
|
|
2109
|
+
/**
|
|
2110
|
+
* Parse a TrackHeaderBox from an IsoView
|
|
2111
|
+
*
|
|
2112
|
+
* @param view - The IsoView to read data from
|
|
2113
|
+
*
|
|
2114
|
+
* @returns A parsed TrackHeaderBox
|
|
2115
|
+
*
|
|
2116
|
+
* @public
|
|
2117
|
+
*/
|
|
2118
|
+
function readTkhd(view) {
|
|
2119
|
+
const { version, flags } = view.readFullBox();
|
|
2120
|
+
const size = version === 1 ? 8 : 4;
|
|
2121
|
+
return {
|
|
2122
|
+
type: "tkhd",
|
|
2123
|
+
version,
|
|
2124
|
+
flags,
|
|
2125
|
+
creationTime: view.readUint(size),
|
|
2126
|
+
modificationTime: view.readUint(size),
|
|
2127
|
+
trackId: view.readUint(4),
|
|
2128
|
+
reserved1: view.readUint(4),
|
|
2129
|
+
duration: view.readUint(size),
|
|
2130
|
+
reserved2: view.readArray(UINT, 4, 2),
|
|
2131
|
+
layer: view.readUint(2),
|
|
2132
|
+
alternateGroup: view.readUint(2),
|
|
2133
|
+
volume: view.readTemplate(2),
|
|
2134
|
+
reserved3: view.readUint(2),
|
|
2135
|
+
matrix: view.readArray(TEMPLATE, 4, 9),
|
|
2136
|
+
width: view.readTemplate(4),
|
|
2137
|
+
height: view.readTemplate(4)
|
|
2138
|
+
};
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
//#endregion
|
|
2142
|
+
//#region src/readers/readTrex.ts
|
|
2143
|
+
/**
|
|
2144
|
+
* Parse a TrackExtendsBox from an IsoView
|
|
2145
|
+
*
|
|
2146
|
+
* @param view - The IsoView to read data from
|
|
2147
|
+
*
|
|
2148
|
+
* @returns A parsed TrackExtendsBox
|
|
2149
|
+
*
|
|
2150
|
+
* @public
|
|
2151
|
+
*/
|
|
2152
|
+
function readTrex(view) {
|
|
2153
|
+
return {
|
|
2154
|
+
type: "trex",
|
|
2155
|
+
...view.readFullBox(),
|
|
2156
|
+
trackId: view.readUint(4),
|
|
2157
|
+
defaultSampleDescriptionIndex: view.readUint(4),
|
|
2158
|
+
defaultSampleDuration: view.readUint(4),
|
|
2159
|
+
defaultSampleSize: view.readUint(4),
|
|
2160
|
+
defaultSampleFlags: view.readUint(4)
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2095
2163
|
|
|
2096
2164
|
//#endregion
|
|
2097
|
-
//#region src/
|
|
2165
|
+
//#region src/readers/readTrun.ts
|
|
2098
2166
|
/**
|
|
2099
|
-
*
|
|
2167
|
+
* Parse a TrackRunBox from an IsoView
|
|
2100
2168
|
*
|
|
2101
|
-
* @param
|
|
2102
|
-
* @param config - The configuration for the IsoView
|
|
2169
|
+
* @param view - The IsoView to read data from
|
|
2103
2170
|
*
|
|
2104
|
-
* @returns
|
|
2171
|
+
* @returns A parsed TrackRunBox
|
|
2105
2172
|
*
|
|
2106
|
-
* @
|
|
2107
|
-
|
|
2173
|
+
* @public
|
|
2174
|
+
*/
|
|
2175
|
+
function readTrun(view) {
|
|
2176
|
+
const { version, flags } = view.readFullBox();
|
|
2177
|
+
const sampleCount = view.readUint(4);
|
|
2178
|
+
let dataOffset;
|
|
2179
|
+
let firstSampleFlags;
|
|
2180
|
+
if (flags & 1) dataOffset = view.readInt(4);
|
|
2181
|
+
if (flags & 4) firstSampleFlags = view.readUint(4);
|
|
2182
|
+
const samples = view.readEntries(sampleCount, () => {
|
|
2183
|
+
const sample = {};
|
|
2184
|
+
if (flags & 256) sample.sampleDuration = view.readUint(4);
|
|
2185
|
+
if (flags & 512) sample.sampleSize = view.readUint(4);
|
|
2186
|
+
if (flags & 1024) sample.sampleFlags = view.readUint(4);
|
|
2187
|
+
if (flags & 2048) sample.sampleCompositionTimeOffset = version === 1 ? view.readInt(4) : view.readUint(4);
|
|
2188
|
+
return sample;
|
|
2189
|
+
});
|
|
2190
|
+
return {
|
|
2191
|
+
type: "trun",
|
|
2192
|
+
version,
|
|
2193
|
+
flags,
|
|
2194
|
+
sampleCount,
|
|
2195
|
+
dataOffset,
|
|
2196
|
+
firstSampleFlags,
|
|
2197
|
+
samples
|
|
2198
|
+
};
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
//#endregion
|
|
2202
|
+
//#region src/readers/readUrl.ts
|
|
2203
|
+
/**
|
|
2204
|
+
* Parse a UrlBox from an IsoView
|
|
2205
|
+
*
|
|
2206
|
+
* @param view - The IsoView to read data from
|
|
2207
|
+
*
|
|
2208
|
+
* @returns A parsed UrlBox
|
|
2108
2209
|
*
|
|
2109
2210
|
* @public
|
|
2110
2211
|
*/
|
|
2111
|
-
function
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2212
|
+
function readUrl(view) {
|
|
2213
|
+
return {
|
|
2214
|
+
type: "url ",
|
|
2215
|
+
...view.readFullBox(),
|
|
2216
|
+
location: view.readString(-1)
|
|
2217
|
+
};
|
|
2115
2218
|
}
|
|
2116
2219
|
|
|
2117
2220
|
//#endregion
|
|
2118
|
-
//#region src/
|
|
2221
|
+
//#region src/readers/readUrn.ts
|
|
2119
2222
|
/**
|
|
2120
|
-
*
|
|
2223
|
+
* Parse a UrnBox from an IsoView
|
|
2121
2224
|
*
|
|
2122
|
-
* @param
|
|
2123
|
-
* @param depthFirst - Whether to traverse the boxes depth-first or breadth-first
|
|
2124
|
-
* @param maxDepth - The maximum depth to traverse. A value of 0 will only traverse the root boxes.
|
|
2225
|
+
* @param view - The IsoView to read data from
|
|
2125
2226
|
*
|
|
2126
|
-
* @returns A
|
|
2227
|
+
* @returns A parsed UrnBox
|
|
2127
2228
|
*
|
|
2128
|
-
* @
|
|
2129
|
-
|
|
2229
|
+
* @public
|
|
2230
|
+
*/
|
|
2231
|
+
function readUrn(view) {
|
|
2232
|
+
return {
|
|
2233
|
+
type: "urn ",
|
|
2234
|
+
...view.readFullBox(),
|
|
2235
|
+
name: view.readString(-1),
|
|
2236
|
+
location: view.readString(-1)
|
|
2237
|
+
};
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
//#endregion
|
|
2241
|
+
//#region src/readers/readVlab.ts
|
|
2242
|
+
/**
|
|
2243
|
+
* Parse a WebVTTSourceLabelBox from an IsoView
|
|
2244
|
+
*
|
|
2245
|
+
* @param view - The IsoView to read data from
|
|
2246
|
+
*
|
|
2247
|
+
* @returns A parsed WebVTTSourceLabelBox
|
|
2130
2248
|
*
|
|
2131
2249
|
* @public
|
|
2132
2250
|
*/
|
|
2133
|
-
function
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
if (!item) continue;
|
|
2139
|
-
const [children, depth] = item;
|
|
2140
|
-
for (const child of children) {
|
|
2141
|
-
yield child;
|
|
2142
|
-
if (depth >= maxDepth) continue;
|
|
2143
|
-
if (isContainer(child) && child.boxes) {
|
|
2144
|
-
const next = child.boxes;
|
|
2145
|
-
if (depthFirst) yield* traverseIsoBoxes(next, depthFirst, maxDepth - 1);
|
|
2146
|
-
else queue.push([next, depth + 1]);
|
|
2147
|
-
}
|
|
2148
|
-
}
|
|
2149
|
-
}
|
|
2251
|
+
function readVlab(view) {
|
|
2252
|
+
return {
|
|
2253
|
+
type: "vlab",
|
|
2254
|
+
sourceLabel: view.readUtf8(-1)
|
|
2255
|
+
};
|
|
2150
2256
|
}
|
|
2151
2257
|
|
|
2152
2258
|
//#endregion
|
|
2153
|
-
//#region src/
|
|
2259
|
+
//#region src/readers/readVmhd.ts
|
|
2154
2260
|
/**
|
|
2155
|
-
*
|
|
2261
|
+
* Parse a VideoMediaHeaderBox from an IsoView
|
|
2156
2262
|
*
|
|
2157
|
-
* @param
|
|
2263
|
+
* @param view - The IsoView to read data from
|
|
2158
2264
|
*
|
|
2159
|
-
* @returns
|
|
2265
|
+
* @returns A parsed VideoMediaHeaderBox
|
|
2160
2266
|
*
|
|
2161
2267
|
* @public
|
|
2162
2268
|
*/
|
|
2163
|
-
function
|
|
2164
|
-
return
|
|
2269
|
+
function readVmhd(view) {
|
|
2270
|
+
return {
|
|
2271
|
+
type: "vmhd",
|
|
2272
|
+
...view.readFullBox(),
|
|
2273
|
+
graphicsmode: view.readUint(2),
|
|
2274
|
+
opcolor: view.readArray(UINT, 2, 3)
|
|
2275
|
+
};
|
|
2165
2276
|
}
|
|
2166
2277
|
|
|
2167
2278
|
//#endregion
|
|
2168
|
-
//#region src/
|
|
2279
|
+
//#region src/readers/readVttC.ts
|
|
2169
2280
|
/**
|
|
2170
|
-
*
|
|
2281
|
+
* Parse a WebVTTConfigurationBox from an IsoView
|
|
2171
2282
|
*
|
|
2172
|
-
* @param
|
|
2173
|
-
* @param config - The configuration for the readable stream
|
|
2283
|
+
* @param view - The IsoView to read data from
|
|
2174
2284
|
*
|
|
2175
|
-
* @returns A
|
|
2285
|
+
* @returns A parsed WebVttConfigurationBox
|
|
2176
2286
|
*
|
|
2177
|
-
* @
|
|
2178
|
-
|
|
2287
|
+
* @public
|
|
2288
|
+
*/
|
|
2289
|
+
function readVttC(view) {
|
|
2290
|
+
return {
|
|
2291
|
+
type: "vttC",
|
|
2292
|
+
config: view.readUtf8()
|
|
2293
|
+
};
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2296
|
+
//#endregion
|
|
2297
|
+
//#region src/readers/readVtte.ts
|
|
2298
|
+
/**
|
|
2299
|
+
* Parse a WebVTT Empty Sample Box from an IsoView
|
|
2300
|
+
*
|
|
2301
|
+
* @returns A parsed WebVTT Empty Sample Box
|
|
2179
2302
|
*
|
|
2180
2303
|
* @public
|
|
2181
2304
|
*/
|
|
2182
|
-
function
|
|
2183
|
-
|
|
2184
|
-
|
|
2305
|
+
function readVtte(_) {
|
|
2306
|
+
return { type: "vtte" };
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
//#endregion
|
|
2310
|
+
//#region src/utils/isFullBox.ts
|
|
2311
|
+
/**
|
|
2312
|
+
* Check if a box is a full box
|
|
2313
|
+
*
|
|
2314
|
+
* @param box - The box to check
|
|
2315
|
+
*
|
|
2316
|
+
* @returns `true` if the box is a full box, `false` otherwise
|
|
2317
|
+
*
|
|
2318
|
+
* @public
|
|
2319
|
+
*/
|
|
2320
|
+
function isFullBox(box) {
|
|
2321
|
+
return "version" in box && "flags" in box;
|
|
2185
2322
|
}
|
|
2186
2323
|
|
|
2187
2324
|
//#endregion
|
|
@@ -2202,6 +2339,45 @@ function writeArdi(box) {
|
|
|
2202
2339
|
return writer;
|
|
2203
2340
|
}
|
|
2204
2341
|
|
|
2342
|
+
//#endregion
|
|
2343
|
+
//#region src/writers/writeAudioSampleEntryBox.ts
|
|
2344
|
+
/**
|
|
2345
|
+
* Write an AudioSampleEntryBox to an IsoDataWriter.
|
|
2346
|
+
*
|
|
2347
|
+
* ISO/IEC 14496-12:2012 - 12.2.3 Audio Sample Entry
|
|
2348
|
+
*
|
|
2349
|
+
* @param box - The AudioSampleEntryBox fields to write
|
|
2350
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2351
|
+
*
|
|
2352
|
+
* @returns An IsoDataWriter containing the encoded box
|
|
2353
|
+
*
|
|
2354
|
+
* @public
|
|
2355
|
+
*/
|
|
2356
|
+
function writeAudioSampleEntryBox(box, config) {
|
|
2357
|
+
const headerSize = 8;
|
|
2358
|
+
const reserved1Size = 6;
|
|
2359
|
+
const dataReferenceIndexSize = 2;
|
|
2360
|
+
const reserved2Size = 8;
|
|
2361
|
+
const channelcountSize = 2;
|
|
2362
|
+
const samplesizeSize = 2;
|
|
2363
|
+
const preDefinedSize = 2;
|
|
2364
|
+
const reserved3Size = 2;
|
|
2365
|
+
const samplerateSize = 4;
|
|
2366
|
+
const { bytes, size } = writeChildBoxes(box.boxes, config);
|
|
2367
|
+
const totalSize = headerSize + reserved1Size + dataReferenceIndexSize + reserved2Size + channelcountSize + samplesizeSize + preDefinedSize + reserved3Size + samplerateSize + size;
|
|
2368
|
+
const writer = new IsoBoxWriteView(box.type, totalSize);
|
|
2369
|
+
writer.writeArray(box.reserved1, UINT, 1, 6);
|
|
2370
|
+
writer.writeUint(box.dataReferenceIndex, 2);
|
|
2371
|
+
writer.writeArray(box.reserved2, UINT, 4, 2);
|
|
2372
|
+
writer.writeUint(box.channelcount, 2);
|
|
2373
|
+
writer.writeUint(box.samplesize, 2);
|
|
2374
|
+
writer.writeUint(box.preDefined, 2);
|
|
2375
|
+
writer.writeUint(box.reserved3, 2);
|
|
2376
|
+
writer.writeTemplate(box.samplerate, 4);
|
|
2377
|
+
writer.writeBytes(bytes);
|
|
2378
|
+
return writer;
|
|
2379
|
+
}
|
|
2380
|
+
|
|
2205
2381
|
//#endregion
|
|
2206
2382
|
//#region src/writers/writeVisualSampleEntryBox.ts
|
|
2207
2383
|
/**
|
|
@@ -2210,13 +2386,13 @@ function writeArdi(box) {
|
|
|
2210
2386
|
* ISO/IEC 14496-12:2012 - 12.1.3 Visual Sample Entry
|
|
2211
2387
|
*
|
|
2212
2388
|
* @param box - The VisualSampleEntryBox fields to write
|
|
2213
|
-
* @param
|
|
2389
|
+
* @param config - The configuration for the writer
|
|
2214
2390
|
*
|
|
2215
2391
|
* @returns An IsoDataWriter containing the encoded box
|
|
2216
2392
|
*
|
|
2217
2393
|
* @public
|
|
2218
2394
|
*/
|
|
2219
|
-
function writeVisualSampleEntryBox(box,
|
|
2395
|
+
function writeVisualSampleEntryBox(box, config) {
|
|
2220
2396
|
const headerSize = 8;
|
|
2221
2397
|
const reserved1Size = 6;
|
|
2222
2398
|
const dataReferenceIndexSize = 2;
|
|
@@ -2232,8 +2408,9 @@ function writeVisualSampleEntryBox(box, type) {
|
|
|
2232
2408
|
const compressorNameSize = 32;
|
|
2233
2409
|
const depthSize = 2;
|
|
2234
2410
|
const preDefined3Size = 2;
|
|
2235
|
-
const
|
|
2236
|
-
const
|
|
2411
|
+
const { bytes, size } = writeChildBoxes(box.boxes, config);
|
|
2412
|
+
const totalSize = headerSize + reserved1Size + dataReferenceIndexSize + preDefined1Size + reserved2Size + preDefined2Size + widthSize + heightSize + horizresolutionSize + vertresolutionSize + reserved3Size + frameCountSize + compressorNameSize + depthSize + preDefined3Size + size;
|
|
2413
|
+
const writer = new IsoBoxWriteView(box.type, totalSize);
|
|
2237
2414
|
writer.writeArray(box.reserved1, UINT, 1, 6);
|
|
2238
2415
|
writer.writeUint(box.dataReferenceIndex, 2);
|
|
2239
2416
|
writer.writeUint(box.preDefined1, 2);
|
|
@@ -2248,7 +2425,7 @@ function writeVisualSampleEntryBox(box, type) {
|
|
|
2248
2425
|
writer.writeArray(box.compressorName, UINT, 1, 32);
|
|
2249
2426
|
writer.writeUint(box.depth, 2);
|
|
2250
2427
|
writer.writeUint(box.preDefined3 & 65535, 2);
|
|
2251
|
-
writer.writeBytes(
|
|
2428
|
+
writer.writeBytes(bytes);
|
|
2252
2429
|
return writer;
|
|
2253
2430
|
}
|
|
2254
2431
|
|
|
@@ -2260,13 +2437,14 @@ function writeVisualSampleEntryBox(box, type) {
|
|
|
2260
2437
|
* ISO/IEC 14496-12:2012 - 12.1.3 Visual Sample Entry
|
|
2261
2438
|
*
|
|
2262
2439
|
* @param box - The VisualSampleEntryBox fields to write
|
|
2440
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2263
2441
|
*
|
|
2264
2442
|
* @returns An IsoDataWriter containing the encoded box
|
|
2265
2443
|
*
|
|
2266
2444
|
* @public
|
|
2267
2445
|
*/
|
|
2268
|
-
function writeAvc1(box) {
|
|
2269
|
-
return writeVisualSampleEntryBox(box,
|
|
2446
|
+
function writeAvc1(box, config) {
|
|
2447
|
+
return writeVisualSampleEntryBox(box, config);
|
|
2270
2448
|
}
|
|
2271
2449
|
|
|
2272
2450
|
//#endregion
|
|
@@ -2275,13 +2453,14 @@ function writeAvc1(box) {
|
|
|
2275
2453
|
* Write a VisualSampleEntryBox (avc2) to an IsoDataWriter.
|
|
2276
2454
|
*
|
|
2277
2455
|
* @param box - The VisualSampleEntryBox fields to write
|
|
2456
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2278
2457
|
*
|
|
2279
2458
|
* @returns An IsoDataWriter containing the encoded box
|
|
2280
2459
|
*
|
|
2281
2460
|
* @public
|
|
2282
2461
|
*/
|
|
2283
|
-
function writeAvc2(box) {
|
|
2284
|
-
return writeVisualSampleEntryBox(box,
|
|
2462
|
+
function writeAvc2(box, config) {
|
|
2463
|
+
return writeVisualSampleEntryBox(box, config);
|
|
2285
2464
|
}
|
|
2286
2465
|
|
|
2287
2466
|
//#endregion
|
|
@@ -2290,13 +2469,14 @@ function writeAvc2(box) {
|
|
|
2290
2469
|
* Write a VisualSampleEntryBox (avc3) to an IsoDataWriter.
|
|
2291
2470
|
*
|
|
2292
2471
|
* @param box - The VisualSampleEntryBox fields to write
|
|
2472
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2293
2473
|
*
|
|
2294
2474
|
* @returns An IsoDataWriter containing the encoded box
|
|
2295
2475
|
*
|
|
2296
2476
|
* @public
|
|
2297
2477
|
*/
|
|
2298
|
-
function writeAvc3(box) {
|
|
2299
|
-
return writeVisualSampleEntryBox(box,
|
|
2478
|
+
function writeAvc3(box, config) {
|
|
2479
|
+
return writeVisualSampleEntryBox(box, config);
|
|
2300
2480
|
}
|
|
2301
2481
|
|
|
2302
2482
|
//#endregion
|
|
@@ -2305,13 +2485,14 @@ function writeAvc3(box) {
|
|
|
2305
2485
|
* Write a VisualSampleEntryBox (avc4) to an IsoDataWriter.
|
|
2306
2486
|
*
|
|
2307
2487
|
* @param box - The VisualSampleEntryBox fields to write
|
|
2488
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2308
2489
|
*
|
|
2309
2490
|
* @returns An IsoDataWriter containing the encoded box
|
|
2310
2491
|
*
|
|
2311
2492
|
* @public
|
|
2312
2493
|
*/
|
|
2313
|
-
function writeAvc4(box) {
|
|
2314
|
-
return writeVisualSampleEntryBox(box,
|
|
2494
|
+
function writeAvc4(box, config) {
|
|
2495
|
+
return writeVisualSampleEntryBox(box, config);
|
|
2315
2496
|
}
|
|
2316
2497
|
|
|
2317
2498
|
//#endregion
|
|
@@ -2348,6 +2529,7 @@ function writeCtts(box) {
|
|
|
2348
2529
|
* Write a DataReferenceBox to an IsoDataWriter.
|
|
2349
2530
|
*
|
|
2350
2531
|
* @param box - The DataReferenceBox fields to write
|
|
2532
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2351
2533
|
*
|
|
2352
2534
|
* @returns An IsoDataWriter containing the encoded box
|
|
2353
2535
|
*
|
|
@@ -2358,12 +2540,11 @@ function writeDref(box, config) {
|
|
|
2358
2540
|
const fullBoxSize = 4;
|
|
2359
2541
|
const entryCountSize = 4;
|
|
2360
2542
|
const entryCount = box.entries.length;
|
|
2361
|
-
const
|
|
2362
|
-
const
|
|
2363
|
-
const writer = new IsoBoxWriteView("dref", headerSize + fullBoxSize + entryCountSize + entriesSize);
|
|
2543
|
+
const { bytes, size } = writeChildBoxes(box.entries, config);
|
|
2544
|
+
const writer = new IsoBoxWriteView("dref", headerSize + fullBoxSize + entryCountSize + size);
|
|
2364
2545
|
writer.writeFullBox(box.version, box.flags);
|
|
2365
2546
|
writer.writeUint(entryCount, 4);
|
|
2366
|
-
|
|
2547
|
+
writer.writeBytes(bytes);
|
|
2367
2548
|
return writer;
|
|
2368
2549
|
}
|
|
2369
2550
|
|
|
@@ -2469,33 +2650,14 @@ function writeEmsg(box) {
|
|
|
2469
2650
|
* Write an AudioSampleEntryBox (enca) to an IsoDataWriter.
|
|
2470
2651
|
*
|
|
2471
2652
|
* @param box - The AudioSampleEntryBox fields to write
|
|
2653
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2472
2654
|
*
|
|
2473
2655
|
* @returns An IsoDataWriter containing the encoded box
|
|
2474
2656
|
*
|
|
2475
2657
|
* @public
|
|
2476
2658
|
*/
|
|
2477
|
-
function writeEnca(box) {
|
|
2478
|
-
|
|
2479
|
-
const reserved1Size = 6;
|
|
2480
|
-
const dataReferenceIndexSize = 2;
|
|
2481
|
-
const reserved2Size = 8;
|
|
2482
|
-
const channelcountSize = 2;
|
|
2483
|
-
const samplesizeSize = 2;
|
|
2484
|
-
const preDefinedSize = 2;
|
|
2485
|
-
const reserved3Size = 2;
|
|
2486
|
-
const samplerateSize = 4;
|
|
2487
|
-
const esdsSize = box.esds.length;
|
|
2488
|
-
const writer = new IsoBoxWriteView("enca", headerSize + reserved1Size + dataReferenceIndexSize + reserved2Size + channelcountSize + samplesizeSize + preDefinedSize + reserved3Size + samplerateSize + esdsSize);
|
|
2489
|
-
writer.writeArray(box.reserved1, UINT, 1, 6);
|
|
2490
|
-
writer.writeUint(box.dataReferenceIndex, 2);
|
|
2491
|
-
writer.writeArray(box.reserved2, UINT, 4, 2);
|
|
2492
|
-
writer.writeUint(box.channelcount, 2);
|
|
2493
|
-
writer.writeUint(box.samplesize, 2);
|
|
2494
|
-
writer.writeUint(box.preDefined, 2);
|
|
2495
|
-
writer.writeUint(box.reserved3, 2);
|
|
2496
|
-
writer.writeTemplate(box.samplerate, 4);
|
|
2497
|
-
writer.writeBytes(box.esds);
|
|
2498
|
-
return writer;
|
|
2659
|
+
function writeEnca(box, config) {
|
|
2660
|
+
return writeAudioSampleEntryBox(box, config);
|
|
2499
2661
|
}
|
|
2500
2662
|
|
|
2501
2663
|
//#endregion
|
|
@@ -2504,13 +2666,14 @@ function writeEnca(box) {
|
|
|
2504
2666
|
* Write a VisualSampleEntryBox (encv) to an IsoDataWriter.
|
|
2505
2667
|
*
|
|
2506
2668
|
* @param box - The VisualSampleEntryBox fields to write
|
|
2669
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2507
2670
|
*
|
|
2508
2671
|
* @returns An IsoDataWriter containing the encoded box
|
|
2509
2672
|
*
|
|
2510
2673
|
* @public
|
|
2511
2674
|
*/
|
|
2512
|
-
function writeEncv(box) {
|
|
2513
|
-
return writeVisualSampleEntryBox(box,
|
|
2675
|
+
function writeEncv(box, config) {
|
|
2676
|
+
return writeVisualSampleEntryBox(box, config);
|
|
2514
2677
|
}
|
|
2515
2678
|
|
|
2516
2679
|
//#endregion
|
|
@@ -2611,13 +2774,14 @@ function writeHdlr(box) {
|
|
|
2611
2774
|
* Write a VisualSampleEntryBox (hev1) to an IsoDataWriter.
|
|
2612
2775
|
*
|
|
2613
2776
|
* @param box - The VisualSampleEntryBox fields to write
|
|
2777
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2614
2778
|
*
|
|
2615
2779
|
* @returns An IsoDataWriter containing the encoded box
|
|
2616
2780
|
*
|
|
2617
2781
|
* @public
|
|
2618
2782
|
*/
|
|
2619
|
-
function writeHev1(box) {
|
|
2620
|
-
return writeVisualSampleEntryBox(box,
|
|
2783
|
+
function writeHev1(box, config) {
|
|
2784
|
+
return writeVisualSampleEntryBox(box, config);
|
|
2621
2785
|
}
|
|
2622
2786
|
|
|
2623
2787
|
//#endregion
|
|
@@ -2626,13 +2790,14 @@ function writeHev1(box) {
|
|
|
2626
2790
|
* Write a VisualSampleEntryBox (hvc1) to an IsoDataWriter.
|
|
2627
2791
|
*
|
|
2628
2792
|
* @param box - The VisualSampleEntryBox fields to write
|
|
2793
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2629
2794
|
*
|
|
2630
2795
|
* @returns An IsoDataWriter containing the encoded box
|
|
2631
2796
|
*
|
|
2632
2797
|
* @public
|
|
2633
2798
|
*/
|
|
2634
|
-
function writeHvc1(box) {
|
|
2635
|
-
return writeVisualSampleEntryBox(box,
|
|
2799
|
+
function writeHvc1(box, config) {
|
|
2800
|
+
return writeVisualSampleEntryBox(box, config);
|
|
2636
2801
|
}
|
|
2637
2802
|
|
|
2638
2803
|
//#endregion
|
|
@@ -2806,14 +2971,19 @@ function writeMehd(box) {
|
|
|
2806
2971
|
* ISO/IEC 14496-12:2012 - 8.11.1 Meta Box
|
|
2807
2972
|
*
|
|
2808
2973
|
* @param box - The MetaBox fields to write
|
|
2974
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2809
2975
|
*
|
|
2810
2976
|
* @returns An IsoDataWriter containing the encoded box
|
|
2811
2977
|
*
|
|
2812
2978
|
* @public
|
|
2813
2979
|
*/
|
|
2814
|
-
function writeMeta(box) {
|
|
2815
|
-
const
|
|
2980
|
+
function writeMeta(box, config) {
|
|
2981
|
+
const headerSize = 8;
|
|
2982
|
+
const fullBoxSize = 4;
|
|
2983
|
+
const { bytes, size } = writeChildBoxes(box.boxes, config);
|
|
2984
|
+
const writer = new IsoBoxWriteView("meta", headerSize + fullBoxSize + size);
|
|
2816
2985
|
writer.writeFullBox(box.version, box.flags);
|
|
2986
|
+
writer.writeBytes(bytes);
|
|
2817
2987
|
return writer;
|
|
2818
2988
|
}
|
|
2819
2989
|
|
|
@@ -2870,28 +3040,8 @@ function writeMfro(box) {
|
|
|
2870
3040
|
*
|
|
2871
3041
|
* @public
|
|
2872
3042
|
*/
|
|
2873
|
-
function writeMp4a(box) {
|
|
2874
|
-
|
|
2875
|
-
const reserved1Size = 6;
|
|
2876
|
-
const dataReferenceIndexSize = 2;
|
|
2877
|
-
const reserved2Size = 8;
|
|
2878
|
-
const channelcountSize = 2;
|
|
2879
|
-
const samplesizeSize = 2;
|
|
2880
|
-
const preDefinedSize = 2;
|
|
2881
|
-
const reserved3Size = 2;
|
|
2882
|
-
const samplerateSize = 4;
|
|
2883
|
-
const esdsSize = box.esds.length;
|
|
2884
|
-
const writer = new IsoBoxWriteView("mp4a", headerSize + reserved1Size + dataReferenceIndexSize + reserved2Size + channelcountSize + samplesizeSize + preDefinedSize + reserved3Size + samplerateSize + esdsSize);
|
|
2885
|
-
writer.writeArray(box.reserved1, UINT, 1, 6);
|
|
2886
|
-
writer.writeUint(box.dataReferenceIndex, 2);
|
|
2887
|
-
writer.writeArray(box.reserved2, UINT, 4, 2);
|
|
2888
|
-
writer.writeUint(box.channelcount, 2);
|
|
2889
|
-
writer.writeUint(box.samplesize, 2);
|
|
2890
|
-
writer.writeUint(box.preDefined, 2);
|
|
2891
|
-
writer.writeUint(box.reserved3, 2);
|
|
2892
|
-
writer.writeTemplate(box.samplerate, 4);
|
|
2893
|
-
writer.writeBytes(box.esds);
|
|
2894
|
-
return writer;
|
|
3043
|
+
function writeMp4a(box, config) {
|
|
3044
|
+
return writeAudioSampleEntryBox(box, config);
|
|
2895
3045
|
}
|
|
2896
3046
|
|
|
2897
3047
|
//#endregion
|
|
@@ -2975,12 +3125,13 @@ function writePrft(box) {
|
|
|
2975
3125
|
* Write a PreselectionGroupBox to an IsoDataWriter.
|
|
2976
3126
|
*
|
|
2977
3127
|
* @param box - The PreselectionGroupBox fields to write
|
|
3128
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
2978
3129
|
*
|
|
2979
3130
|
* @returns An IsoDataWriter containing the encoded box
|
|
2980
3131
|
*
|
|
2981
3132
|
* @public
|
|
2982
3133
|
*/
|
|
2983
|
-
function writePrsl(box) {
|
|
3134
|
+
function writePrsl(box, config) {
|
|
2984
3135
|
const preselectionTagBytes = box.flags & 4096 && box.preselectionTag ? encodeText(box.preselectionTag) : null;
|
|
2985
3136
|
const interleavingTagBytes = box.flags & 16384 && box.interleavingTag ? encodeText(box.interleavingTag) : null;
|
|
2986
3137
|
const headerSize = 8;
|
|
@@ -2991,7 +3142,8 @@ function writePrsl(box) {
|
|
|
2991
3142
|
const preselectionTagSize = preselectionTagBytes ? preselectionTagBytes.length + 1 : 0;
|
|
2992
3143
|
const selectionPrioritySize = box.flags & 8192 ? 1 : 0;
|
|
2993
3144
|
const interleavingTagSize = interleavingTagBytes ? interleavingTagBytes.length + 1 : 0;
|
|
2994
|
-
const
|
|
3145
|
+
const { bytes, size } = writeChildBoxes(box.boxes, config);
|
|
3146
|
+
const writer = new IsoBoxWriteView("prsl", headerSize + fullBoxSize + groupIdSize + numEntitiesInGroupSize + entitiesSize + preselectionTagSize + selectionPrioritySize + interleavingTagSize + size);
|
|
2995
3147
|
writer.writeFullBox(box.version, box.flags);
|
|
2996
3148
|
writer.writeUint(box.groupId, 4);
|
|
2997
3149
|
writer.writeUint(box.numEntitiesInGroup, 4);
|
|
@@ -2999,6 +3151,7 @@ function writePrsl(box) {
|
|
|
2999
3151
|
if (preselectionTagBytes && box.preselectionTag) writer.writeUtf8TerminatedString(box.preselectionTag);
|
|
3000
3152
|
if (box.flags & 8192) writer.writeUint(box.selectionPriority ?? 0, 1);
|
|
3001
3153
|
if (interleavingTagBytes && box.interleavingTag) writer.writeUtf8TerminatedString(box.interleavingTag);
|
|
3154
|
+
writer.writeBytes(bytes);
|
|
3002
3155
|
return writer;
|
|
3003
3156
|
}
|
|
3004
3157
|
|
|
@@ -3227,6 +3380,7 @@ function writeSthd(box) {
|
|
|
3227
3380
|
* Write a SampleDescriptionBox to an IsoDataWriter.
|
|
3228
3381
|
*
|
|
3229
3382
|
* @param box - The SampleDescriptionBox fields to write
|
|
3383
|
+
* @param config - The IsoBoxWriteViewConfig to use
|
|
3230
3384
|
*
|
|
3231
3385
|
* @returns An IsoDataWriter containing the encoded box
|
|
3232
3386
|
*
|
|
@@ -3237,12 +3391,11 @@ function writeStsd(box, config) {
|
|
|
3237
3391
|
const fullBoxSize = 4;
|
|
3238
3392
|
const entryCountSize = 4;
|
|
3239
3393
|
const entryCount = box.entries.length;
|
|
3240
|
-
const
|
|
3241
|
-
const
|
|
3242
|
-
const writer = new IsoBoxWriteView("stsd", headerSize + fullBoxSize + entryCountSize + entriesSize);
|
|
3394
|
+
const { bytes, size } = writeChildBoxes(box.entries, config);
|
|
3395
|
+
const writer = new IsoBoxWriteView("stsd", headerSize + fullBoxSize + entryCountSize + size);
|
|
3243
3396
|
writer.writeFullBox(box.version, box.flags);
|
|
3244
3397
|
writer.writeUint(entryCount, 4);
|
|
3245
|
-
|
|
3398
|
+
writer.writeBytes(bytes);
|
|
3246
3399
|
return writer;
|
|
3247
3400
|
}
|
|
3248
3401
|
|
|
@@ -3712,5 +3865,5 @@ function writeVtte(_) {
|
|
|
3712
3865
|
}
|
|
3713
3866
|
|
|
3714
3867
|
//#endregion
|
|
3715
|
-
export { CONTAINERS, IsoBoxReadableStream, createIsoBoxReadableStream, isContainer, isFullBox, readArdi, readAvc1, readAvc2, readAvc3, readAvc4, readCtts, readDref, readElng, readElst, readEmsg, readEnca, readEncv, readFree, readFrma, readFtyp, readHdlr, readHev1, readHvc1, readIden, readImda, readIsoBoxes, readKind, readLabl, readMdat, readMdhd, readMehd, readMeta, readMfhd, readMfro, readMp4a, readMvhd, readPayl, readPrft, readPrsl, readPssh, readSchm, readSdtp, readSidx, readSkip, readSmhd, readSsix, readSthd, readStsd, readStss, readSttg, readStts, readStyp, readSubs, readTenc, readTfdt, readTfhd, readTfra, readTkhd, readTrex, readTrun, readUrl, readUrn, readVlab, readVmhd, readVttC, readVtte, traverseIsoBoxes, writeArdi, writeAvc1, writeAvc2, writeAvc3, writeAvc4, writeCtts, writeDref, writeElng, writeElst, writeEmsg, writeEnca, writeEncv, writeFree, writeFrma, writeFtyp, writeHdlr, writeHev1, writeHvc1, writeIden, writeImda, writeIsoBox, writeIsoBoxes, writeKind, writeLabl, writeMdat, writeMdhd, writeMehd, writeMeta, writeMfhd, writeMfro, writeMp4a, writeMvhd, writePayl, writePrft, writePrsl, writePssh, writeSchm, writeSdtp, writeSidx, writeSkip, writeSmhd, writeSsix, writeSthd, writeStsd, writeStss, writeSttg, writeStts, writeStyp, writeSubs, writeTenc, writeTfdt, writeTfhd, writeTfra, writeTkhd, writeTrex, writeTrun, writeUrl, writeUrn, writeVlab, writeVmhd, writeVttC, writeVtte };
|
|
3868
|
+
export { CONTAINERS, IsoBoxReadableStream, createAudioSampleEntryReader, createIsoBoxReadableStream, createVisualSampleEntryReader, filterIsoBoxes, findIsoBox, isContainer, isFullBox, readArdi, readAudioSampleEntryBox, readAvc1, readAvc2, readAvc3, readAvc4, readCtts, readDref, readElng, readElst, readEmsg, readEnca, readEncv, readFree, readFrma, readFtyp, readHdlr, readHev1, readHvc1, readIden, readImda, readIsoBoxes, readKind, readLabl, readMdat, readMdhd, readMehd, readMeta, readMfhd, readMfro, readMp4a, readMvhd, readPayl, readPrft, readPrsl, readPssh, readSchm, readSdtp, readSidx, readSkip, readSmhd, readSsix, readSthd, readStsd, readStss, readSttg, readStts, readStyp, readSubs, readTenc, readTfdt, readTfhd, readTfra, readTkhd, readTrex, readTrun, readUrl, readUrn, readVisualSampleEntryBox, readVlab, readVmhd, readVttC, readVtte, traverseIsoBoxes, writeArdi, writeAudioSampleEntryBox, writeAvc1, writeAvc2, writeAvc3, writeAvc4, writeCtts, writeDref, writeElng, writeElst, writeEmsg, writeEnca, writeEncv, writeFree, writeFrma, writeFtyp, writeHdlr, writeHev1, writeHvc1, writeIden, writeImda, writeIsoBox, writeIsoBoxes, writeKind, writeLabl, writeMdat, writeMdhd, writeMehd, writeMeta, writeMfhd, writeMfro, writeMp4a, writeMvhd, writePayl, writePrft, writePrsl, writePssh, writeSchm, writeSdtp, writeSidx, writeSkip, writeSmhd, writeSsix, writeSthd, writeStsd, writeStss, writeSttg, writeStts, writeStyp, writeSubs, writeTenc, writeTfdt, writeTfhd, writeTfra, writeTkhd, writeTrex, writeTrun, writeUrl, writeUrn, writeVisualSampleEntryBox, writeVlab, writeVmhd, writeVttC, writeVtte };
|
|
3716
3869
|
//# sourceMappingURL=index.js.map
|