ed8384a0 by Jon-Carlos Rivera

Merge pull request #549 from videojs/live-remove

Fix buffer trimming so that it doesn't use seekable.start if it has a…
2 parents 09fa9fb5 67cadfbe
...@@ -1130,7 +1130,8 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { ...@@ -1130,7 +1130,8 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) {
1130 self = this, 1130 self = this,
1131 segment = segmentInfo.playlist.segments[segmentInfo.mediaIndex], 1131 segment = segmentInfo.playlist.segments[segmentInfo.mediaIndex],
1132 removeToTime = 0, 1132 removeToTime = 0,
1133 seekable = this.seekable(); 1133 seekable = this.seekable(),
1134 currentTime = this.tech_.currentTime();
1134 1135
1135 // Chrome has a hard limit of 150mb of buffer and a very conservative "garbage collector" 1136 // Chrome has a hard limit of 150mb of buffer and a very conservative "garbage collector"
1136 // We manually clear out the old buffer to ensure we don't trigger the QuotaExceeded error 1137 // We manually clear out the old buffer to ensure we don't trigger the QuotaExceeded error
...@@ -1138,10 +1139,10 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { ...@@ -1138,10 +1139,10 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) {
1138 if (this.sourceBuffer && !this.sourceBuffer.updating) { 1139 if (this.sourceBuffer && !this.sourceBuffer.updating) {
1139 // If we have a seekable range use that as the limit for what can be removed safely 1140 // If we have a seekable range use that as the limit for what can be removed safely
1140 // otherwise remove anything older than 1 minute before the current play head 1141 // otherwise remove anything older than 1 minute before the current play head
1141 if (seekable.length && seekable.start(0) > 0) { 1142 if (seekable.length && seekable.start(0) > 0 && seekable.start(0) < currentTime) {
1142 removeToTime = seekable.start(0); 1143 removeToTime = seekable.start(0);
1143 } else { 1144 } else {
1144 removeToTime = this.tech_.currentTime() - 60; 1145 removeToTime = currentTime - 60;
1145 } 1146 }
1146 1147
1147 if (removeToTime > 0) { 1148 if (removeToTime > 0) {
......
...@@ -427,7 +427,7 @@ test('duration is set when the source opens after the playlist is loaded', funct ...@@ -427,7 +427,7 @@ test('duration is set when the source opens after the playlist is loaded', funct
427 equal(player.tech_.hls.mediaSource.duration , 40, 'set the duration'); 427 equal(player.tech_.hls.mediaSource.duration , 40, 'set the duration');
428 }); 428 });
429 429
430 test('calls `remove` on sourceBuffer to when loading a live segment', function() { 430 test('calls `remove` based on seekable when loading a live segment', function() {
431 var 431 var
432 removes = [], 432 removes = [],
433 seekable = videojs.createTimeRanges([[60, 120]]); 433 seekable = videojs.createTimeRanges([[60, 120]]);
...@@ -471,7 +471,53 @@ test('calls `remove` on sourceBuffer to when loading a live segment', function() ...@@ -471,7 +471,53 @@ test('calls `remove` on sourceBuffer to when loading a live segment', function()
471 deepEqual(removes[0], [0, seekable.start(0)], 'remove called with the right range'); 471 deepEqual(removes[0], [0, seekable.start(0)], 'remove called with the right range');
472 }); 472 });
473 473
474 test('calls `remove` on sourceBuffer to when loading a vod segment', function() { 474 test('calls `remove` based on currentTime when loading a live segment '+
475 'if seekable start is after currentTime', function() {
476 var
477 removes = [],
478 seekable = videojs.createTimeRanges([[0, 80]]);
479
480 player.src({
481 src: 'liveStart30sBefore.m3u8',
482 type: 'application/vnd.apple.mpegurl'
483 });
484 openMediaSource(player);
485 player.tech_.hls.seekable = function(){
486 return seekable;
487 };
488
489 openMediaSource(player);
490 player.tech_.hls.mediaSource.addSourceBuffer = function() {
491 return new (videojs.extend(videojs.EventTarget, {
492 constructor: function() {},
493 abort: function() {},
494 buffered: videojs.createTimeRange(),
495 appendBuffer: function() {},
496 remove: function(start, end) {
497 removes.push([start, end]);
498 }
499 }))();
500 };
501 player.tech_.hls.bandwidth = 20e10;
502 player.tech_.triggerReady();
503 standardXHRResponse(requests[0]);
504 player.tech_.hls.playlists.trigger('loadedmetadata');
505 player.tech_.trigger('canplay');
506 player.tech_.paused = function() { return false; };
507 player.tech_.readyState = function(){return 1;};
508 player.tech_.trigger('play');
509 clock.tick(1);
510 // Change seekable so that it starts *after* the currentTime which was set
511 // based on the previous seekable range (the end of 80)
512 seekable = videojs.createTimeRanges([[100, 120]]);
513 standardXHRResponse(requests[1]);
514
515 strictEqual(requests[0].url, 'liveStart30sBefore.m3u8', 'master playlist requested');
516 equal(removes.length, 1, 'remove called');
517 deepEqual(removes[0], [0, 80 - 60], 'remove called with the right range');
518 });
519
520 test('calls `remove` based on currentTime when loading a vod segment', function() {
475 var removes = []; 521 var removes = [];
476 player.src({ 522 player.src({
477 src: 'manifest/master.m3u8', 523 src: 'manifest/master.m3u8',
......