| /******************************************************************************* | |
| * 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])); | |
| } | |
| })(); | |