b65573ad by David LaPalomento

Switch to fully-loaded playlists immediately

Don't re-request playlists that have already been fully loaded. If the loader is in the middle of requesting a new playlist and is asked to switch back to a loaded one, abort the outstanding request. Update playlist loader state diagram.
1 parent 4f97809b
...@@ -150,12 +150,21 @@ ...@@ -150,12 +150,21 @@
150 playlist = loader.master.playlists[playlist]; 150 playlist = loader.master.playlists[playlist];
151 } 151 }
152 152
153 if (playlist.uri === media.uri) { 153 // switch to fully loaded playlists immediately
154 // switching to the currently active playlist is a no-op 154 if (loader.master.playlists[playlist.uri].endList) {
155 if (request) {
156 request.abort();
157 request = null;
158 }
159 loader.state = 'HAVE_METADATA';
160 media = playlist;
155 return; 161 return;
156 } 162 }
157 163
158 164 // switching to the active playlist is a no-op
165 if (playlist.uri === media.uri) {
166 return;
167 }
159 168
160 loader.state = 'SWITCHING_MEDIA'; 169 loader.state = 'SWITCHING_MEDIA';
161 170
......
...@@ -348,9 +348,78 @@ ...@@ -348,9 +348,78 @@
348 '#EXT-X-ENDLIST\n'); 348 '#EXT-X-ENDLIST\n');
349 loader.media('low.m3u8'); 349 loader.media('low.m3u8');
350 350
351 strictEqual(requests.length, 0, 'no requests is sent'); 351 strictEqual(requests.length, 0, 'no requests are sent');
352 }); 352 });
353 353
354 test('switching to the active live playlist is a no-op', function() {
355 var loader = new videojs.Hls.PlaylistLoader('master.m3u8');
356 requests.pop().respond(200, null,
357 '#EXTM3U\n' +
358 '#EXT-X-STREAM-INF:BANDWIDTH=1\n' +
359 'low.m3u8\n' +
360 '#EXT-X-STREAM-INF:BANDWIDTH=2\n' +
361 'high.m3u8\n');
362 requests.pop().respond(200, null,
363 '#EXTM3U\n' +
364 '#EXT-X-MEDIA-SEQUENCE:0\n' +
365 '#EXTINF:10,\n' +
366 'low-0.ts\n');
367 loader.media('low.m3u8');
368
369 strictEqual(requests.length, 0, 'no requests are sent');
370 });
371
372 test('switches back to loaded playlists without re-requesting them', function() {
373 var loader = new videojs.Hls.PlaylistLoader('master.m3u8');
374 requests.pop().respond(200, null,
375 '#EXTM3U\n' +
376 '#EXT-X-STREAM-INF:BANDWIDTH=1\n' +
377 'low.m3u8\n' +
378 '#EXT-X-STREAM-INF:BANDWIDTH=2\n' +
379 'high.m3u8\n');
380 requests.pop().respond(200, null,
381 '#EXTM3U\n' +
382 '#EXT-X-MEDIA-SEQUENCE:0\n' +
383 '#EXTINF:10,\n' +
384 'low-0.ts\n' +
385 '#EXT-X-ENDLIST\n');
386 loader.media('high.m3u8');
387 requests.pop().respond(200, null,
388 '#EXTM3U\n' +
389 '#EXT-X-MEDIA-SEQUENCE:0\n' +
390 '#EXTINF:10,\n' +
391 'high-0.ts\n' +
392 '#EXT-X-ENDLIST\n');
393 loader.media('low.m3u8');
394
395 strictEqual(requests.length, 0, 'no outstanding requests');
396 strictEqual(loader.state, 'HAVE_METADATA', 'returned to loaded playlist');
397 });
398
399 test('aborts outstanding requests if switching back to an already loaded playlist', function() {
400 var loader = new videojs.Hls.PlaylistLoader('master.m3u8');
401 requests.pop().respond(200, null,
402 '#EXTM3U\n' +
403 '#EXT-X-STREAM-INF:BANDWIDTH=1\n' +
404 'low.m3u8\n' +
405 '#EXT-X-STREAM-INF:BANDWIDTH=2\n' +
406 'high.m3u8\n');
407 requests.pop().respond(200, null,
408 '#EXTM3U\n' +
409 '#EXT-X-MEDIA-SEQUENCE:0\n' +
410 '#EXTINF:10,\n' +
411 'low-0.ts\n' +
412 '#EXT-X-ENDLIST\n');
413 loader.media('high.m3u8');
414 loader.media('low.m3u8');
415
416 strictEqual(requests.length, 1, 'requested high playlist');
417 ok(requests[0].aborted, 'aborted playlist request');
418 strictEqual(loader.state, 'HAVE_METADATA', 'returned to loaded playlist');
419 strictEqual(loader.media(), loader.master.playlists[0], 'switched to loaded playlist');
420 });
421
422
354 test('does not abort requests when the same playlist is re-requested', function() { 423 test('does not abort requests when the same playlist is re-requested', function() {
355 var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); 424 var loader = new videojs.Hls.PlaylistLoader('master.m3u8');
356 requests.pop().respond(200, null, 425 requests.pop().respond(200, null,
......