|
@ -570,7 +570,7 @@ function(assert) { |
|
|
|
|
|
|
|
|
assert.equal(error.code, 2, 'error has correct code'); |
|
|
assert.equal(error.code, 2, 'error has correct code'); |
|
|
assert.equal(error.message, |
|
|
assert.equal(error.message, |
|
|
'HLS playlist request error at URL: manifest/master.m3u8', |
|
|
|
|
|
|
|
|
'HLS playlist request error at URL: manifest/master.m3u8.', |
|
|
'error has correct message'); |
|
|
'error has correct message'); |
|
|
assert.equal(errLogs.length, 1, 'logged an error'); |
|
|
assert.equal(errLogs.length, 1, 'logged an error'); |
|
|
|
|
|
|
|
@ -1237,6 +1237,45 @@ QUnit.test('segment 404 should trigger blacklisting of media', function(assert) |
|
|
assert.equal(this.player.tech_.hls.stats.bandwidth, 20000, 'bandwidth set above'); |
|
|
assert.equal(this.player.tech_.hls.stats.bandwidth, 20000, 'bandwidth set above'); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
QUnit.test('unsupported playlist should not be re-included when excluding last playlist', function(assert) { |
|
|
|
|
|
this.player.src({ |
|
|
|
|
|
src: 'manifest/master.m3u8', |
|
|
|
|
|
type: 'application/vnd.apple.mpegurl' |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
this.clock.tick(1); |
|
|
|
|
|
|
|
|
|
|
|
openMediaSource(this.player, this.clock); |
|
|
|
|
|
|
|
|
|
|
|
this.player.tech_.hls.bandwidth = 1; |
|
|
|
|
|
// master
|
|
|
|
|
|
this.requests.shift() |
|
|
|
|
|
.respond(200, null, |
|
|
|
|
|
'#EXTM3U\n' + |
|
|
|
|
|
'#EXT-X-STREAM-INF:BANDWIDTH=1,CODECS="avc1.4d400d,mp4a.40.2"\n' + |
|
|
|
|
|
'media.m3u8\n' + |
|
|
|
|
|
'#EXT-X-STREAM-INF:BANDWIDTH=10,CODECS="avc1.4d400d,not-an-audio-codec"\n' + |
|
|
|
|
|
'media1.m3u8\n'); |
|
|
|
|
|
// media
|
|
|
|
|
|
this.standardXHRResponse(this.requests.shift()); |
|
|
|
|
|
|
|
|
|
|
|
let master = this.player.tech_.hls.playlists.master; |
|
|
|
|
|
let media = this.player.tech_.hls.playlists.media_; |
|
|
|
|
|
|
|
|
|
|
|
// segment
|
|
|
|
|
|
this.requests.shift().respond(400); |
|
|
|
|
|
|
|
|
|
|
|
assert.ok(master.playlists[0].excludeUntil > 0, 'original media excluded for some time'); |
|
|
|
|
|
assert.strictEqual(master.playlists[1].excludeUntil, |
|
|
|
|
|
Infinity, |
|
|
|
|
|
'blacklisted invalid audio codec'); |
|
|
|
|
|
|
|
|
|
|
|
assert.equal(this.env.log.warn.calls, 2, 'warning logged for blacklist'); |
|
|
|
|
|
assert.equal(this.env.log.warn.args[0], |
|
|
|
|
|
'Removing all playlists from the blacklist because the last rendition is about to be blacklisted.', |
|
|
|
|
|
'log generic error message'); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
QUnit.test('playlist 404 should blacklist media', function(assert) { |
|
|
QUnit.test('playlist 404 should blacklist media', function(assert) { |
|
|
let media; |
|
|
let media; |
|
|
let url; |
|
|
let url; |
|
@ -1281,7 +1320,7 @@ QUnit.test('playlist 404 should blacklist media', function(assert) { |
|
|
assert.ok(media.excludeUntil > 0, 'original media blacklisted for some time'); |
|
|
assert.ok(media.excludeUntil > 0, 'original media blacklisted for some time'); |
|
|
assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist'); |
|
|
assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist'); |
|
|
assert.equal(this.env.log.warn.args[0], |
|
|
assert.equal(this.env.log.warn.args[0], |
|
|
'Problem encountered with the current HLS playlist. HLS playlist request error at URL: media.m3u8 Switching to another playlist.', |
|
|
|
|
|
|
|
|
'Problem encountered with the current HLS playlist. HLS playlist request error at URL: media.m3u8. Switching to another playlist.', |
|
|
'log generic error message'); |
|
|
'log generic error message'); |
|
|
assert.equal(blacklistplaylist, 1, 'there is one blacklisted playlist'); |
|
|
assert.equal(blacklistplaylist, 1, 'there is one blacklisted playlist'); |
|
|
assert.equal(hlsRenditionBlacklistedEvents, 1, 'an hls-rendition-blacklisted event was fired'); |
|
|
assert.equal(hlsRenditionBlacklistedEvents, 1, 'an hls-rendition-blacklisted event was fired'); |
|
@ -1292,27 +1331,36 @@ QUnit.test('playlist 404 should blacklist media', function(assert) { |
|
|
url = this.requests[2].url.slice(this.requests[2].url.lastIndexOf('/') + 1); |
|
|
url = this.requests[2].url.slice(this.requests[2].url.lastIndexOf('/') + 1); |
|
|
media = this.player.tech_.hls.playlists.master.playlists[url]; |
|
|
media = this.player.tech_.hls.playlists.master.playlists[url]; |
|
|
|
|
|
|
|
|
// media wasn't blacklisted because it's final rendition
|
|
|
|
|
|
assert.ok(!media.excludeUntil, 'media not blacklisted after playlist 404'); |
|
|
|
|
|
assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist'); |
|
|
|
|
|
|
|
|
assert.ok(media.excludeUntil > 0, 'second media was blacklisted after playlist 404'); |
|
|
|
|
|
assert.equal(this.env.log.warn.calls, 2, 'warning logged for blacklist'); |
|
|
assert.equal(this.env.log.warn.args[1], |
|
|
assert.equal(this.env.log.warn.args[1], |
|
|
'Problem encountered with the current HLS playlist. Trying again since it is the final playlist.', |
|
|
|
|
|
'log specific error message for final playlist'); |
|
|
|
|
|
assert.equal(retryplaylist, 1, 'retried final playlist for once'); |
|
|
|
|
|
assert.equal(blacklistplaylist, 1, 'there is one blacklisted playlist'); |
|
|
|
|
|
assert.equal(hlsRenditionBlacklistedEvents, 1, 'an hls-rendition-blacklisted event was fired'); |
|
|
|
|
|
|
|
|
'Removing all playlists from the blacklist because the last rendition is about to be blacklisted.', |
|
|
|
|
|
'log generic error message'); |
|
|
|
|
|
assert.equal(this.env.log.warn.args[2], |
|
|
|
|
|
'Problem encountered with the current HLS playlist. HLS playlist request error at URL: media1.m3u8. ' + |
|
|
|
|
|
'Switching to another playlist.', |
|
|
|
|
|
'log generic error message'); |
|
|
|
|
|
assert.equal(retryplaylist, 1, 'fired a retryplaylist event'); |
|
|
|
|
|
assert.equal(blacklistplaylist, 2, 'media1 is blacklisted'); |
|
|
|
|
|
|
|
|
this.clock.tick(2 * 1000); |
|
|
this.clock.tick(2 * 1000); |
|
|
// no new request was made since it hasn't been half the segment duration
|
|
|
// no new request was made since it hasn't been half the segment duration
|
|
|
assert.strictEqual(3, this.requests.length, 'no new request was made'); |
|
|
assert.strictEqual(3, this.requests.length, 'no new request was made'); |
|
|
|
|
|
|
|
|
this.clock.tick(3 * 1000); |
|
|
this.clock.tick(3 * 1000); |
|
|
// continue loading the final remaining playlist after it wasn't blacklisted
|
|
|
|
|
|
|
|
|
// loading the first playlist since the blacklist duration was cleared
|
|
|
// when half the segment duaration passed
|
|
|
// when half the segment duaration passed
|
|
|
|
|
|
|
|
|
assert.strictEqual(4, this.requests.length, 'one more request was made'); |
|
|
assert.strictEqual(4, this.requests.length, 'one more request was made'); |
|
|
|
|
|
|
|
|
|
|
|
url = this.requests[3].url.slice(this.requests[3].url.lastIndexOf('/') + 1); |
|
|
|
|
|
media = this.player.tech_.hls.playlists.master.playlists[url]; |
|
|
|
|
|
|
|
|
|
|
|
// the first media was unblacklisted after a refresh delay
|
|
|
|
|
|
assert.ok(!media.excludeUntil, 'removed first media from blacklist'); |
|
|
|
|
|
|
|
|
assert.strictEqual(this.requests[3].url, |
|
|
assert.strictEqual(this.requests[3].url, |
|
|
absoluteUrl('manifest/media1.m3u8'), |
|
|
|
|
|
|
|
|
absoluteUrl('manifest/media.m3u8'), |
|
|
'media playlist requested'); |
|
|
'media playlist requested'); |
|
|
|
|
|
|
|
|
// verify stats
|
|
|
// verify stats
|
|
@ -1390,11 +1438,11 @@ QUnit.test('never blacklist the playlist if it is the only playlist', function(a |
|
|
this.requests.shift().respond(404); |
|
|
this.requests.shift().respond(404); |
|
|
media = this.player.tech_.hls.playlists.media(); |
|
|
media = this.player.tech_.hls.playlists.media(); |
|
|
|
|
|
|
|
|
// media wasn't blacklisted because it's final rendition
|
|
|
|
|
|
|
|
|
// media wasn't blacklisted because it's the only rendition
|
|
|
assert.ok(!media.excludeUntil, 'media was not blacklisted after playlist 404'); |
|
|
assert.ok(!media.excludeUntil, 'media was not blacklisted after playlist 404'); |
|
|
assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist'); |
|
|
assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist'); |
|
|
assert.equal(this.env.log.warn.args[0], |
|
|
assert.equal(this.env.log.warn.args[0], |
|
|
'Problem encountered with the current HLS playlist. Trying again since it is the final playlist.', |
|
|
|
|
|
|
|
|
'Problem encountered with the current HLS playlist. Trying again since it is the only playlist.', |
|
|
'log specific error message for final playlist'); |
|
|
'log specific error message for final playlist'); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
@ -1417,12 +1465,12 @@ QUnit.test('error on the first playlist request does not trigger an error ' + |
|
|
let url = this.requests[1].url.slice(this.requests[1].url.lastIndexOf('/') + 1); |
|
|
let url = this.requests[1].url.slice(this.requests[1].url.lastIndexOf('/') + 1); |
|
|
let media = this.player.tech_.hls.playlists.master.playlists[url]; |
|
|
let media = this.player.tech_.hls.playlists.master.playlists[url]; |
|
|
|
|
|
|
|
|
// media wasn't blacklisted because it's final rendition
|
|
|
|
|
|
|
|
|
// media wasn't blacklisted because it's only rendition
|
|
|
assert.ok(!media.excludeUntil, 'media was not blacklisted after playlist 404'); |
|
|
assert.ok(!media.excludeUntil, 'media was not blacklisted after playlist 404'); |
|
|
assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist'); |
|
|
assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist'); |
|
|
assert.equal(this.env.log.warn.args[0], |
|
|
assert.equal(this.env.log.warn.args[0], |
|
|
'Problem encountered with the current HLS playlist. Trying again since it is the final playlist.', |
|
|
|
|
|
'log specific error message for final playlist'); |
|
|
|
|
|
|
|
|
'Problem encountered with the current HLS playlist. Trying again since it is the only playlist.', |
|
|
|
|
|
'log specific error message for the only playlist'); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
QUnit.test('seeking in an empty playlist is a non-erroring noop', function(assert) { |
|
|
QUnit.test('seeking in an empty playlist is a non-erroring noop', function(assert) { |
|
@ -1797,15 +1845,16 @@ QUnit.test('playlist blacklisting duration is set through options', function(ass |
|
|
assert.ok(media.excludeUntil > 0, 'original media blacklisted for some time'); |
|
|
assert.ok(media.excludeUntil > 0, 'original media blacklisted for some time'); |
|
|
assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist'); |
|
|
assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist'); |
|
|
assert.equal(this.env.log.warn.args[0], |
|
|
assert.equal(this.env.log.warn.args[0], |
|
|
'Problem encountered with the current HLS playlist. HLS playlist request error at URL: media.m3u8 Switching to another playlist.', |
|
|
|
|
|
|
|
|
'Problem encountered with the current HLS playlist. HLS playlist request error at URL: media.m3u8. Switching to another playlist.', |
|
|
'log generic error message'); |
|
|
'log generic error message'); |
|
|
|
|
|
// this takes one millisecond
|
|
|
|
|
|
this.standardXHRResponse(this.requests[2]); |
|
|
|
|
|
|
|
|
this.clock.tick(2 * 60 * 1000); |
|
|
|
|
|
|
|
|
this.clock.tick(2 * 60 * 1000 - 1); |
|
|
assert.ok(media.excludeUntil - Date.now() > 0, 'original media still be blacklisted'); |
|
|
assert.ok(media.excludeUntil - Date.now() > 0, 'original media still be blacklisted'); |
|
|
|
|
|
|
|
|
this.clock.tick(1 * 60 * 1000); |
|
|
this.clock.tick(1 * 60 * 1000); |
|
|
assert.equal(media.excludeUntil, Date.now(), 'media\'s exclude time reach to the current time'); |
|
|
assert.equal(media.excludeUntil, Date.now(), 'media\'s exclude time reach to the current time'); |
|
|
assert.equal(this.env.log.warn.calls, 3, 'warning logged for blacklist'); |
|
|
|
|
|
|
|
|
|
|
|
videojs.options.hls = hlsOptions; |
|
|
videojs.options.hls = hlsOptions; |
|
|
}); |
|
|
}); |
|
|