165 lines
4.3 KiB
JavaScript
165 lines
4.3 KiB
JavaScript
webshims.register('mediaelement-native-fix', function($, webshims, window, document, undefined){
|
|
|
|
var support = webshims.support;
|
|
var fixBuffered = (function(){
|
|
if(support.videoBuffered){return $.noop;}
|
|
|
|
var getBufferedData = function(elem){
|
|
var data = webshims.data(elem, 'mediaelementBuffered');
|
|
if(!data){
|
|
data = {
|
|
buffered: {
|
|
start: function(index){
|
|
if(index >= data.buffered.length){
|
|
webshims.error('buffered index size error');
|
|
return;
|
|
}
|
|
return 0;
|
|
},
|
|
end: function(index){
|
|
if(index >= data.buffered.length){
|
|
webshims.error('buffered index size error');
|
|
return;
|
|
}
|
|
return data.loaded;
|
|
},
|
|
length: 0
|
|
},
|
|
loaded: 0
|
|
};
|
|
webshims.data(elem, 'mediaelementBuffered', data);
|
|
}
|
|
return data;
|
|
};
|
|
|
|
var loadProgessListener = function(e){
|
|
e = e.originalEvent;
|
|
if(!e || !('lengthComputable' in e)){return;}
|
|
var data = webshims.data(e.target, 'mediaelement');
|
|
if(data && data.isActive != 'html5'){return;}
|
|
if(e.lengthComputable && 'loaded' in e){
|
|
var duration = e.target.duration;
|
|
var bufferedData = getBufferedData(e.target);
|
|
bufferedData.loaded = (duration) ? e.loaded / e.total * duration : 0;
|
|
if(bufferedData.loaded){
|
|
bufferedData.buffered.length = 1;
|
|
}
|
|
if(e.type == 'load'){
|
|
$(e.target).triggerHandler('progress');
|
|
}
|
|
}
|
|
};
|
|
var removeProgress = function(e){
|
|
var data = getBufferedData(e.target);
|
|
data.buffered.length = 0;
|
|
data.loaded = 0;
|
|
};
|
|
|
|
['audio', 'video'].forEach(function(nodeName){
|
|
var sup = webshims.defineNodeNameProperty(nodeName, 'buffered', {
|
|
prop: {
|
|
get: function(){
|
|
var data = webshims.data(this, 'mediaelement');
|
|
|
|
if(data && data.isActive == 'flash' && sup.prop._supget){
|
|
sup.prop._supget.apply(this);
|
|
} else {
|
|
return getBufferedData(this).buffered;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
return function(){
|
|
$(this)
|
|
.off('load progress', loadProgessListener)
|
|
.off('emptied', removeProgress)
|
|
.on('load progress', loadProgessListener)
|
|
.on('emptied', removeProgress)
|
|
;
|
|
};
|
|
})();
|
|
|
|
(function(){
|
|
var videoElem = document.createElement('video');
|
|
if( !('preload' in videoElem) && ('autobuffer' in videoElem)){
|
|
var noBufferProps = {
|
|
metadata: 1,
|
|
none: 1
|
|
};
|
|
webshims.onNodeNamesPropertyModify(['audio', 'video'], ['preload'], {
|
|
set: function(value, boolValue, curType){
|
|
if(noBufferProps[value] || curType == 'removeAttr'){
|
|
this.autobuffer = false;
|
|
} else if( !(webshims.data(this, 'mediaelement') || {}).isActive == 'html5') {
|
|
this.autobuffer = true;
|
|
}
|
|
},
|
|
initAttr: true
|
|
});
|
|
}
|
|
})();
|
|
|
|
var fixProgressEvent = (function(){
|
|
if(support.mediaDefaultMuted){return $.noop;}
|
|
|
|
|
|
return function(){
|
|
if($.data(this, 'fixedMediaProgress')){return;}
|
|
var bufferTimer;
|
|
var lastBuffered;
|
|
var elem = this;
|
|
var getBufferedString = function(){
|
|
var buffered = $.prop(elem, 'buffered');
|
|
if(!buffered){return;}
|
|
var bufferString = "";
|
|
for(var i = 0, len = buffered.length; i < len;i++){
|
|
bufferString += buffered.end(i);
|
|
}
|
|
return bufferString;
|
|
};
|
|
var testBuffer = function(){
|
|
var buffered = getBufferedString();
|
|
if(buffered != lastBuffered){
|
|
lastBuffered = buffered;
|
|
webshims.error('needed to trigger progress manually');
|
|
$(elem).triggerHandler('progress');
|
|
}
|
|
};
|
|
|
|
$(this)
|
|
.data('fixedMediaProgress', true)
|
|
.on({
|
|
'play loadstart progress': function(e){
|
|
if(e.type == 'progress'){
|
|
lastBuffered = getBufferedString(this);
|
|
}
|
|
clearTimeout(bufferTimer);
|
|
bufferTimer = setTimeout(testBuffer, 800);
|
|
},
|
|
'emptied stalled mediaerror abort suspend': function(e){
|
|
if(e.type == 'emptied'){
|
|
lastBuffered = false;
|
|
}
|
|
clearTimeout(bufferTimer);
|
|
}
|
|
})
|
|
;
|
|
if('ActiveXObject' in window && $.prop(this, 'paused') && !$.prop(this, 'readyState') && $(this).is('audio[preload="none"][controls]:not([autoplay],.nonnative-api-active)')){
|
|
$(this).prop('preload', 'metadata').mediaLoad();
|
|
}
|
|
};
|
|
})();
|
|
|
|
webshims.addReady(function(context, insertedElement){
|
|
$('video, audio', context)
|
|
.add(insertedElement.filter('video, audio'))
|
|
.each(fixBuffered)
|
|
.each(fixProgressEvent)
|
|
;
|
|
|
|
});
|
|
|
|
});
|