( data: Uint8Array, boxOffset: number, boxSize: number, )
| 52 | // YouTube serves fMP4 audio with a sidx box that maps each fragment |
| 53 | // to a byte range and duration, which we need for MSE seeking. |
| 54 | export function parseSidx( |
| 55 | data: Uint8Array, |
| 56 | boxOffset: number, |
| 57 | boxSize: number, |
| 58 | ): { references: SegmentReference[]; timescale: number } { |
| 59 | const reader = new BinaryReader(data, boxOffset + BOX_HEADER_SIZE); |
| 60 | |
| 61 | const version = reader.readUint8(); |
| 62 | reader.skip(3); // flags |
| 63 | |
| 64 | reader.skip(4); // reference_ID |
| 65 | const timescale = reader.readUint32(); |
| 66 | |
| 67 | let firstOffset: number; |
| 68 | if (version === 0) { |
| 69 | reader.skip(4); // earliest_presentation_time (32-bit) |
| 70 | firstOffset = reader.readUint32(); |
| 71 | } else { |
| 72 | reader.skip(8); // earliest_presentation_time (64-bit) |
| 73 | firstOffset = reader.readUint64(); |
| 74 | } |
| 75 | |
| 76 | reader.skip(2); // reserved |
| 77 | const referenceCount = reader.readUint16(); |
| 78 | |
| 79 | let byteOffset = boxOffset + boxSize + firstOffset; |
| 80 | let timeOffset = 0; |
| 81 | const references: SegmentReference[] = []; |
| 82 | |
| 83 | for (let index = 0; index < referenceCount; index++) { |
| 84 | const referencedSize = reader.readUint32() & 0x7fffffff; |
| 85 | const subsegmentDuration = reader.readUint32(); |
| 86 | reader.skip(4); // starts_with_SAP + SAP_type + SAP_delta_time |
| 87 | |
| 88 | const startByte = byteOffset; |
| 89 | const endByte = byteOffset + referencedSize - 1; |
| 90 | const startTime = timeOffset / timescale; |
| 91 | const endTime = (timeOffset + subsegmentDuration) / timescale; |
| 92 | |
| 93 | references.push({ startByte, endByte, startTime, endTime }); |
| 94 | |
| 95 | byteOffset += referencedSize; |
| 96 | timeOffset += subsegmentDuration; |
| 97 | } |
| 98 | |
| 99 | return { references, timescale }; |
| 100 | } |
| 101 | |
| 102 | export function parseInitSegment(data: Uint8Array): Fmp4Index { |
| 103 | const boxes = findBoxes(data); |
no test coverage detected