c30a0cfa by David LaPalomento

Fix variant switching media index test

The original test was invoking the playlist reload callback which tested whether the media index was updating correctly after a refresh. Now, the test correctly triggers the a variant switch after downloading a segment. Consolidated media index update code and ensured state is properly updated after a switch.
1 parent 736b7c35
......@@ -123,6 +123,42 @@ var
},
/**
* Determine the media index in one playlist that corresponds to a
* specified media index in another. This function can be used to
* calculate a new segment position when a playlist is reloaded or a
* variant playlist is becoming active.
* @param mediaIndex {number} the index into the original playlist
* to translate
* @param original {object} the playlist to translate the media
* index from
* @param update {object} the playlist to translate the media index
* to
* @param {number} the corresponding media index in the updated
* playlist
*/
findCorrespondingMediaIndex = function(mediaIndex, original, update) {
var
i = update.segments.length,
originalSegment;
// no segments have been loaded from the original playlist
if (mediaIndex === 0) {
return 0;
}
// try to sync based on URI
originalSegment = original.segments[mediaIndex - 1];
while (i--) {
if (originalSegment.uri === update.segments[i].uri) {
return i + 1;
}
}
// sync on media sequence
return (original.mediaSequence + mediaIndex) - update.mediaSequence;
},
/**
* Calculate the total duration for a playlist based on segment metadata.
* @param playlist {object} a media playlist object
* @return {number} the currently known duration, in seconds
......@@ -316,6 +352,10 @@ var
mediaSequence > (playlist.mediaSequence || 0) + playlist.segments.length) {
downloadPlaylist(resolveUrl(srcUrl, playlist.uri));
} else {
player.hls.mediaIndex =
findCorrespondingMediaIndex(player.hls.mediaIndex,
player.hls.media,
playlist);
player.hls.media = playlist;
// update the duration
......@@ -411,27 +451,7 @@ var
var xhr = new window.XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = function() {
var i, parser, playlist, playlistUri, refreshDelay,
updateMediaIndex = function(original, update) {
var
i = update.segments.length,
updatedIndex = 0,
originalSegment;
// no segments have been loaded from the original playlist
if (player.hls.mediaIndex === 0) {
return;
}
originalSegment = original.segments[player.hls.mediaIndex - 1];
while (i--) {
if (originalSegment.uri === update.segments[i].uri) {
updatedIndex = i + 1;
break;
}
}
player.hls.mediaIndex = updatedIndex;
};
var i, parser, playlist, playlistUri, refreshDelay;
// wait until the request completes
if (xhr.readyState !== 4) {
......@@ -487,7 +507,11 @@ var
// determine the new mediaIndex if we're updating the
// current media playlist
updateMediaIndex(playlist, parser.manifest);
player.hls.mediaIndex =
findCorrespondingMediaIndex(player.hls.mediaIndex,
playlist,
parser.manifest);
player.hls.media = parser.manifest;
}
}
} else {
......
......@@ -991,7 +991,7 @@ test('updates the media index when a playlist reloads', function() {
'3.ts\n';
callback();
strictEqual(2, player.hls.mediaIndex, 'mediaIndex is updated after the reload');
strictEqual(player.hls.mediaIndex, 2, 'mediaIndex is updated after the reload');
});
test('mediaIndex is zero before the first segment loads', function() {
......@@ -1012,42 +1012,39 @@ test('mediaIndex is zero before the first segment loads', function() {
});
test('reloads out-of-date live playlists when switching variants', function() {
var callback;
// capture timeouts
window.setTimeout = function(cb) {
callback = cb;
};
player.hls('http://example.com/master.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
type: 'sourceopen'
});
// playing segment 15 on playlist 0
player.hls.master = {
playlists: [{
mediaSequence: 15,
segments: [{}, {}]
segments: [1, 1, 1]
}, {
uri: 'http://example.com/variant-update.m3u8',
mediaSequence: 0,
segments: [{}, {}]
segments: [1, 1]
}]
};
// playing segment 15 on playlist zero
player.hls.media = player.hls.master.playlists[0];
player.mediaIndex = 0;
player.mediaIndex = 1;
window.manifests['variant-update'] = '#EXTM3U\n' +
'#EXT-X-MEDIA-SEQUENCE:16\n' +
'#EXTINF:10,\n' +
'16.ts\n';
'16.ts\n' +
'#EXTINF:10,\n' +
'17.ts\n';
// switch playlists
player.hls.selectPlaylist = function() {
return player.hls.master.playlists[1];
};
// timeupdate downloads segment 16 then switches playlists
player.trigger('timeupdate');
ok(callback, 'reload is scheduled');
strictEqual(player.mediaIndex, 1, 'mediaIndex points at the next segment');
});
})(window, window.videojs);
......