blob: 8f02285dcb67c262c940b1c2e2533b50250ee69a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
//
// Ad-hoc codes to bridge the gap in implementations between modern browsers and old IEs
//
(function () {
var FORMAT_REPLACE = { ogv: 'wmv', oga: 'wma', mp4: 'wmv', m4a: 'wma' }; // for new Audio(src) and HTMLMediaElement#src (not for HTMLSourceElement#src)
var TYPE_SUPPORTED = { 'video/x-ms-wmv': true, 'audio/x-ms-wma': true, 'video/mpeg': true, 'audio/mpeg': true }; // for HTMLSourceElement#type
var MAX_PRELOADERS = 4;
if (typeof XMLHttpRequest == 'undefined') {
XMLHttpRequest = function () {
return new ActiveXObject('MSXML2.XMLHTTP');
};
}
globalEventListeners = {};
var fixMediaElement = function (media) {
var wmpMedia = createWMPMedia(media);
media.appendChild(wmpMedia);
media.__wmpMedia__ = wmpMedia;
media.__eventListeners__ = {};
media.addEventListener = addEventListener;
media.dispatchEvent = dispatchEvent;
media.play = play;
media.pause = pause;
media.paused = true;
media.ended = false;
media.volume = wmpMedia.settings.volume / 100;
media.currentTime = media.__prevTime__ = wmpMedia.controls.currentPosition;
createScript(wmpMedia.id, 'positionChange(oldPosition, newPosition)', 'globalEventListeners["' + wmpMedia.id + '"].positionChange(oldPosition, newPosition)');
createScript(wmpMedia.id, 'playStateChange(NewState)', 'globalEventListeners["' + wmpMedia.id + '"].playStateChange(NewState)');
globalEventListeners[wmpMedia.id] = {
positionChange: function (oldPosition, newPosition) {
media.dispatchEvent({ type: 'seeked', target: media });
},
playStateChange: function (NewState) {
switch (NewState) {
case 2: // Paused
media.paused = true;
media.ended = false;
// media.dispatchEvent({ type: 'pause', target: media });
break;
case 3: // Playing
media.paused = false;
media.ended = false;
media.dispatchEvent({ type: 'playing', target: media });
break;
case 8: // MediaEnded
media.paused = true;
media.ended = true;
media.dispatchEvent({ type: 'ended', target: media });
break;
case 6: case 7: // Buffering, Waiting
media.dispatchEvent({ type: 'waiting', target: media });
break;
}
}
};
if (media.getAttribute('preload') != 'none' && !media.__wmpMedia__.settings.autoStart) {
preloadMedia(media);
}
media.addEventListener('seeked', function (e) {
var media = e.target;
if (media.ended) {
media.__pausedForSync__ = true;
media.ended = false;
}
}, false);
var prevTime = wmpMedia.controls.currentPosition;
setInterval(function () {
var time = wmpMedia.controls.currentPosition;
if (time != prevTime) {
media.dispatchEvent({ type: 'timeupdate', target: media });
}
else {
media.dispatchEvent({ type: '__noop__', target: media });
}
prevTime = time;
}, 250);
};
var createScript = function (htmlFor, event, text) {
var s = document.createElement('script');
s.htmlFor = htmlFor;
s.event = event;
s.text = text;
document.body.appendChild(s);
};
var addEventListener = function (type, handler, capture) {
var v = this.__eventListeners__[type] || [];
v.push(handler);
this.__eventListeners__[type] = v;
};
var dispatchEvent = function (e) {
setTimeout(function () {
var media = e.target;
if (media.currentTime != media.__prevTime__) {
media.__wmpMedia__.controls.currentPosition = media.__prevTime__ = media.currentTime;
}
media.__prevTime__ = media.currentTime = media.__wmpMedia__.controls.currentPosition;
media.__wmpMedia__.settings.volume = media.volume * 100;
media.volume = media.__wmpMedia__.settings.volume / 100;
var v = media.__eventListeners__[e.type] || [];
for (var i = 0; i < v.length; ++i) {
v[i].call(media, e);
}
}, 0);
};
var play = function () {
this.__wmpMedia__.controls.currentPosition = this.currentTime;
this.__wmpMedia__.controls.play();
this.paused = false;
this.dispatchEvent({ type: 'play', target: this });
};
var pause = function () {
this.currentTime = this.__wmpMedia__.controls.currentPosition;
this.__wmpMedia__.controls.pause();
this.paused = true;
this.dispatchEvent({ type: 'pause', target: this });
};
var preloaders = 0;
var preloadMedia = function (media) {
(function () {
if (preloaders < MAX_PRELOADERS) {
var wmpFetch = createWMPFetch(media);
media.appendChild(wmpFetch);
++preloaders;
createScript(wmpFetch.id, 'openStateChange(NewState)', 'globalEventListeners["' + wmpFetch.id + '"].openStateChange(NewState)');
createScript(wmpFetch.id, 'playStateChange(NewState)', 'globalEventListeners["' + wmpFetch.id + '"].playStateChange(NewState)');
globalEventListeners[wmpFetch.id] = {
openStateChange: function (NewState) {
if (NewState == 13) { // MediaOpen
--preloaders;
}
},
playStateChange: function (NewState) {
if (NewState == 3) { // Playing
wmpFetch.controls.stop();
}
}
};
}
else {
setTimeout(arguments.callee, 1000);
}
})();
};
var fixDOMStructure = function (media) {
var newMedia = document.createElement(media.outerHTML);
var v = [];
for (var e = media.nextSibling; e.tagName != '/' + media.tagName; e = e.nextSibling) {
v.push(e);
}
for (var i = 0; i < v.length; ++i) {
newMedia.appendChild(v[i]);
}
media.parentNode.replaceChild(newMedia, media);
return newMedia;
};
var createWMPMedia = function (media) {
var wmp = document.createElement('object');
wmp.appendChild(createWMPParam('URL', getSourceURL(media)));
wmp.appendChild(createWMPParam('autoStart', media.getAttribute('autoplay') !== null ? 'true' : 'false'));
wmp.appendChild(createWMPParam('uiMode', media.getAttribute('controls') !== null ? 'full' : 'none'));
wmp.appendChild(createWMPParam('mute', media.getAttribute('muted') !== null ? 'true' : 'false'));
wmp.appendChild(createWMPParam('shrinkToFit', 'true'));
wmp.appendChild(createWMPParam('stretchToFit', 'true'));
wmp.appendChild(createWMPParam('windowlessVideo', 'true'));
wmp.width = media.getAttribute('width') || 1;
wmp.height = media.getAttribute('height') || 1;
wmp.id = document.uniqueID;
wmp.classid = 'CLSID:6BF52A52-394A-11D3-B153-00C04F79FAA6';
wmp.settings.mute = media.getAttribute('muted') !== null; // <param name=mute> does not work (?)
return wmp;
};
var createWMPFetch = function (media) {
var wmp = document.createElement('object');
wmp.appendChild(createWMPParam('URL', getSourceURL(media)));
wmp.width = 1;
wmp.height = 1;
wmp.id = document.uniqueID;
wmp.className = 'vd-prefetcher';
wmp.classid = 'CLSID:6BF52A52-394A-11D3-B153-00C04F79FAA6';
wmp.settings.mute = true;
return wmp;
};
var createWMPParam = function (name, value) {
var p = document.createElement('param');
p.name = name;
p.value = value;
return p;
};
var getSourceURL = function (media) {
if (media.src) {
return media.src.replace(/\b\w+$/, function (e) {
return FORMAT_REPLACE[e] || e;
});
}
var v = media.getElementsByTagName('source');
for (var i = 0; i < v.length; ++i) {
if (TYPE_SUPPORTED[v[i].type]) {
return v[i].src;
}
}
return v[0].src;
};
if (typeof Audio == 'undefined') {
Audio = function (url) {
this.src = url;
fixMediaElement(this);
};
Audio.prototype.appendChild = function (e) { document.body.appendChild(e) };
Audio.prototype.getAttribute = function (_) { return null };
}
var videoElems = document.getElementsByTagName('video');
for (var i = 0; i < videoElems.length; ++i) {
fixMediaElement(fixDOMStructure(videoElems[i]));
}
var audioElems = document.getElementsByTagName('audio');
for (var i = 0; i < audioElems.length; ++i) {
fixMediaElement(fixDOMStructure(audioElems[i]));
}
})();