97197609 by Dylan Dove

Addressed bug where playback doesn't initiate after a playlist 404s

1 parent c672f176
...@@ -90,6 +90,7 @@ ...@@ -90,6 +90,7 @@
90 dispose, 90 dispose,
91 mediaUpdateTimeout, 91 mediaUpdateTimeout,
92 request, 92 request,
93 playlistRequestError,
93 haveMetadata; 94 haveMetadata;
94 95
95 PlaylistLoader.prototype.init.call(this); 96 PlaylistLoader.prototype.init.call(this);
...@@ -102,17 +103,16 @@ ...@@ -102,17 +103,16 @@
102 throw new Error('A non-empty playlist URL is required'); 103 throw new Error('A non-empty playlist URL is required');
103 } 104 }
104 105
105 // update the playlist loader's state in response to a new or 106 playlistRequestError = function(xhr, url, startingState) {
106 // updated playlist.
107 haveMetadata = function(error, xhr, url) {
108 var parser, refreshDelay, update;
109
110 loader.setBandwidth(request || xhr); 107 loader.setBandwidth(request || xhr);
111 108
112 // any in-flight request is now finished 109 // any in-flight request is now finished
113 request = null; 110 request = null;
114 111
115 if (error) { 112 if (startingState) {
113 loader.state = startingState;
114 }
115
116 loader.error = { 116 loader.error = {
117 playlist: loader.master.playlists[url], 117 playlist: loader.master.playlists[url],
118 status: xhr.status, 118 status: xhr.status,
...@@ -120,9 +120,19 @@ ...@@ -120,9 +120,19 @@
120 responseText: xhr.responseText, 120 responseText: xhr.responseText,
121 code: (xhr.status >= 500) ? 4 : 2 121 code: (xhr.status >= 500) ? 4 : 2
122 }; 122 };
123 return loader.trigger('error'); 123 loader.trigger('error');
124 } 124 };
125
126 // update the playlist loader's state in response to a new or
127 // updated playlist.
128
129 haveMetadata = function(xhr, url) {
130 var parser, refreshDelay, update;
125 131
132 loader.setBandwidth(request || xhr);
133
134 // any in-flight request is now finished
135 request = null;
126 loader.state = 'HAVE_METADATA'; 136 loader.state = 'HAVE_METADATA';
127 137
128 parser = new videojs.m3u8.Parser(); 138 parser = new videojs.m3u8.Parser();
...@@ -252,12 +262,12 @@ ...@@ -252,12 +262,12 @@
252 uri: resolveUrl(loader.master.uri, playlist.uri), 262 uri: resolveUrl(loader.master.uri, playlist.uri),
253 withCredentials: withCredentials 263 withCredentials: withCredentials
254 }, function(error, request) { 264 }, function(error, request) {
255 haveMetadata(error, request, playlist.uri);
256
257 if (error) { 265 if (error) {
258 return; 266 return playlistRequestError(request, playlist.uri, startingState);
259 } 267 }
260 268
269 haveMetadata(request, playlist.uri);
270
261 // fire loadedmetadata the first time a media playlist is loaded 271 // fire loadedmetadata the first time a media playlist is loaded
262 if (startingState === 'HAVE_MASTER') { 272 if (startingState === 'HAVE_MASTER') {
263 loader.trigger('loadedmetadata'); 273 loader.trigger('loadedmetadata');
...@@ -289,7 +299,10 @@ ...@@ -289,7 +299,10 @@
289 uri: resolveUrl(loader.master.uri, loader.media().uri), 299 uri: resolveUrl(loader.master.uri, loader.media().uri),
290 withCredentials: withCredentials 300 withCredentials: withCredentials
291 }, function(error, request) { 301 }, function(error, request) {
292 haveMetadata(error, request, loader.media().uri); 302 if (error) {
303 return playlistRequestError(request, loader.media().uri);
304 }
305 haveMetadata(request, loader.media().uri);
293 }); 306 });
294 }); 307 });
295 308
...@@ -349,7 +362,7 @@ ...@@ -349,7 +362,7 @@
349 }] 362 }]
350 }; 363 };
351 loader.master.playlists[srcUrl] = loader.master.playlists[0]; 364 loader.master.playlists[srcUrl] = loader.master.playlists[0];
352 haveMetadata(null, req, srcUrl); 365 haveMetadata(req, srcUrl);
353 return loader.trigger('loadedmetadata'); 366 return loader.trigger('loadedmetadata');
354 }); 367 });
355 }; 368 };
......
...@@ -1296,6 +1296,28 @@ test('blacklists switching from video-only playlists to video+audio', function() ...@@ -1296,6 +1296,28 @@ test('blacklists switching from video-only playlists to video+audio', function()
1296 equal(videoAudioPlaylist.excludeUntil, Infinity, 'excluded incompatible playlist'); 1296 equal(videoAudioPlaylist.excludeUntil, Infinity, 'excluded incompatible playlist');
1297 }); 1297 });
1298 1298
1299 test('After an initial media playlist 404s, we fire loadedmetadata once we successfully load a playlist', function() {
1300 var count = 0;
1301 player.src({
1302 src: 'manifest/master.m3u8',
1303 type: 'application/vnd.apple.mpegurl'
1304 });
1305 openMediaSource(player);
1306 player.tech_.hls.bandwidth = 20000;
1307 player.on('loadedmetadata', function() {
1308 count += 1;
1309 });
1310 standardXHRResponse(requests.shift()); //master
1311 equal(count, 0,
1312 'loadedMedia not triggered before requesting playlist');
1313 requests.shift().respond(404); //media
1314 equal(count, 0,
1315 'loadedMedia not triggered after playlist 404');
1316 standardXHRResponse(requests.shift()); //media
1317 equal(count, 1,
1318 'loadedMedia triggered after successful recovery from 404');
1319 });
1320
1299 test('does not blacklist compatible H.264 codec strings', function() { 1321 test('does not blacklist compatible H.264 codec strings', function() {
1300 var master; 1322 var master;
1301 player.src({ 1323 player.src({
......