mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
58 lines
2.0 KiB
JavaScript
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
|