@@ -1,7 +1,7 @@ | |||||
import * as WaveformPlaylist from 'waveform-playlist'; | import * as WaveformPlaylist from 'waveform-playlist'; | ||||
import delay from 'delay'; | import delay from 'delay'; | ||||
import parseMediaFragmentIdentifier from '../util/parse-media-fragment-identifier.js'; | |||||
import { parseMediaFragmentIdentifier } from '../util/media-fragment-identifier.js'; | |||||
async function init() { | async function init() { | ||||
document.body.innerHTML = ` | document.body.innerHTML = ` | ||||
@@ -1,8 +1,20 @@ | |||||
// Parses the time range from a media fragment identifier such as '#t=12.5,1:59:45.12'. | |||||
// Functions for parsing and creating a media fragment identifiers. | |||||
// A media fragment is used to specify a time range of an audio/video track, e.g. #t=12,18.5. | |||||
// See https://www.w3.org/TR/media-frags/ | // See https://www.w3.org/TR/media-frags/ | ||||
// Note this only supports npt (normal playing time) format, not smpte or wall clock time. | |||||
// Creates a media fragment identifier for a given time range (in seconds). | |||||
export function createMediaFragmentIdentifier({ start, end }) { | |||||
// Always output the time in seconds, as it is more widely supported than h:m:s syntax. | |||||
const maybeStart = start !== undefined ? start : ''; | |||||
const maybeEnd = end !== undefined ? `,${end}` : ''; | |||||
const fragmentIdentifier = `t=${maybeStart}${maybeEnd}`; | |||||
return fragmentIdentifier; | |||||
} | |||||
// Parses the time range from a media fragment identifier. | |||||
// Returns an object { start, end }; both numbers are given in seconds (possibly non-integer). | // Returns an object { start, end }; both numbers are given in seconds (possibly non-integer). | ||||
export default function parseMediaFragmentIdentifier(fragmentIdentifier) { | |||||
// Note this only supports the usual npt (normal playing time) format, not smpte or wall clock time. | |||||
export function parseMediaFragmentIdentifier(fragmentIdentifier) { | |||||
// Strip possible leading hash character '#'. | // Strip possible leading hash character '#'. | ||||
if (fragmentIdentifier.startsWith('#')) { | if (fragmentIdentifier.startsWith('#')) { | ||||
fragmentIdentifier = fragmentIdentifier.substring(1); | fragmentIdentifier = fragmentIdentifier.substring(1); |
@@ -1,8 +1,18 @@ | |||||
import test from 'ava'; | import test from 'ava'; | ||||
import parse from './parse-media-fragment-identifier.js'; | |||||
import { | |||||
createMediaFragmentIdentifier, | |||||
parseMediaFragmentIdentifier, | |||||
} from './media-fragment-identifier.js'; | |||||
const inputResultPairs = { | |||||
const creatorResultInputPairs = { | |||||
't=12.345,67.89': { start: 12.345, end: 67.89 }, | |||||
't=,67.89': { end: 67.89 }, | |||||
't=0,67.89': { start: 0, end: 67.89 }, | |||||
't=12.345': { start: 12.345 }, | |||||
}; | |||||
const parserInputResultPairs = { | |||||
't=1,2': { start: 1, end: 2 }, | 't=1,2': { start: 1, end: 2 }, | ||||
't=npt:1,2': { start: 1, end: 2 }, | 't=npt:1,2': { start: 1, end: 2 }, | ||||
't=,2': { start: 0, end: 2 }, | 't=,2': { start: 0, end: 2 }, | ||||
@@ -27,10 +37,18 @@ const inputResultPairs = { | |||||
't=10%2C20': { start: 10, end: 20 }, | 't=10%2C20': { start: 10, end: 20 }, | ||||
't=%6ept:10': { start: 10, end: undefined }, | 't=%6ept:10': { start: 10, end: undefined }, | ||||
't=npt%3a10': { start: 10, end: undefined }, | 't=npt%3a10': { start: 10, end: undefined }, | ||||
}; | |||||
// Test creating. | |||||
for (const [expectedResult, input] of Object.entries(creatorResultInputPairs)) { | |||||
test(`Correctly create fragment '${expectedResult}'`, t => { | |||||
t.is(createMediaFragmentIdentifier(input), expectedResult); | |||||
}); | |||||
} | } | ||||
for (const [input, expectedResult] of Object.entries(inputResultPairs)) { | |||||
// Test parsing. | |||||
for (const [input, expectedResult] of Object.entries(parserInputResultPairs)) { | |||||
test(`Correctly parse input '${input}'`, t => { | test(`Correctly parse input '${input}'`, t => { | ||||
t.deepEqual(parse(input), expectedResult); | |||||
t.deepEqual(parseMediaFragmentIdentifier(input), expectedResult); | |||||
}); | }); | ||||
} | } |