Files
v10/dist/dev/media/mp4/box.js
T

58 lines
2.0 KiB
JavaScript

//#region src/media/mp4/box.ts
function toDataView(data) {
return data instanceof Uint8Array ? new DataView(data.buffer, data.byteOffset, data.byteLength) : new DataView(data);
}
/** Read a 4-character box type / FourCC at `offset`. */
function readFourCC(view, offset) {
return String.fromCharCode(view.getUint8(offset), view.getUint8(offset + 1), view.getUint8(offset + 2), view.getUint8(offset + 3));
}
/** Iterate the boxes directly contained in `[start, end)`. */
function* iterateBoxes(view, start = 0, end = view.byteLength) {
let offset = start;
while (offset + 8 <= end) {
let size = view.getUint32(offset);
const type = readFourCC(view, offset + 4);
let dataStart = offset + 8;
if (size === 1) {
size = Number(view.getBigUint64(offset + 8));
dataStart = offset + 16;
} else if (size === 0) size = end - offset;
if (size < dataStart - offset) return;
yield {
type,
start: offset,
dataStart,
end: offset + size
};
offset += size;
}
}
/** Iterate the direct child boxes of a given `type` within `[start, end)`. */
function* iterateBoxesOfType(view, type, start = 0, end = view.byteLength) {
for (const box of iterateBoxes(view, start, end)) if (box.type === type) yield box;
}
/**
* Depth-first descent to the first box matching a nested path, e.g.
* `['moov', 'trak', 'mdia', 'mdhd']`. Returns `undefined` if any level is
* absent.
*/
function findBox(view, path, start = 0, end = view.byteLength) {
const [head, ...rest] = path;
for (const box of iterateBoxes(view, start, end)) {
if (box.type !== head) continue;
if (rest.length === 0) return box;
const found = findBox(view, rest, box.dataStart, box.end);
if (found) return found;
}
}
/**
* Read the version byte of a FullBox — the `version(1) + flags(3)` header at the
* start of the payload of `mdhd` / `tkhd` / `tfdt` / `hdlr` / `elst` / etc.
*/
function readFullBoxVersion(view, dataStart) {
return view.getUint8(dataStart);
}
//#endregion
export { findBox, iterateBoxes, iterateBoxesOfType, readFourCC, readFullBoxVersion, toDataView };
//# sourceMappingURL=box.js.map