5448f63f by David LaPalomento

Duration should be infinity for live playlists

Unless an explicit total duration tag is present in the playlist, set the duration to Infinity for live HLS. Document iOS behavior for live streams.
1 parent 83a9f86f
# Live HLS Research
This document is a collection of notes on Live HLS implementations in the wild.
There are two varieties of Live HLS. In the first, playlists are
persistent and strictly appended to. In the alternative form, the
maximum number of segments in a playlist is relatively stable and an
old segment is removed every time a new segment becomes available.
On iOS devices, both stream types report a duration of `Infinity`. The
`currentTime` is equal to the amount of the stream that has been
played back on the device.
## Akamai HD2
## OnceLIVE
"Sliding window" live streams.
### Variant Playlists
Once variant playlists look like standard HLS variant playlists.
......
......@@ -132,6 +132,11 @@ var
duration = 0,
i = playlist.segments.length,
segment;
// duration should be Infinity for live playlists
if (!playlist.endList) {
return window.Infinity;
}
while (i--) {
segment = playlist.segments[i];
duration += segment.duration || playlist.targetDuration || 0;
......
......@@ -181,13 +181,15 @@ test('calculates the duration if needed', function() {
}
durations.push(duration);
};
player.hls('http://example.com/manifest/liveMissingSegmentDuration.m3u8');
player.hls('http://example.com/manifest/missingExtinf.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
type: 'sourceopen'
});
strictEqual(durations.length, 1, 'duration is set');
strictEqual(durations[0], 6.64 + (2 * 8), 'duration is calculated');
strictEqual(durations[0],
player.hls.media.segments.length * 10,
'duration is calculated');
});
test('starts downloading a segment on loadedmetadata', function() {
......@@ -890,6 +892,15 @@ test('reloads live playlists', function() {
'waited one target duration');
});
test('duration is Infinity for live playlists', function() {
player.hls('manifest/missingEndlist.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
type: 'sourceopen'
});
strictEqual(Infinity, player.duration(), 'duration is infinity');
});
test('does not reload playlists with an endlist tag', function() {
var callbacks = [];
// capture timeouts
......