95e7ec11 by David LaPalomento

Missing segments are skipped

In the long run, we'd like to switch variants if we encounter a missing segment but for now just dive ahead. Player errors are reserved for fatal conditions, so it doesn't make sense to trigger an error now that we have some error handling. For the moment, an error is exposed on the hls plugin but no player-level event is triggered.
1 parent 279e4048
...@@ -484,7 +484,9 @@ var ...@@ -484,7 +484,9 @@ var
484 message: 'HLS segment request error at URL: ' + segmentUri, 484 message: 'HLS segment request error at URL: ' + segmentUri,
485 code: (this.status >= 500) ? 4 : 2 485 code: (this.status >= 500) ? 4 : 2
486 }; 486 };
487 player.trigger('error'); 487
488 // try moving on to the next segment
489 player.hls.mediaIndex++
488 return; 490 return;
489 } 491 }
490 492
......
...@@ -292,6 +292,28 @@ test('selects a playlist after segment downloads', function() { ...@@ -292,6 +292,28 @@ test('selects a playlist after segment downloads', function() {
292 strictEqual(calls, 2, 'selects after additional segments'); 292 strictEqual(calls, 2, 'selects after additional segments');
293 }); 293 });
294 294
295 test('moves to the next segment if there is a network error', function() {
296 var mediaIndex;
297 player.hls('manifest/master.m3u8');
298 videojs.mediaSources[player.currentSrc()].trigger({
299 type: 'sourceopen'
300 });
301
302 // fail the next segment request
303 window.XMLHttpRequest = function() {
304 this.open = function() {};
305 this.send = function() {
306 this.readyState = 4;
307 this.status = 400;
308 this.onreadystatechange();
309 };
310 };
311 mediaIndex = player.hls.mediaIndex;
312 player.trigger('timeupdate');
313
314 strictEqual(mediaIndex + 1, player.hls.mediaIndex, 'media index is incremented');
315 });
316
295 test('updates the duration after switching playlists', function() { 317 test('updates the duration after switching playlists', function() {
296 var 318 var
297 calls = 0, 319 calls = 0,
...@@ -593,8 +615,6 @@ test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() { ...@@ -593,8 +615,6 @@ test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() {
593 }); 615 });
594 616
595 test('segment 404 should trigger MEDIA_ERR_NETWORK', function () { 617 test('segment 404 should trigger MEDIA_ERR_NETWORK', function () {
596 var errorTriggered = false;
597
598 player.hls('manifest/media.m3u8'); 618 player.hls('manifest/media.m3u8');
599 619
600 player.on('loadedmanifest', function () { 620 player.on('loadedmanifest', function () {
...@@ -610,22 +630,15 @@ test('segment 404 should trigger MEDIA_ERR_NETWORK', function () { ...@@ -610,22 +630,15 @@ test('segment 404 should trigger MEDIA_ERR_NETWORK', function () {
610 }; 630 };
611 }); 631 });
612 632
613 player.on('error', function () {
614 errorTriggered = true;
615 });
616
617 videojs.mediaSources[player.currentSrc()].trigger({ 633 videojs.mediaSources[player.currentSrc()].trigger({
618 type: 'sourceopen' 634 type: 'sourceopen'
619 }); 635 });
620 636
621 equal(true, errorTriggered, 'Missing Segment error event should trigger');
622 ok(player.hls.error.message, 'an error message is available'); 637 ok(player.hls.error.message, 'an error message is available');
623 equal(2, player.hls.error.code, 'Player error code should be set to MediaError.MEDIA_ERR_NETWORK'); 638 equal(2, player.hls.error.code, 'Player error code should be set to MediaError.MEDIA_ERR_NETWORK');
624 }); 639 });
625 640
626 test('segment 500 should trigger MEDIA_ERR_ABORTED', function () { 641 test('segment 500 should trigger MEDIA_ERR_ABORTED', function () {
627 var errorTriggered = false;
628
629 player.hls('manifest/media.m3u8'); 642 player.hls('manifest/media.m3u8');
630 643
631 player.on('loadedmanifest', function () { 644 player.on('loadedmanifest', function () {
...@@ -641,15 +654,10 @@ test('segment 500 should trigger MEDIA_ERR_ABORTED', function () { ...@@ -641,15 +654,10 @@ test('segment 500 should trigger MEDIA_ERR_ABORTED', function () {
641 }; 654 };
642 }); 655 });
643 656
644 player.on('error', function () {
645 errorTriggered = true;
646 });
647
648 videojs.mediaSources[player.currentSrc()].trigger({ 657 videojs.mediaSources[player.currentSrc()].trigger({
649 type: 'sourceopen' 658 type: 'sourceopen'
650 }); 659 });
651 660
652 equal(true, errorTriggered, 'Missing Segment error event should trigger');
653 ok(player.hls.error.message, 'an error message is available'); 661 ok(player.hls.error.message, 'an error message is available');
654 equal(4, player.hls.error.code, 'Player error code should be set to MediaError.MEDIA_ERR_ABORTED'); 662 equal(4, player.hls.error.code, 'Player error code should be set to MediaError.MEDIA_ERR_ABORTED');
655 }); 663 });
......