98b3fc0b by jrivera

Work around a bug with the buffered property in IE11 that prevented playback

1 parent dd5d71c9
...@@ -305,6 +305,7 @@ const filterBufferedRanges = function(predicate) { ...@@ -305,6 +305,7 @@ const filterBufferedRanges = function(predicate) {
305 let i; 305 let i;
306 let ranges = []; 306 let ranges = [];
307 let tech = this.tech_; 307 let tech = this.tech_;
308
308 // !!The order of the next two assignments is important!! 309 // !!The order of the next two assignments is important!!
309 // `currentTime` must be equal-to or greater-than the start of the 310 // `currentTime` must be equal-to or greater-than the start of the
310 // buffered range. Flash executes out-of-process so, every value can 311 // buffered range. Flash executes out-of-process so, every value can
...@@ -317,6 +318,15 @@ const filterBufferedRanges = function(predicate) { ...@@ -317,6 +318,15 @@ const filterBufferedRanges = function(predicate) {
317 time = tech.currentTime(); 318 time = tech.currentTime();
318 } 319 }
319 320
321 // IE 11 has a bug where it will report a the video as fully buffered
322 // before any data has been loaded. This is a work around where we
323 // report a fully empty buffer until SourceBuffers have been created
324 // which is after a segment has been loaded and transmuxed.
325 if (!this.mediaSource ||
326 !this.mediaSource.mediaSource_.sourceBuffers.length) {
327 return videojs.createTimeRanges([]);
328 }
329
320 if (buffered && buffered.length) { 330 if (buffered && buffered.length) {
321 // Search for a range containing the play-head 331 // Search for a range containing the play-head
322 for (i = 0; i < buffered.length; i++) { 332 for (i = 0; i < buffered.length; i++) {
......
...@@ -172,6 +172,11 @@ class MockMediaSource extends videojs.EventTarget { ...@@ -172,6 +172,11 @@ class MockMediaSource extends videojs.EventTarget {
172 super(); 172 super();
173 this.duration = NaN; 173 this.duration = NaN;
174 this.seekable = videojs.createTimeRange(); 174 this.seekable = videojs.createTimeRange();
175 this.mediaSource_ = {
176 // Mock a fake sourceBuffer array because of an IE11 work-around
177 // in `filterBufferedRanges`
178 sourceBuffers: ['fake']
179 };
175 } 180 }
176 addSeekableRange_(start, end) { 181 addSeekableRange_(start, end) {
177 this.seekable = videojs.createTimeRange(start, end); 182 this.seekable = videojs.createTimeRange(start, end);
...@@ -747,6 +752,33 @@ QUnit.test('starts downloading a segment on loadedmetadata', function() { ...@@ -747,6 +752,33 @@ QUnit.test('starts downloading a segment on loadedmetadata', function() {
747 'the first segment is requested'); 752 'the first segment is requested');
748 }); 753 });
749 754
755 QUnit.test('always returns an empty buffered region when there are no SourceBuffers', function() {
756 this.player.src({
757 src: 'manifest/media.m3u8',
758 type: 'application/vnd.apple.mpegurl'
759 });
760 this.player.tech_.buffered = function() {
761 return videojs.createTimeRanges([[0, 10]]);
762 };
763 openMediaSource(this.player, this.clock);
764
765 standardXHRResponse(this.requests[0]);
766 standardXHRResponse(this.requests[1]);
767 this.player.currentTime(3);
768 this.clock.tick(1);
769
770 QUnit.equal(this.player.tech_.hls.findBufferedRange_().end(0),
771 10,
772 'inside the first buffered region');
773
774 // Simulate the condition with no source buffers
775 this.player.hls.mediaSource.mediaSource_.sourceBuffers = [];
776
777 QUnit.equal(this.player.tech_.hls.findBufferedRange_().length,
778 0,
779 'empty TimeRanges returned');
780 });
781
750 QUnit.test('finds the correct buffered region based on currentTime', function() { 782 QUnit.test('finds the correct buffered region based on currentTime', function() {
751 this.player.src({ 783 this.player.src({
752 src: 'manifest/media.m3u8', 784 src: 'manifest/media.m3u8',
......