diff --git a/src/js/media/html5.js b/src/js/media/html5.js
index c9bff000cb..74f3858a00 100644
--- a/src/js/media/html5.js
+++ b/src/js/media/html5.js
@@ -27,7 +27,7 @@ vjs.Html5 = vjs.MediaTechController.extend({
// If the element source is already set, we may have missed the loadstart event, and want to trigger it.
// We don't want to set the source again and interrupt playback.
- if (source && this.el_.currentSrc == source.src) {
+ if (source && this.el_.currentSrc === source.src && this.el_.networkState > 0) {
player.trigger('loadstart');
// Otherwise set the source if one was provided.
@@ -67,19 +67,20 @@ vjs.Html5.prototype.createEl = function(){
var player = this.player_,
// If possible, reuse original tag for HTML5 playback technology element
el = player.tag,
- newEl;
+ newEl,
+ clone;
// Check if this browser supports moving the element into the box.
// On the iPhone video will break if you move the element,
// So we have to create a brand new element.
if (!el || this.features['movingMediaElementInDOM'] === false) {
- // If the original tag is still there, remove it.
+ // If the original tag is still there, clone and remove it.
if (el) {
- el['player'] = null;
+ clone = el.cloneNode(false);
+ vjs.Html5.disposeMediaElement(el);
+ el = clone;
player.tag = null;
- player.el().removeChild(el);
- el = el.cloneNode(false);
} else {
el = vjs.createEl('video', {
id:player.id() + '_html5_api',
@@ -258,6 +259,29 @@ vjs.Html5.canControlVolume = function(){
// List of all HTML5 events (various uses).
vjs.Html5.Events = 'loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange'.split(',');
+vjs.Html5.disposeMediaElement = function(el){
+ if (!el) { return; }
+
+ el['player'] = null;
+
+ if (el.parentNode) {
+ el.parentNode.removeChild(el);
+ }
+
+ // remove any child track or source nodes to prevent their loading
+ while(el.hasChildNodes()) {
+ el.removeChild(el.firstChild);
+ }
+
+ // remove any src reference. not setting `src=''` because that causes a warning
+ // in firefox
+ el.removeAttribute('src');
+
+ // force the media element to update its loading state by calling load()
+ if (typeof el.load === 'function') {
+ el.load();
+ }
+};
// HTML5 Feature detection and Device Fixes --------------------------------- //
diff --git a/src/js/player.js b/src/js/player.js
index f2f0d2b293..9a6f5c5c5b 100644
--- a/src/js/player.js
+++ b/src/js/player.js
@@ -151,7 +151,7 @@ vjs.Player.prototype.createEl = function(){
// Remove width/height attrs from tag so CSS can make it 100% width/height
tag.removeAttribute('width');
tag.removeAttribute('height');
- // Empty video tag sources and tracks so the built-in player doesn't use them also.
+ // Empty video tag tracks so the built-in player doesn't use them also.
// This may not be fast enough to stop HTML5 browsers from reading the tags
// so we'll need to turn off any default tracks if we're manually doing
// captions and subtitles. videoElement.textTracks
@@ -165,7 +165,7 @@ vjs.Player.prototype.createEl = function(){
while (nodesLength--) {
node = nodes[nodesLength];
nodeName = node.nodeName.toLowerCase();
- if (nodeName === 'source' || nodeName === 'track') {
+ if (nodeName === 'track') {
removeNodes.push(node);
}
}
@@ -218,11 +218,10 @@ vjs.Player.prototype.loadTech = function(techName, source){
if (this.tech) {
this.unloadTech();
- // If the first time loading, HTML5 tag will exist but won't be initialized
- // So we need to remove it if we're not loading HTML5
+ // if this is the first time loading, HTML5 tag will exist but won't be initialized
+ // so we need to remove it if we're not loading HTML5
} else if (techName !== 'Html5' && this.tag) {
- this.el_.removeChild(this.tag);
- this.tag['player'] = null;
+ vjs.Html5.disposeMediaElement(this.tag);
this.tag = null;
}
@@ -538,6 +537,10 @@ vjs.Player.prototype.duration = function(seconds){
return this;
}
+ if (this.cache_.duration === undefined) {
+ this.onDurationChange();
+ }
+
return this.cache_.duration;
};
diff --git a/test/unit/mediafaker.js b/test/unit/mediafaker.js
index 2f008f4041..108f9c6ff9 100644
--- a/test/unit/mediafaker.js
+++ b/test/unit/mediafaker.js
@@ -38,6 +38,7 @@ vjs.MediaFaker.prototype.pause = function(){ return false; };
vjs.MediaFaker.prototype.supportsFullScreen = function(){ return false; };
vjs.MediaFaker.prototype.features = {};
vjs.MediaFaker.prototype.buffered = function(){ return {}; };
+vjs.MediaFaker.prototype.duration = function(){ return {}; };
// Export vars for Closure Compiler
vjs['MediaFaker'] = vjs.MediaFaker;