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