diff --git a/src/css/video-js.less b/src/css/video-js.less index 81fad22495..287fbe8ccb 100644 --- a/src/css/video-js.less +++ b/src/css/video-js.less @@ -396,7 +396,7 @@ fonts to show/hide properly. /* Progress Bars */ .vjs-default-skin .vjs-progress-holder .vjs-play-progress, -.vjs-default-skin .vjs-progress-holder .vjs-load-progress { +.vjs-default-skin .vjs-progress-holder .vjs-load-progress div { position: absolute; display: block; height: 100%; @@ -422,7 +422,7 @@ fonts to show/hide properly. url(@slider-bar-pattern) -50% 0 repeat; } -.vjs-default-skin .vjs-load-progress { +.vjs-default-skin .vjs-load-progress div { background: rgb(100, 100, 100) /* IE8- Fallback */; background: rgba(255, 255, 255, 0.4); } diff --git a/src/js/control-bar/progress-control.js b/src/js/control-bar/progress-control.js index 7c0dee699e..e7f7a0b03d 100644 --- a/src/js/control-bar/progress-control.js +++ b/src/js/control-bar/progress-control.js @@ -107,7 +107,6 @@ vjs.SeekBar.prototype.stepBack = function(){ this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users }; - /** * Shows load progress * @@ -125,15 +124,38 @@ vjs.LoadProgressBar = vjs.Component.extend({ vjs.LoadProgressBar.prototype.createEl = function(){ return vjs.Component.prototype.createEl.call(this, 'div', { - className: 'vjs-load-progress', - innerHTML: 'Loaded: 0%' + className: 'vjs-load-progress' }); }; vjs.LoadProgressBar.prototype.update = function(){ - if (this.el_.style) { this.el_.style.width = vjs.round(this.player_.bufferedPercent() * 100, 2) + '%'; } + if (this.el_.style) { + var buffered = this.player_.buffered(), + children = this.el_.children; + + for (var i=0; i buffered.length; i--) { + this.el_.removeChild(children[i-1]); + } + } }; +vjs.LoadProgressBar.prototype.percentify = function(time) { + return vjs.round(time / this.player_.duration() * 100, 2) + '%' +} /** * Shows play progress @@ -151,8 +173,7 @@ vjs.PlayProgressBar = vjs.Component.extend({ vjs.PlayProgressBar.prototype.createEl = function(){ return vjs.Component.prototype.createEl.call(this, 'div', { - className: 'vjs-play-progress', - innerHTML: 'Progress: 0%' + className: 'vjs-play-progress' }); }; diff --git a/src/js/player.js b/src/js/player.js index cb6798943c..64af7acae1 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -349,13 +349,17 @@ vjs.Player.prototype.trackProgress = function(){ this.progressInterval = setInterval(vjs.bind(this, function(){ // Don't trigger unless buffered amount is greater than last time - // log(this.cache_.bufferEnd, this.buffered().end(0), this.duration()) - /* TODO: update for multiple buffered regions */ - if (this.cache_.bufferEnd < this.buffered().end(0)) { + + var bufferedPercent = this.bufferedPercent(); + + if (this.cache_.bufferedPercent != bufferedPercent) { this.trigger('progress'); - } else if (this.bufferedPercent() == 1) { + } + + this.cache_.bufferedPercent = bufferedPercent; + + if (bufferedPercent == 1) { this.stopTrackingProgress(); - this.trigger('progress'); // Last update } }), 500); }; @@ -742,7 +746,6 @@ vjs.Player.prototype.remainingTime = function(){ // http://dev.w3.org/html5/spec/video.html#dom-media-buffered // Buffered returns a timerange object. // Kind of like an array of portions of the video that have been downloaded. -// So far no browsers return more than one range (portion) /** * Get a TimeRange object with the times of the video that have been downloaded @@ -765,19 +768,13 @@ vjs.Player.prototype.remainingTime = function(){ * @return {Object} A mock TimeRange object (following HTML spec) */ vjs.Player.prototype.buffered = function(){ - var buffered = this.techGet('buffered'), - start = 0, - buflast = buffered.length - 1, - // Default end to 0 and store in values - end = this.cache_.bufferEnd = this.cache_.bufferEnd || 0; - - if (buffered && buflast >= 0 && buffered.end(buflast) !== end) { - end = buffered.end(buflast); - // Storing values allows them be overridden by setBufferedFromProgress - this.cache_.bufferEnd = end; + var buffered = this.techGet('buffered'); + + if (!buffered || !buffered.length) { + buffered = vjs.createTimeRange(0,0); } - return vjs.createTimeRange(start, end); + return buffered; }; /** @@ -791,7 +788,24 @@ vjs.Player.prototype.buffered = function(){ * @return {Number} A decimal between 0 and 1 representing the percent */ vjs.Player.prototype.bufferedPercent = function(){ - return (this.duration()) ? this.buffered().end(0) / this.duration() : 0; + var duration = this.duration(), + buffered = this.buffered(), + bufferedDuration = 0, + start, end; + + if (!duration) return 0; + + for (var i=0; i duration) end = duration; + + bufferedDuration += end - start; + } + + return bufferedDuration / duration; }; /** diff --git a/src/js/slider.js b/src/js/slider.js index cc3654f84a..6b1d46123f 100644 --- a/src/js/slider.js +++ b/src/js/slider.js @@ -117,7 +117,9 @@ vjs.Slider.prototype.update = function(){ } // Set the new bar width - bar.el().style.width = vjs.round(barProgress * 100, 2) + '%'; + if (bar) { + bar.el().style.width = vjs.round(barProgress * 100, 2) + '%'; + } }; vjs.Slider.prototype.calculateDistance = function(event){ diff --git a/test/unit/mediafaker.js b/test/unit/mediafaker.js index 222a9c10e1..364ffa5baf 100644 --- a/test/unit/mediafaker.js +++ b/test/unit/mediafaker.js @@ -44,6 +44,7 @@ vjs.MediaFaker.prototype.paused = function(){ return true; }; vjs.MediaFaker.prototype.supportsFullScreen = function(){ return false; }; vjs.MediaFaker.prototype.features = {}; vjs.MediaFaker.prototype.buffered = function(){ return {}; }; +vjs.MediaFaker.prototype.played = function(){ return {}; }; vjs.MediaFaker.prototype.duration = function(){ return {}; }; // Export vars for Closure Compiler