@ -570,7 +570,7 @@ function(assert) {
assert . equal ( error . code , 2 , 'error has correct code' ) ;
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' ) ;
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' ) ;
} ) ;
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 ) {
let media ;
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 . equal ( this . env . log . warn . calls , 1 , 'warning logged for blacklist' ) ;
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' ) ;
assert . equal ( blacklistplaylist , 1 , 'there is one blacklisted playlist' ) ;
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 ) ;
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 ] ,
'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 ) ;
// 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' ) ;
this . clock . tick ( 3 * 1000 ) ;
// continue loading the final remaining playlist after it wasn't blacklist ed
// loading the first playlist since the blacklist duration was clear ed
// when half the segment duaration passed
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 ,
absoluteUrl ( 'manifest/media1.m3u8' ) ,
absoluteUrl ( 'manifest/media.m3u8' ) ,
'media playlist requested' ) ;
// 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 ) ;
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 . equal ( this . env . log . warn . calls , 1 , 'warning logged for blacklist' ) ;
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' ) ;
} ) ;
@ -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 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 . equal ( this . env . log . warn . calls , 1 , 'warning logged for blacklist' ) ;
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 ) {
@ -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 . equal ( this . env . log . warn . calls , 1 , 'warning logged for blacklist' ) ;
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' ) ;
// 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' ) ;
this . clock . tick ( 1 * 60 * 1000 ) ;
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 ;
} ) ;