//#region src/media/text/parse-vtt-timestamp-map.ts const TIMESTAMP_MAP_PREFIX = "X-TIMESTAMP-MAP="; /** * Scrape a WebVTT segment's `X-TIMESTAMP-MAP` header into a {@link TimestampMap} * — the only header line we need to correlate LOCAL cue times with the media * presentation timeline. Deliberately *not* a WebVTT parser: cue parsing stays * with the browser's native `` parser (which drops this line); this reads * just the one header field the native path discards. * * Returns `undefined` when the segment carries no map (e.g. cues already in * absolute presentation time) — per the HLS spec that means LOCAL 0 maps to * MPEGTS 0. Tolerant of attribute order and `[HH:]MM:SS.mmm` LOCAL forms. */ function parseVttTimestampMap(text) { const timestampMapLine = text.split(/\r\n|\r|\n/).find((line) => line.startsWith(TIMESTAMP_MAP_PREFIX)); return timestampMapLine ? parseTimestampMapBody(timestampMapLine.slice(16)) : void 0; } const TimeStampMapParserMap = { LOCAL: parseWebVttTimestamp, MPEGTS: (v) => +v }; function parseTimestampMapBody(body) { return Object.fromEntries(body.split(",").map((kvStr) => { const [k, v] = kvStr.split(/:(.*)/).map((kOrV) => kOrV.trim()); return [k?.toLowerCase(), TimeStampMapParserMap[k](v)]; })); } /** Seconds-per-unit for the `[HH:]MM:SS.mmm` parts, right-aligned so a missing HH just drops the leading weight. */ const VTT_TIMESTAMP_WEIGHTS = [ 3600, 60, 1, .001 ]; function parseWebVttTimestamp(value) { const parts = value.split(/[:.]/); return parts.reduce((acc, val, i) => acc + +val * (VTT_TIMESTAMP_WEIGHTS[i + 4 - parts.length] ?? 0), 0); } //#endregion export { parseVttTimestampMap }; //# sourceMappingURL=parse-vtt-timestamp-map.js.map