UNPKG

rx-player

Version:
110 lines (102 loc) 3.47 kB
/** * Copyright 2015 CANAL+ Group * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { getMDHDTimescale, takePSSHOut } from "../../parsers/containers/isobmff"; import { getKeyIdFromInitSegment } from "../../parsers/containers/isobmff/utils"; import { getTimeCodeScale } from "../../parsers/containers/matroska"; import type { IProtectionDataInfo, ISegmentContext, ISegmentParserParsedInitChunk, ISegmentParserParsedMediaChunk, } from "../types"; import getISOBMFFTimingInfos from "../utils/get_isobmff_timing_infos"; import inferSegmentContainer from "../utils/infer_segment_container"; export default function segmentParser( loadedSegment: { data: ArrayBuffer | Uint8Array<ArrayBuffer> | null; isChunked: boolean; }, context: ISegmentContext, initTimescale: number | undefined, ): | ISegmentParserParsedInitChunk<ArrayBuffer | Uint8Array<ArrayBuffer> | null> | ISegmentParserParsedMediaChunk<ArrayBuffer | Uint8Array<ArrayBuffer> | null> { const { segment, periodStart, periodEnd } = context; const { data } = loadedSegment; const appendWindow: [number, number | undefined] = [periodStart, periodEnd]; if (data === null) { if (segment.isInit) { return { segmentType: "init", initializationData: null, initializationDataSize: 0, protectionData: [], initTimescale: undefined, }; } return { segmentType: "media", chunkData: null, chunkSize: 0, chunkInfos: null, chunkOffset: 0, protectionData: [], appendWindow, }; } const chunkData = new Uint8Array(data); const containerType = inferSegmentContainer(context.type, context.mimeType); // TODO take a look to check if this is an ISOBMFF/webm? const seemsToBeMP4 = containerType === "mp4" || containerType === undefined; const protectionData: IProtectionDataInfo[] = []; if (seemsToBeMP4) { const psshInfo = takePSSHOut(chunkData); let keyId; if (segment.isInit) { keyId = getKeyIdFromInitSegment(chunkData) ?? undefined; } if (psshInfo.length > 0 || keyId !== undefined) { protectionData.push({ initDataType: "cenc", keyId, initData: psshInfo }); } } if (segment.isInit) { const timescale = containerType === "webm" ? getTimeCodeScale(chunkData, 0) : // assume ISOBMFF-compliance getMDHDTimescale(chunkData); return { segmentType: "init", initializationData: chunkData, initializationDataSize: 0, initTimescale: timescale ?? undefined, protectionData, }; } const chunkInfos = seemsToBeMP4 ? getISOBMFFTimingInfos(chunkData, false, segment, initTimescale) : null; // TODO extract time info from webm const chunkOffset = segment.timestampOffset ?? 0; return { segmentType: "media", chunkData, chunkSize: chunkData.length, chunkInfos, chunkOffset, protectionData, appendWindow, }; }