fcebc231 by David LaPalomento

Abort key XHRs on media change

If a key request was outstanding when the media playlist changed, the call to fetchKeys() for the new playlist would be ignored. This caused segments to get stuck in drainBuffer() waiting for their keys. Now, we abort key requests as soon as we change media and immediately try to fetch the keys for the new playlist.
1 parent 4dc56848
......@@ -127,9 +127,16 @@ videojs.Hls.prototype.handleSourceOpen = function() {
this.fetchKeys(updatedPlaylist, this.mediaIndex);
}));
this.playlists.on('mediachange', function() {
this.playlists.on('mediachange', videojs.bind(this, function() {
// abort outstanding key requests and check if new keys need to be retrieved
if (keyXhr) {
keyXhr.abort();
keyXhr = null;
this.fetchKeys(this.playlists.media(), this.mediaIndex);
}
player.trigger('mediachange');
});
}));
// if autoplay is enabled, begin playback. This is duplicative of
// code in video.js but is required because play() must be invoked
......
......@@ -1626,4 +1626,42 @@ test('supplies the media sequence of current segment as the IV by default, if no
'the IV for the segment is the media sequence');
});
test('switching playlists with an outstanding key request does not stall playback', function() {
var media = '#EXTM3U\n' +
'#EXT-X-MEDIA-SEQUENCE:5\n' +
'#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52"\n' +
'#EXTINF:2.833,\n' +
'http://media.example.com/fileSequence52-A.ts\n' +
'#EXTINF:15.0,\n' +
'http://media.example.com/fileSequence52-B.ts\n';
player.src({
src: 'https://example.com/master.m3u8',
type: 'application/vnd.apple.mpegurl'
});
openMediaSource(player);
// master playlist
standardXHRResponse(requests.shift());
// media playlist
requests.shift().respond(200, null, media);
// mock out media switching from this point on
player.hls.playlists.media = function() {
return player.hls.playlists.master.playlists[0];
};
// don't respond to the initial key request
requests.shift();
// first segment of the original media playlist
standardXHRResponse(requests.shift());
// "switch" media
player.hls.playlists.trigger('mediachange');
player.trigger('timeupdate');
ok(requests.length, 'made a request');
equal(requests[0].url,
'https://priv.example.com/key.php?r=52',
'requested the segment and key');
});
})(window, window.videojs);
......