Merge pull request #470 from videojs/remove-from-buffer
Remove from buffer
Showing
2 changed files
with
95 additions
and
1 deletions
... | @@ -982,7 +982,26 @@ videojs.HlsHandler.prototype.blacklistCurrentPlaylist_ = function(error) { | ... | @@ -982,7 +982,26 @@ videojs.HlsHandler.prototype.blacklistCurrentPlaylist_ = function(error) { |
982 | videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { | 982 | videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { |
983 | var | 983 | var |
984 | self = this, | 984 | self = this, |
985 | segment = segmentInfo.playlist.segments[segmentInfo.mediaIndex]; | 985 | segment = segmentInfo.playlist.segments[segmentInfo.mediaIndex], |
986 | removeToTime = 0, | ||
987 | seekable = this.seekable(); | ||
988 | |||
989 | // Chrome has a hard limit of 150mb of buffer and a very conservative "garbage collector" | ||
990 | // We manually clear out the old buffer to ensure we don't trigger the QuotaExceeded error | ||
991 | // on the source buffer during subsequent appends | ||
992 | if (this.sourceBuffer && !this.sourceBuffer.updating) { | ||
993 | // If we have a seekable range use that as the limit for what can be removed safely | ||
994 | // otherwise remove anything older than 1 minute before the current play head | ||
995 | if (seekable.length && seekable.start(0) > 0) { | ||
996 | removeToTime = seekable.start(0); | ||
997 | } else { | ||
998 | removeToTime = this.tech_.currentTime() - 60; | ||
999 | } | ||
1000 | |||
1001 | if (removeToTime > 0) { | ||
1002 | this.sourceBuffer.remove(0, removeToTime); | ||
1003 | } | ||
1004 | } | ||
986 | 1005 | ||
987 | // if the segment is encrypted, request the key | 1006 | // if the segment is encrypted, request the key |
988 | if (segment.key) { | 1007 | if (segment.key) { | ... | ... |
... | @@ -373,6 +373,81 @@ test('duration is set when the source opens after the playlist is loaded', funct | ... | @@ -373,6 +373,81 @@ test('duration is set when the source opens after the playlist is loaded', funct |
373 | equal(player.tech_.hls.mediaSource.duration , 40, 'set the duration'); | 373 | equal(player.tech_.hls.mediaSource.duration , 40, 'set the duration'); |
374 | }); | 374 | }); |
375 | 375 | ||
376 | test('calls `remove` on sourceBuffer to when loading a live segment', function() { | ||
377 | var | ||
378 | removes = [], | ||
379 | seekable = videojs.createTimeRanges([[60, 120]]); | ||
380 | |||
381 | player.src({ | ||
382 | src: 'liveStart30sBefore.m3u8', | ||
383 | type: 'application/vnd.apple.mpegurl' | ||
384 | }); | ||
385 | openMediaSource(player); | ||
386 | player.tech_.hls.seekable = function(){ | ||
387 | return seekable; | ||
388 | }; | ||
389 | |||
390 | openMediaSource(player); | ||
391 | player.tech_.hls.mediaSource.addSourceBuffer = function() { | ||
392 | return new (videojs.extend(videojs.EventTarget, { | ||
393 | constructor: function() {}, | ||
394 | abort: function() {}, | ||
395 | buffered: videojs.createTimeRange(), | ||
396 | appendBuffer: function() {}, | ||
397 | remove: function(start, end) { | ||
398 | removes.push([start, end]); | ||
399 | } | ||
400 | }))(); | ||
401 | }; | ||
402 | player.tech_.hls.bandwidth = 20e10; | ||
403 | player.tech_.triggerReady(); | ||
404 | standardXHRResponse(requests[0]); | ||
405 | |||
406 | player.tech_.hls.playlists.trigger('loadedmetadata'); | ||
407 | player.tech_.trigger('canplay'); | ||
408 | player.tech_.paused = function() { return false; }; | ||
409 | player.tech_.trigger('play'); | ||
410 | |||
411 | clock.tick(1); | ||
412 | standardXHRResponse(requests[1]); | ||
413 | |||
414 | strictEqual(requests[0].url, 'liveStart30sBefore.m3u8', 'master playlist requested'); | ||
415 | equal(removes.length, 1, 'remove called'); | ||
416 | deepEqual(removes[0], [0, seekable.start(0)], 'remove called with the right range'); | ||
417 | }); | ||
418 | |||
419 | test('calls `remove` on sourceBuffer to when loading a vod segment', function() { | ||
420 | var removes = []; | ||
421 | player.src({ | ||
422 | src: 'manifest/master.m3u8', | ||
423 | type: 'application/vnd.apple.mpegurl' | ||
424 | }); | ||
425 | openMediaSource(player); | ||
426 | player.tech_.hls.mediaSource.addSourceBuffer = function() { | ||
427 | return new (videojs.extend(videojs.EventTarget, { | ||
428 | constructor: function() {}, | ||
429 | abort: function() {}, | ||
430 | buffered: videojs.createTimeRange(), | ||
431 | appendBuffer: function() {}, | ||
432 | remove: function(start, end) { | ||
433 | removes.push([start, end]); | ||
434 | } | ||
435 | }))(); | ||
436 | }; | ||
437 | player.tech_.hls.bandwidth = 20e10; | ||
438 | standardXHRResponse(requests[0]); | ||
439 | player.currentTime(120); | ||
440 | standardXHRResponse(requests[1]); | ||
441 | standardXHRResponse(requests[2]); | ||
442 | |||
443 | strictEqual(requests[0].url, 'manifest/master.m3u8', 'master playlist requested'); | ||
444 | strictEqual(requests[1].url, | ||
445 | absoluteUrl('manifest/media3.m3u8'), | ||
446 | 'media playlist requested'); | ||
447 | equal(removes.length, 1, 'remove called'); | ||
448 | deepEqual(removes[0], [0, 120 - 60], 'remove called with the right range'); | ||
449 | }); | ||
450 | |||
376 | test('codecs are passed to the source buffer', function() { | 451 | test('codecs are passed to the source buffer', function() { |
377 | var codecs = []; | 452 | var codecs = []; |
378 | player.src({ | 453 | player.src({ | ... | ... |
-
Please register or sign in to post a comment