|
1234567891011121314151617181920212223242526272829303132333435363738 |
- // Parses the time range from a media fragment identifier such as '#t=12.5,1:59:45.12'.
- // See https://www.w3.org/TR/media-frags/
- // Note this only supports npt (normal playing time) format, not smpte or wall clock time.
- // Returns an object { start, end }; both numbers are given in seconds (possibly non-integer).
- export default function parseMediaFragmentIdentifier(fragmentIdentifier) {
- // Strip possible leading hash character '#'.
- if (fragmentIdentifier.startsWith('#')) {
- fragmentIdentifier = fragmentIdentifier.substring(1);
- }
-
- const temporalDimensionRegex = /(?:^|&)(?:t|%74)=([^&]+)(?=&|$)/g;
- const temporalDimensionMatches = [...fragmentIdentifier.matchAll(temporalDimensionRegex)];
- if (temporalDimensionMatches.length === 0) {
- throw new Error('No time dimension defined');
- }
- // If there are multiple occurrences (e.g. t=1&t=2), take the last one.
- const temporalDimensionMatch = temporalDimensionMatches[temporalDimensionMatches.length - 1];
- const temporalDimensionValue = decodeURIComponent(temporalDimensionMatch[1]);
-
- const nptRegex = /^(?:npt:)?(?:(?:(\d+):)??(?:(\d+):)?(\d+(?:\.\d*)?))?(?:,(?:(\d+):)??(?:(\d+):)?(\d+(?:\.\d*)?))?$/;
- const nptMatch = temporalDimensionValue.match(nptRegex);
- if (!nptMatch) {
- throw new Error('Unable to parse fragment identifier.');
- }
-
- const start = (nptMatch[3] ? Number.parseFloat(nptMatch[3]) : 0)
- + (nptMatch[2] ? Number.parseInt(nptMatch[2]) * 60 : 0)
- + (nptMatch[1] ? Number.parseInt(nptMatch[1]) * 60 * 60 : 0);
-
- let end;
- if (nptMatch[6]) {
- end = Number.parseFloat(nptMatch[6])
- + (nptMatch[5] ? Number.parseInt(nptMatch[5]) * 60 : 0)
- + (nptMatch[4] ? Number.parseInt(nptMatch[4]) * 60 * 60 : 0);
- }
-
- return { start, end };
- }
|