From e6d4ac85558f7dd8a990d36f8e7eb8296dcc2c83 Mon Sep 17 00:00:00 2001 From: llaffont <llaffont@git-test.afi-sa.fr> Date: Thu, 22 Nov 2012 16:25:03 +0000 Subject: [PATCH] Notices GAM: lecture audio fonctionne sous IE8/7 --- .gitattributes | 14 + .../opac/controllers/NoticeajaxController.php | 2 - doc/extern_libs.txt | 1 + library/Class/NoticeHtml.php | 10 +- library/ZendAfi/View/Helper/AudioJsPlayer.php | 8 +- public/admin/js/audiojs/Manifest | 5 + public/admin/js/audiojs/README.md | 70 ++ public/admin/js/audiojs/Rakefile | 21 + public/admin/js/audiojs/audiojs/audio.js | 673 ++++++++++++++++++ public/admin/js/audiojs/audiojs/audio.min.js | 48 +- public/admin/js/audiojs/audiojs/audiojs.as | 146 ++++ public/admin/js/audiojs/audiojs/audiojs.swf | Bin 1644 -> 1733 bytes public/admin/js/audiojs/audiojs/audiojs2.swf | Bin 0 -> 1733 bytes .../audiojs/audiojs/player-graphics_blue.gif | Bin 0 -> 3546 bytes .../admin/js/audiojs/audiojs/style-dark.css | 189 +++++ .../admin/js/audiojs/audiojs/style-light.css | 188 +++++ .../admin/js/audiojs/audiojs/vol-graphics.png | Bin 0 -> 1091 bytes public/admin/js/audiojs/demos/test1.html | 24 + public/admin/js/audiojs/demos/test4.html | 29 + public/admin/js/audiojs/demos/test6.html | 39 + public/admin/js/audiojs/includes/divider.png | Bin 0 -> 379 bytes public/admin/js/audiojs/includes/index.css | 24 +- public/admin/js/audiojs/index.html | 36 +- .../ZendAfi/View/Helper/AudioJSPlayerTest.php | 13 +- 24 files changed, 1471 insertions(+), 69 deletions(-) create mode 100644 public/admin/js/audiojs/Manifest create mode 100644 public/admin/js/audiojs/README.md create mode 100644 public/admin/js/audiojs/Rakefile create mode 100644 public/admin/js/audiojs/audiojs/audio.js create mode 100644 public/admin/js/audiojs/audiojs/audiojs.as create mode 100644 public/admin/js/audiojs/audiojs/audiojs2.swf create mode 100644 public/admin/js/audiojs/audiojs/player-graphics_blue.gif create mode 100644 public/admin/js/audiojs/audiojs/style-dark.css create mode 100644 public/admin/js/audiojs/audiojs/style-light.css create mode 100644 public/admin/js/audiojs/audiojs/vol-graphics.png create mode 100644 public/admin/js/audiojs/demos/test1.html create mode 100644 public/admin/js/audiojs/demos/test4.html create mode 100644 public/admin/js/audiojs/demos/test6.html create mode 100644 public/admin/js/audiojs/includes/divider.png diff --git a/.gitattributes b/.gitattributes index 7ee2e126f36..b581efd56c0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3007,9 +3007,23 @@ public/admin/images/zone/zone_5.jpg -text public/admin/images/zone/zone_6.jpg -text public/admin/images/zone/zone_7.jpg -text public/admin/js/audiojs/LICENSE -text +public/admin/js/audiojs/Manifest -text +public/admin/js/audiojs/README.md -text +public/admin/js/audiojs/Rakefile -text +public/admin/js/audiojs/audiojs/audio.js -text public/admin/js/audiojs/audiojs/audio.min.js -text +public/admin/js/audiojs/audiojs/audiojs.as -text public/admin/js/audiojs/audiojs/audiojs.swf -text svneol=unset#unset +public/admin/js/audiojs/audiojs/audiojs2.swf -text svneol=unset#unset public/admin/js/audiojs/audiojs/player-graphics.gif -text svneol=unset#unset +public/admin/js/audiojs/audiojs/player-graphics_blue.gif -text svneol=unset#unset +public/admin/js/audiojs/audiojs/style-dark.css -text +public/admin/js/audiojs/audiojs/style-light.css -text +public/admin/js/audiojs/audiojs/vol-graphics.png -text svneol=unset#unset +public/admin/js/audiojs/demos/test1.html -text +public/admin/js/audiojs/demos/test4.html -text +public/admin/js/audiojs/demos/test6.html -text +public/admin/js/audiojs/includes/divider.png -text svneol=unset#unset public/admin/js/audiojs/includes/index.css -text public/admin/js/audiojs/index.html -text public/admin/js/cacheimages.js -text diff --git a/application/modules/opac/controllers/NoticeajaxController.php b/application/modules/opac/controllers/NoticeajaxController.php index 61b9ba0661d..5d360c9e9f5 100644 --- a/application/modules/opac/controllers/NoticeajaxController.php +++ b/application/modules/opac/controllers/NoticeajaxController.php @@ -282,8 +282,6 @@ class NoticeAjaxController extends Zend_Controller_Action { $morceaux["id_notice"]=$notice["id_notice"]; } $morceaux["auteur"]=$notice["A"]; - Class_ScriptLoader::getInstance()->loadJQuery(); - $this->view->audioJsPlayer(); $html=$this->notice_html->getMorceaux($morceaux,$source); $this->_sendResponse(Class_ScriptLoader::getInstance()->html().$html); } diff --git a/doc/extern_libs.txt b/doc/extern_libs.txt index c8ccec177ad..6380c0a660f 100644 --- a/doc/extern_libs.txt +++ b/doc/extern_libs.txt @@ -31,6 +31,7 @@ | JQuery PlaceHolder plugin | MIT/GPL | | compat IE | | https://github.com/mathiasbynens/jquery-placeholder | | OSM Player | GPL v3 | | player multimedia | | http://mediafront.org/osmplayer/index.html#.UFB0Q3lOpw4 | | jQuery Mobile Icon Pack | CC BY 3.0 + MIT / GPL | | icônes version téléphone | | https://github.com/commadelimited/jQuery-Mobile-Icon-Pack | +| AudioJS | MIT | | lire les morceaux notices GAM | X (css) | http://kolber.github.com/audiojs/ | | | | | | | | diff --git a/library/Class/NoticeHtml.php b/library/Class/NoticeHtml.php index 7aa64955501..6d21c99642e 100644 --- a/library/Class/NoticeHtml.php +++ b/library/Class/NoticeHtml.php @@ -566,6 +566,8 @@ class Class_NoticeHtml { { $ix= new Class_Indexation(); $html=$this->haut_onglet; + $audio_js_player = new ZendAfi_View_Helper_AudioJsPlayer(); + if(!$notice["morceaux"]) return $html.$this->getNonTrouve(); $html.='<table width="100%">'; $html.=sprintf('<tr><td class="notice_info_titre" align="left" colspan="4">%s : %s</td></tr>', @@ -617,13 +619,9 @@ class Class_NoticeHtml { "afficher_media('".$id_div."','close','')", $this->_translate->_("Replier"), $this->_translate->_("Replier")); + if (isset($morceau["url_ecoute"])) - { - $id_morceau="morceau_".$plage; - $img_ecoute='<div id="'.$id_morceau.'">'; - $img_ecoute.='<audio src="'.$morceau["url_ecoute"].'" controls="controls">'; - $img_ecoute.='</div>'; - } + $img_ecoute .= $audio_js_player->audioJsPlayer($morceau["url_ecoute"]); } // Html diff --git a/library/ZendAfi/View/Helper/AudioJsPlayer.php b/library/ZendAfi/View/Helper/AudioJsPlayer.php index 7328b1d4818..d5ac8b58946 100644 --- a/library/ZendAfi/View/Helper/AudioJsPlayer.php +++ b/library/ZendAfi/View/Helper/AudioJsPlayer.php @@ -26,13 +26,17 @@ class ZendAfi_View_Helper_AudioJsPlayer extends Zend_View_Helper_HtmlElement { * $this->audioJsPlayer(); * Voir: http://kolber.github.com/audiojs/ */ - public function audioJsPlayer() { + public function audioJsPlayer($src) { $options = ['swfLocation' => URL_ADMIN_JS.'audiojs/audiojs/audiojs.swf', 'imageLocation' => URL_ADMIN_JS.'audiojs/audiojs/player-graphics.gif']; - return Class_ScriptLoader::getInstance() + Class_ScriptLoader::getInstance() + ->loadJQuery() + ->addStyleSheet(URL_ADMIN_JS.'audiojs/audiojs/style-light.css') ->addAdminScript('audiojs/audiojs/audio.min.js') ->addInlineScript(sprintf('audiojs.events.ready(function() {audiojs.createAll(%s);})', json_encode($options))); + + return '<audio controls="controls"><source src="'.$src.'"></audio>'; } } diff --git a/public/admin/js/audiojs/Manifest b/public/admin/js/audiojs/Manifest new file mode 100644 index 00000000000..0e36b43f64a --- /dev/null +++ b/public/admin/js/audiojs/Manifest @@ -0,0 +1,5 @@ +audiojs/audio.min.js +audiojs/audiojs.swf +audiojs/player-graphics.gif +includes/index.css +index.html \ No newline at end of file diff --git a/public/admin/js/audiojs/README.md b/public/admin/js/audiojs/README.md new file mode 100644 index 00000000000..9eae82aae50 --- /dev/null +++ b/public/admin/js/audiojs/README.md @@ -0,0 +1,70 @@ +# audio.js + +audiojs is a drop-in javascript library that allows HTML5's `<audio>` tag to +be used anywhere. It uses native `<audio>` where available and falls back +to an invisible flash player to emulate it for other browsers. It also serves +a consistent html player UI to all browsers which can be styled used standard css. + +It plays mp3s. **No ogg**. Because, lets be honest, in the real world, no one +really exports ogg files. Sadly, that means Opera and Firefox get flash audio. +Hopefully they can add mp3 support soon. + +## Usage + +1. Put `audio.js`, `style-light.css`, `player-graphics.gif` & `audiojs.swf` in the same folder. + +2. Include `style-light.css`: + + <link rel="stylesheet" href="style-light.css" media="screen"> + +3. Include `audio.js`: + + <script src="/audiojs/audio.js"></script> + +4. Initialise audiojs: + + <script> + audiojs.events.ready(function() { + var as = audiojs.createAll(); + }); + </script> + +5. Then you can use `<audio>` wherever you like in your HTML: + + <audio src="/mp3/juicy.mp3" preload="auto" /> + +## Bugs / Contributions + +- [Report a bug](https://github.com/kolber/audiojs/issues) +- To contribute or send an idea, github message me or fork the project + +## Build + +On OSX, you should install [closure compiler](http://closure-compiler.googlecode.com/files/compiler-latest.zip) following the instructions in +[Ben's gist](https://gist.github.com/739724). + +Then you can run `rake compile` from root directory and it will package `audio.js` +into `audio.min.js`. + +## Compiling Flash from the command line + +If you want to mess around with the flash-side of things, you will need to be +able to compile the `.as` file into a `.swf`. + +Using the Flex SDK (which is free), flash movies can be compiled +directly from the command line. It makes life that little bit less painful. + +### Installing mxmlc + +1. Download and unzip the current 'Milestone Release' 'Open Source Flex SDK' from: + <http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4> + +2. Copy the `bin` folder to `/usr/local/bin/flex/bin/` + +3. Add `/usr/local/bin/flex/bin/` to your `PATH` + +### Compiling the SWF + +Run the following command from within the `audiojs` folder. + + mxmlc audiojs.as \ No newline at end of file diff --git a/public/admin/js/audiojs/Rakefile b/public/admin/js/audiojs/Rakefile new file mode 100644 index 00000000000..9924df3cd6b --- /dev/null +++ b/public/admin/js/audiojs/Rakefile @@ -0,0 +1,21 @@ +desc "Compile and commit new build to git" +task :build => [:compile, :commit_build] + +desc "Build audio.js to audio.min.js" +task :compile do + `closure --js=audiojs/audio.js --compilation_level=SIMPLE_OPTIMIZATIONS --js_output_file=audiojs/audio.min.js --warning_level=QUIET` +end + +task :commit_build do + `git commit audiojs/audio.min.js -m "Closure compiled \`git rev-parse HEAD\`"` +end + +desc "Zip up a release" +task :release => :compile do + `cat Manifest | zip -9 -@ audiojs.zip` +end + +#desc "Run the test suite" +#task :test do +# `open -a Safari test/suite.html` +#end diff --git a/public/admin/js/audiojs/audiojs/audio.js b/public/admin/js/audiojs/audiojs/audio.js new file mode 100644 index 00000000000..9307936dacc --- /dev/null +++ b/public/admin/js/audiojs/audiojs/audio.js @@ -0,0 +1,673 @@ +// A cross-browser javascript shim for html5 audio +(function(audiojs, audiojsInstance, container) { + // Use the path to the audio.js file to create relative paths to the swf and player graphics + // Remember that some systems (e.g. ruby on rails) append strings like '?1301478336' to asset paths + var path = (function() { + var re = new RegExp('audio(\.min)?\.js.*'), + scripts = document.getElementsByTagName('script'); + for (var i = 0, ii = scripts.length; i < ii; i++) { + var path = scripts[i].getAttribute('src'); + if(re.test(path)) return path.replace(re, ''); + } + })(); + + // ##The audiojs interface + // This is the global object which provides an interface for creating new `audiojs` instances. + // It also stores all of the construction helper methods and variables. + container[audiojs] = { + instanceCount: 0, + instances: {}, + // The markup for the swf. It is injected into the page if there is not support for the `<audio>` element. The `$n`s are placeholders. + // `$1` The name of the flash movie + // `$2` The path to the swf + // `$3` Cache invalidation + flashSource: '\ + <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="$1" width="1" height="1" name="$1" style="position: absolute; left: -1px;"> \ + <param name="movie" value="$2?playerInstance='+audiojs+'.instances[\'$1\']&datetime=$3"> \ + <param name="allowscriptaccess" value="always"> \ + <embed name="$1" src="$2?playerInstance='+audiojs+'.instances[\'$1\']&datetime=$3" width="1" height="1" allowscriptaccess="always"> \ + </object>', + + // ### The main settings object + // Where all the default settings are stored. Each of these variables and methods can be overwritten by the user-provided `options` object. + settings: { + autoplay: false, + loop: false, + preload: true, + initialVolume: 0.5, + imageLocation: path + 'player-graphics.gif', + swfLocation: path + 'audiojs.swf', + useFlash: (function() { + var a = document.createElement('audio'); + return !(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, '')); + })(), + hasFlash: (function() { + if (navigator.plugins && navigator.plugins.length && navigator.plugins['Shockwave Flash']) { + return true; + } else if (navigator.mimeTypes && navigator.mimeTypes.length) { + var mimeType = navigator.mimeTypes['application/x-shockwave-flash']; + return mimeType && mimeType.enabledPlugin; + } else { + try { + var ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); + return true; + } catch (e) {} + } + return false; + })(), + // The default markup and classes for creating the player: + createPlayer: { + markup: '\ + <div class="play-pause"> \ + <p class="play"></p> \ + <p class="pause"></p> \ + <p class="loading"></p> \ + <p class="error"></p> \ + </div> \ + <div class="scrubber"> \ + <div class="progress"></div> \ + <div class="loaded"></div> \ + </div> \ + <div class="time"> \ + <em class="played">00:00</em>/<strong class="duration">00:00</strong> \ + </div> \ + <div class="volume"> \ + <div class="level"></div> \ + </div> \ + <div class="error-message"></div>', + playPauseClass: 'play-pause', + scrubberClass: 'scrubber', + progressClass: 'progress', + loaderClass: 'loaded', + timeClass: 'time', + durationClass: 'duration', + playedClass: 'played', + errorMessageClass: 'error-message', + playingClass: 'playing', + loadingClass: 'loading', + errorClass: 'error', + volumeClass: 'volume', + levelClass: 'level' + }, + // The default event callbacks: + trackEnded: function(e) {}, + flashError: function() { + var player = this.settings.createPlayer, + errorMessage = getByClass(player.errorMessageClass, this.wrapper), + html = 'Missing <a href="http://get.adobe.com/flashplayer/">flash player</a> plugin.'; + if (this.mp3) html += ' <a href="'+this.mp3+'">Download audio file</a>.'; + container[audiojs].helpers.removeClass(this.wrapper, player.loadingClass); + container[audiojs].helpers.addClass(this.wrapper, player.errorClass); + errorMessage.innerHTML = html; + }, + loadError: function(e) { + var player = this.settings.createPlayer, + errorMessage = getByClass(player.errorMessageClass, this.wrapper); + container[audiojs].helpers.removeClass(this.wrapper, player.loadingClass); + container[audiojs].helpers.addClass(this.wrapper, player.errorClass); + errorMessage.innerHTML = 'Error loading: "'+this.mp3+'"'; + }, + init: function() { + var player = this.settings.createPlayer; + container[audiojs].helpers.addClass(this.wrapper, player.loadingClass); + }, + loadStarted: function() { + var player = this.settings.createPlayer, + duration = getByClass(player.durationClass, this.wrapper), + m = Math.floor(this.duration / 60), + s = Math.floor(this.duration % 60); + container[audiojs].helpers.removeClass(this.wrapper, player.loadingClass); + duration.innerHTML = ((m<10?'0':'')+m+':'+(s<10?'0':'')+s); + }, + loadProgress: function(percent) { + var player = this.settings.createPlayer, + loaded = getByClass(player.loaderClass, this.wrapper); + loaded.style.width = (100 * percent) + '%'; + }, + playPause: function() { + if (this.playing) this.settings.play(); + else this.settings.pause(); + }, + play: function() { + var player = this.settings.createPlayer; + container[audiojs].helpers.addClass(this.wrapper, player.playingClass); + }, + pause: function() { + var player = this.settings.createPlayer; + container[audiojs].helpers.removeClass(this.wrapper, player.playingClass); + }, + updatePlayhead: function(percent) { + var player = this.settings.createPlayer, + progress = getByClass(player.progressClass, this.wrapper); + progress.style.width = (100 * percent) + '%'; + + var played = getByClass(player.playedClass, this.wrapper), + p = this.duration * percent, + m = Math.floor(p / 60), + s = Math.floor(p % 60); + played.innerHTML = ((m<10?'0':'')+m+':'+(s<10?'0':'')+s); + }, + volume: function(percent) { + var player = this.settings.createPlayer, + volume = getByClass(player.volumeClass, this.wrapper), + level = getByClass(player.levelClass, this.wrapper); + level.style.width = (volume.offsetWidth * percent) + 'px'; + } + }, + + // ### Contructor functions + + // `create()` + // Used to create a single `audiojs` instance. + // If an array is passed then it calls back to `createAll()`. + // Otherwise, it creates a single instance and returns it. + create: function(element, options) { + var options = options || {} + if (element.length) { + return this.createAll(options, element); + } else { + return this.newInstance(element, options); + } + }, + + // `createAll()` + // Creates multiple `audiojs` instances. + // If `elements` is `null`, then automatically find any `<audio>` tags on the page and create `audiojs` instances for them. + createAll: function(options, elements) { + var audioElements = elements || document.getElementsByTagName('audio'), + instances = [], + options = options || {}, + re = new RegExp('audiojs_wrapper\\d+'); + for (var i = 0, ii = audioElements.length; i < ii; i++) { + var e = audioElements[i].parentNode, + wrapped = false; + if (e && e.getAttribute) { + var id = e.getAttribute('id'); + if (id != null && re.test(id)) wrapped = true; + } + if (! wrapped) instances.push(this.newInstance(audioElements[i], options)); + } + return instances; + }, + + // ### Creating and returning a new instance + // This goes through all the steps required to build out a usable `audiojs` instance. + newInstance: function(element, options) { + var element = element, + s = this.helpers.clone(this.settings), + id = 'audiojs'+this.instanceCount, + wrapperId = 'audiojs_wrapper'+this.instanceCount, + instanceCount = this.instanceCount++; + + // Check for `autoplay`, `loop` and `preload` attributes and write them into the settings. + if (element.getAttribute('autoplay') != null) s.autoplay = true; + if (element.getAttribute('loop') != null) s.loop = true; + if (element.getAttribute('preload') == 'none') s.preload = false; + // Merge the default settings with the user-defined `options`. + if (options) this.helpers.merge(s, options); + + // Inject the player html if required. + if (s.createPlayer.markup) element = this.createPlayer(element, s.createPlayer, wrapperId); + else element.parentNode.setAttribute('id', wrapperId); + + // Return a new `audiojs` instance. + var audio = new container[audiojsInstance](element, s); + + // If `<audio>` or mp3 playback isn't supported, insert the swf & attach the required events for it. + if (s.useFlash && s.hasFlash) { + this.injectFlash(audio, id); + this.attachFlashEvents(audio.wrapper, audio); + } else if (s.useFlash && !s.hasFlash) { + this.settings.flashError.apply(audio); + } + + // Attach event callbacks to the new audiojs instance. + if (!s.useFlash || (s.useFlash && s.hasFlash)) this.attachEvents(audio.wrapper, audio); + + // Set initial volume to the new audiojs instance. + if (!s.useFlash) { + audio.setVolume.call(audio, s.initialVolume); + } + + // Store the newly-created `audiojs` instance. + this.instances[id] = audio; + return audio; + }, + + // ### Helper methods for constructing a working player + // Inject a wrapping div and the markup for the html player. + createPlayer: function(element, player, id) { + var wrapper = document.createElement('div'), + newElement = element.cloneNode(true); + var divClass = element.getAttribute('class') || 'audiojs'; + wrapper.setAttribute('class', divClass); + wrapper.setAttribute('className', 'audiojs'); + wrapper.setAttribute('id', id); + + // Fix IE's broken implementation of `innerHTML` & `cloneNode` for HTML5 elements. + if (newElement.outerHTML && !document.createElement('audio').canPlayType) { + newElement = this.helpers.cloneHtml5Node(element); + wrapper.innerHTML = player.markup; + wrapper.appendChild(newElement); + element.outerHTML = wrapper.outerHTML; + wrapper = document.getElementById(id); + } else { + wrapper.appendChild(newElement); + wrapper.innerHTML = wrapper.innerHTML + player.markup; + element.parentNode.replaceChild(wrapper, element); + } + return wrapper.getElementsByTagName('audio')[0]; + }, + + // Attaches useful event callbacks to an `audiojs` instance. + attachEvents: function(wrapper, audio) { + if (!audio.settings.createPlayer) return; + var player = audio.settings.createPlayer, + playPause = getByClass(player.playPauseClass, wrapper), + scrubber = getByClass(player.scrubberClass, wrapper), + volume = getByClass(player.volumeClass, wrapper), + getOffsetSum = function(elem) { + var curleft = 0; + if (elem.offsetParent) { + do { curleft += elem.offsetLeft; } while (elem = elem.offsetParent); + } + return curleft; + }, + getOffsetRect = function(elem) { + var box = elem.getBoundingClientRect(), + body = document.body, + docElem = document.documentElement, + scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft, + clientLeft = docElem.clientLeft || body.clientLeft || 0; + + return Math.round(box.left + scrollLeft - clientLeft); + }, + getLeftOffset = function(elem) { + if (elem.getBoundingClientRect) { + return getOffsetRect(elem) + } else { + return getOffsetSum(elem) + } + }; + + container[audiojs].events.addListener(playPause, 'click', function(e) { + audio.playPause.apply(audio); + }); + + container[audiojs].events.addListener(scrubber, 'click', function(e) { + var relativeLeft = e.clientX - getLeftOffset(this); + audio.skipTo(relativeLeft / scrubber.offsetWidth); + }); + + container[audiojs].events.addListener(volume, 'click', function(e) { + var relativeLeft = e.clientX - getLeftOffset(this); + audio.setVolume(relativeLeft / volume.offsetWidth); + }); + + // _If flash is being used, then the following handlers don't need to be registered._ + if (audio.settings.useFlash) return; + + // Start tracking the load progress of the track. + container[audiojs].events.trackLoadProgress(audio); + + container[audiojs].events.addListener(audio.element, 'timeupdate', function(e) { + audio.updatePlayhead.apply(audio); + }); + + container[audiojs].events.addListener(audio.element, 'ended', function(e) { + audio.trackEnded.apply(audio); + }); + + container[audiojs].events.addListener(audio.source, 'error', function(e) { + // on error, cancel any load timers that are running. + clearInterval(audio.readyTimer); + clearInterval(audio.loadTimer); + audio.settings.loadError.apply(audio); + }); + + }, + + // Flash requires a slightly different API to the `<audio>` element, so this method is used to overwrite the standard event handlers. + attachFlashEvents: function(element, audio) { + audio['swfReady'] = false; + audio['load'] = function(mp3) { + // If the swf isn't ready yet then just set `audio.mp3`. `init()` will load it in once the swf is ready. + audio.mp3 = mp3; + if (audio.swfReady) audio.element.load(mp3); + } + audio['loadProgress'] = function(percent, duration) { + audio.loadedPercent = percent; + audio.duration = duration; + audio.settings.loadStarted.apply(audio); + audio.settings.loadProgress.apply(audio, [percent]); + } + audio['skipTo'] = function(percent) { + if (percent > audio.loadedPercent) return; + audio.updatePlayhead.call(audio, [percent]) + audio.element.skipTo(percent); + } + audio['updatePlayhead'] = function(percent) { + audio.settings.updatePlayhead.apply(audio, [percent]); + } + audio['play'] = function() { + // If the audio hasn't started preloading, then start it now. + // Then set `preload` to `true`, so that any tracks loaded in subsequently are loaded straight away. + if (!audio.settings.preload) { + audio.settings.preload = true; + audio.element.init(audio.mp3); + } + audio.playing = true; + // IE doesn't allow a method named `play()` to be exposed through `ExternalInterface`, so lets go with `pplay()`. + // <http://dev.nuclearrooster.com/2008/07/27/externalinterfaceaddcallback-can-cause-ie-js-errors-with-certain-keyworkds/> + audio.element.pplay(); + audio.settings.play.apply(audio); + } + audio['pause'] = function() { + audio.playing = false; + // Use `ppause()` for consistency with `pplay()`, even though it isn't really required. + audio.element.ppause(); + audio.settings.pause.apply(audio); + } + audio['setVolume'] = function(v) { + audio.element.setVolume(v); + audio.settings.volume.call(audio, [v]) + } + audio['loadStarted'] = function() { + // Load the mp3 specified by the audio element into the swf. + audio.swfReady = true; + if (audio.settings.preload) audio.element.init(audio.mp3); + if (audio.settings.autoplay) audio.play.apply(audio); + } + }, + + // ### Injecting an swf from a string + // Build up the swf source by replacing the `$keys` and then inject the markup into the page. + injectFlash: function(audio, id) { + var flashSource = this.flashSource.replace(/\$1/g, id); + flashSource = flashSource.replace(/\$2/g, audio.settings.swfLocation); + // `(+new Date)` ensures the swf is not pulled out of cache. The fixes an issue with Firefox running multiple players on the same page. + flashSource = flashSource.replace(/\$3/g, (+new Date + Math.random())); + // Inject the player markup using a more verbose `innerHTML` insertion technique that works with IE. + var html = audio.wrapper.innerHTML, + div = document.createElement('div'); + div.innerHTML = flashSource + html; + audio.wrapper.innerHTML = div.innerHTML; + audio.element = this.helpers.getSwf(id); + }, + + // ## Helper functions + helpers: { + // **Merge two objects, with `obj2` overwriting `obj1`** + // The merge is shallow, but that's all that is required for our purposes. + merge: function(obj1, obj2) { + for (attr in obj2) { + if (obj1.hasOwnProperty(attr) || obj2.hasOwnProperty(attr)) { + obj1[attr] = obj2[attr]; + } + } + }, + // **Clone a javascript object (recursively)** + clone: function(obj){ + if (obj == null || typeof(obj) !== 'object') return obj; + var temp = new obj.constructor(); + for (var key in obj) temp[key] = arguments.callee(obj[key]); + return temp; + }, + // **Adding/removing classnames from elements** + addClass: function(element, className) { + var re = new RegExp('(\\s|^)'+className+'(\\s|$)'); + if (re.test(element.className)) return; + element.className += ' ' + className; + }, + removeClass: function(element, className) { + var re = new RegExp('(\\s|^)'+className+'(\\s|$)'); + element.className = element.className.replace(re,' '); + }, + // **Handle all the IE6+7 requirements for cloning `<audio>` nodes** + // Create a html5-safe document fragment by injecting an `<audio>` element into the document fragment. + cloneHtml5Node: function(audioTag) { + var fragment = document.createDocumentFragment(), + doc = fragment.createElement ? fragment : document; + doc.createElement('audio'); + var div = doc.createElement('div'); + fragment.appendChild(div); + div.innerHTML = audioTag.outerHTML; + return div.firstChild; + }, + // **Cross-browser `<object>` / `<embed>` element selection** + getSwf: function(name) { + var swf = document[name] || window[name]; + return swf.length > 1 ? swf[swf.length - 1] : swf; + } + }, + // ## Event-handling + events: { + memoryLeaking: false, + listeners: [], + // **A simple cross-browser event handler abstraction** + addListener: function(element, eventName, func) { + // For modern browsers use the standard DOM-compliant `addEventListener`. + if (element.addEventListener) { + element.addEventListener(eventName, func, false); + // For older versions of Internet Explorer, use `attachEvent`. + // Also provide a fix for scoping `this` to the calling element and register each listener so the containing elements can be purged on page unload. + } else if (element.attachEvent) { + this.listeners.push(element); + if (!this.memoryLeaking) { + window.attachEvent('onunload', function() { + if(this.listeners) { + for (var i = 0, ii = this.listeners.length; i < ii; i++) { + container[audiojs].events.purge(this.listeners[i]); + } + } + }); + this.memoryLeaking = true; + } + element.attachEvent('on' + eventName, function() { + func.call(element, window.event); + }); + } + }, + + trackLoadProgress: function(audio) { + // If `preload` has been set to `none`, then we don't want to start loading the track yet. + if (!audio.settings.preload) return; + + var readyTimer, + loadTimer, + audio = audio, + ios = (/(ipod|iphone|ipad)/i).test(navigator.userAgent); + + // Use timers here rather than the official `progress` event, as Chrome has issues calling `progress` when loading mp3 files from cache. + readyTimer = setInterval(function() { + if (audio.element.readyState > -1) { + // iOS doesn't start preloading the mp3 until the user interacts manually, so this stops the loader being displayed prematurely. + if (!ios) audio.init.apply(audio); + } + if (audio.element.readyState > 1) { + if (audio.settings.autoplay) audio.play.apply(audio); + clearInterval(readyTimer); + // Once we have data, start tracking the load progress. + loadTimer = setInterval(function() { + audio.loadProgress.apply(audio); + if (audio.loadedPercent >= 1) clearInterval(loadTimer); + }); + } + }, 10); + audio.readyTimer = readyTimer; + audio.loadTimer = loadTimer; + }, + + // **Douglas Crockford's IE6 memory leak fix** + // <http://javascript.crockford.com/memory/leak.html> + // This is used to release the memory leak created by the circular references created when fixing `this` scoping for IE. It is called on page unload. + purge: function(d) { + var a = d.attributes, i; + if (a) { + for (i = 0; i < a.length; i += 1) { + if (typeof d[a[i].name] === 'function') d[a[i].name] = null; + } + } + a = d.childNodes; + if (a) { + for (i = 0; i < a.length; i += 1) purge(d.childNodes[i]); + } + }, + + // **DOMready function** + // As seen here: <https://github.com/dperini/ContentLoaded/>. + ready: (function() { return function(fn) { + var win = window, done = false, top = true, + doc = win.document, root = doc.documentElement, + add = doc.addEventListener ? 'addEventListener' : 'attachEvent', + rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent', + pre = doc.addEventListener ? '' : 'on', + init = function(e) { + if (e.type == 'readystatechange' && doc.readyState != 'complete') return; + (e.type == 'load' ? win : doc)[rem](pre + e.type, init, false); + if (!done && (done = true)) fn.call(win, e.type || e); + }, + poll = function() { + try { root.doScroll('left'); } catch(e) { setTimeout(poll, 50); return; } + init('poll'); + }; + if (doc.readyState == 'complete') fn.call(win, 'lazy'); + else { + if (doc.createEventObject && root.doScroll) { + try { top = !win.frameElement; } catch(e) { } + if (top) poll(); + } + doc[add](pre + 'DOMContentLoaded', init, false); + doc[add](pre + 'readystatechange', init, false); + win[add](pre + 'load', init, false); + } + } + })() + + } + } + + // ## The audiojs class + // We create one of these per `<audio>` and then push them into `audiojs['instances']`. + container[audiojsInstance] = function(element, settings) { + // Each audio instance returns an object which contains an API back into the `<audio>` element. + this.element = element; + this.wrapper = element.parentNode; + this.source = element.getElementsByTagName('source')[0] || element; + // First check the `<audio>` element directly for a src and if one is not found, look for a `<source>` element. + this.mp3 = (function(element) { + var source = element.getElementsByTagName('source')[0]; + return element.getAttribute('src') || (source ? source.getAttribute('src') : null); + })(element); + this.settings = settings; + this.loadStartedCalled = false; + this.loadedPercent = 0; + this.duration = 1; + this.playing = false; + } + + container[audiojsInstance].prototype = { + // API access events: + // Each of these do what they need do and then call the matching methods defined in the settings object. + updatePlayhead: function() { + var percent = this.element.currentTime / this.duration; + this.settings.updatePlayhead.apply(this, [percent]); + }, + skipTo: function(percent) { + if (percent > this.loadedPercent) return; + this.element.currentTime = this.duration * percent; + this.updatePlayhead(); + }, + load: function(mp3) { + this.loadStartedCalled = false; + this.source.setAttribute('src', mp3); + // The now outdated `load()` method is required for Safari 4 + this.element.load(); + this.mp3 = mp3; + container[audiojs].events.trackLoadProgress(this); + }, + loadError: function() { + this.settings.loadError.apply(this); + }, + init: function() { + this.settings.init.apply(this); + }, + loadStarted: function() { + // Wait until `element.duration` exists before setting up the audio player. + if (!this.element.duration) return false; + + this.duration = this.element.duration; + this.updatePlayhead(); + this.settings.loadStarted.apply(this); + }, + loadProgress: function() { + if (this.element.buffered != null && this.element.buffered.length) { + // Ensure `loadStarted()` is only called once. + if (!this.loadStartedCalled) { + this.loadStartedCalled = this.loadStarted(); + } + var durationLoaded = this.element.buffered.end(this.element.buffered.length - 1); + this.loadedPercent = durationLoaded / this.duration; + + this.settings.loadProgress.apply(this, [this.loadedPercent]); + } + }, + playPause: function() { + if (this.playing) this.pause(); + else this.play(); + }, + play: function() { + var ios = (/(ipod|iphone|ipad)/i).test(navigator.userAgent); + // On iOS this interaction will trigger loading the mp3, so run `init()`. + if (ios && this.element.readyState == 0) this.init.apply(this); + // If the audio hasn't started preloading, then start it now. + // Then set `preload` to `true`, so that any tracks loaded in subsequently are loaded straight away. + if (!this.settings.preload) { + this.settings.preload = true; + this.element.setAttribute('preload', 'auto'); + container[audiojs].events.trackLoadProgress(this); + } + this.playing = true; + this.element.play(); + this.settings.play.apply(this); + }, + pause: function() { + this.playing = false; + this.element.pause(); + this.settings.pause.apply(this); + }, + setVolume: function(v) { + this.element.volume = v; + this.settings.volume.apply(this, [v]); + }, + trackEnded: function(e) { + this.skipTo.apply(this, [0]); + if (!this.settings.loop) this.pause.apply(this); + this.settings.trackEnded.apply(this); + } + } + + // **getElementsByClassName** + // Having to rely on `getElementsByTagName` is pretty inflexible internally, so a modified version of Dustin Diaz's `getElementsByClassName` has been included. + // This version cleans things up and prefers the native DOM method if it's available. + var getByClass = function(searchClass, node) { + var matches = []; + node = node || document; + + if (node.getElementsByClassName) { + matches = node.getElementsByClassName(searchClass); + } else { + var i, l, + els = node.getElementsByTagName("*"), + pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"); + + for (i = 0, l = els.length; i < l; i++) { + if (pattern.test(els[i].className)) { + matches.push(els[i]); + } + } + } + return matches.length > 1 ? matches : matches[0]; + }; +// The global variable names are passed in here and can be changed if they conflict with anything else. +})('audiojs', 'audiojsInstance', this); diff --git a/public/admin/js/audiojs/audiojs/audio.min.js b/public/admin/js/audiojs/audiojs/audio.min.js index e5fde2b1fdf..db6ab35a2d2 100644 --- a/public/admin/js/audiojs/audiojs/audio.min.js +++ b/public/admin/js/audiojs/audiojs/audio.min.js @@ -1,24 +1,24 @@ -(function(h,o,g){var p=function(){for(var b=/audio(.min)?.js.*/,a=document.getElementsByTagName("script"),c=0,d=a.length;c<d;c++){var e=a[c].getAttribute("src");if(b.test(e))return e.replace(b,"")}}();g[h]={instanceCount:0,instances:{},flashSource:' <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="$1" width="1" height="1" name="$1" style="position: absolute; left: -1px;"> <param name="movie" value="$2?playerInstance='+h+'.instances[\'$1\']&datetime=$3"> <param name="allowscriptaccess" value="always"> <embed name="$1" src="$2?playerInstance='+ -h+'.instances[\'$1\']&datetime=$3" width="1" height="1" allowscriptaccess="always"> </object>',settings:{autoplay:false,loop:false,preload:true,imageLocation:p+"player-graphics.gif",swfLocation:p+"audiojs.swf",useFlash:function(){var b=document.createElement("audio");return!(b.canPlayType&&b.canPlayType("audio/mpeg;").replace(/no/,""))}(),hasFlash:function(){if(navigator.plugins&&navigator.plugins.length&&navigator.plugins["Shockwave Flash"])return true;else if(navigator.mimeTypes&&navigator.mimeTypes.length){var b= -navigator.mimeTypes["application/x-shockwave-flash"];return b&&b.enabledPlugin}else try{new ActiveXObject("ShockwaveFlash.ShockwaveFlash");return true}catch(a){}return false}(),createPlayer:{markup:' <div class="play-pause"> <p class="play"></p> <p class="pause"></p> <p class="loading"></p> <p class="error"></p> </div> <div class="scrubber"> <div class="progress"></div> <div class="loaded"></div> </div> <div class="time"> <em class="played">00:00</em>/<strong class="duration">00:00</strong> </div> <div class="error-message"></div>', -playPauseClass:"play-pause",scrubberClass:"scrubber",progressClass:"progress",loaderClass:"loaded",timeClass:"time",durationClass:"duration",playedClass:"played",errorMessageClass:"error-message",playingClass:"playing",loadingClass:"loading",errorClass:"error"},css:' .audiojs audio { position: absolute; left: -1px; } .audiojs { width: 460px; height: 36px; background: #404040; overflow: hidden; font-family: monospace; font-size: 12px; background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #444), color-stop(0.5, #555), color-stop(0.51, #444), color-stop(1, #444)); background-image: -moz-linear-gradient(center top, #444 0%, #555 50%, #444 51%, #444 100%); -webkit-box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.3); -moz-box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.3); -o-box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.3); box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.3); } .audiojs .play-pause { width: 25px; height: 40px; padding: 4px 6px; margin: 0px; float: left; overflow: hidden; border-right: 1px solid #000; } .audiojs p { display: none; width: 25px; height: 40px; margin: 0px; cursor: pointer; } .audiojs .play { display: block; } .audiojs .scrubber { position: relative; float: left; width: 280px; background: #5a5a5a; height: 14px; margin: 10px; border-top: 1px solid #3f3f3f; border-left: 0px; border-bottom: 0px; overflow: hidden; } .audiojs .progress { position: absolute; top: 0px; left: 0px; height: 14px; width: 0px; background: #ccc; z-index: 1; background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ccc), color-stop(0.5, #ddd), color-stop(0.51, #ccc), color-stop(1, #ccc)); background-image: -moz-linear-gradient(center top, #ccc 0%, #ddd 50%, #ccc 51%, #ccc 100%); } .audiojs .loaded { position: absolute; top: 0px; left: 0px; height: 14px; width: 0px; background: #000; background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #222), color-stop(0.5, #333), color-stop(0.51, #222), color-stop(1, #222)); background-image: -moz-linear-gradient(center top, #222 0%, #333 50%, #222 51%, #222 100%); } .audiojs .time { float: left; height: 36px; line-height: 36px; margin: 0px 0px 0px 6px; padding: 0px 6px 0px 12px; border-left: 1px solid #000; color: #ddd; text-shadow: 1px 1px 0px rgba(0, 0, 0, 0.5); } .audiojs .time em { padding: 0px 2px 0px 0px; color: #f9f9f9; font-style: normal; } .audiojs .time strong { padding: 0px 0px 0px 2px; font-weight: normal; } .audiojs .error-message { float: left; display: none; margin: 0px 10px; height: 36px; width: 400px; overflow: hidden; line-height: 36px; white-space: nowrap; color: #fff; text-overflow: ellipsis; -o-text-overflow: ellipsis; -icab-text-overflow: ellipsis; -khtml-text-overflow: ellipsis; -moz-text-overflow: ellipsis; -webkit-text-overflow: ellipsis; } .audiojs .error-message a { color: #eee; text-decoration: none; padding-bottom: 1px; border-bottom: 1px solid #999; white-space: wrap; } .audiojs .play { background: url("$1") -2px -1px no-repeat; } .audiojs .loading { background: url("$1") -2px -31px no-repeat; } .audiojs .error { background: url("$1") -2px -61px no-repeat; } .audiojs .pause { background: url("$1") -2px -91px no-repeat; } .playing .play, .playing .loading, .playing .error { display: none; } .playing .pause { display: block; } .loading .play, .loading .pause, .loading .error { display: none; } .loading .loading { display: block; } .error .time, .error .play, .error .pause, .error .scrubber, .error .loading { display: none; } .error .error { display: block; } .error .play-pause p { cursor: auto; } .error .error-message { display: block; }', -trackEnded:function(){},flashError:function(){var b=this.settings.createPlayer,a=j(b.errorMessageClass,this.wrapper),c='Missing <a href="http://get.adobe.com/flashplayer/">flash player</a> plugin.';if(this.mp3)c+=' <a href="'+this.mp3+'">Download audio file</a>.';g[h].helpers.removeClass(this.wrapper,b.loadingClass);g[h].helpers.addClass(this.wrapper,b.errorClass);a.innerHTML=c},loadError:function(){var b=this.settings.createPlayer,a=j(b.errorMessageClass,this.wrapper);g[h].helpers.removeClass(this.wrapper, -b.loadingClass);g[h].helpers.addClass(this.wrapper,b.errorClass);a.innerHTML='Error loading: "'+this.mp3+'"'},init:function(){g[h].helpers.addClass(this.wrapper,this.settings.createPlayer.loadingClass)},loadStarted:function(){var b=this.settings.createPlayer,a=j(b.durationClass,this.wrapper),c=Math.floor(this.duration/60),d=Math.floor(this.duration%60);g[h].helpers.removeClass(this.wrapper,b.loadingClass);a.innerHTML=(c<10?"0":"")+c+":"+(d<10?"0":"")+d},loadProgress:function(b){var a=this.settings.createPlayer, -c=j(a.scrubberClass,this.wrapper);j(a.loaderClass,this.wrapper).style.width=c.offsetWidth*b+"px"},playPause:function(){this.playing?this.settings.play():this.settings.pause()},play:function(){g[h].helpers.addClass(this.wrapper,this.settings.createPlayer.playingClass)},pause:function(){g[h].helpers.removeClass(this.wrapper,this.settings.createPlayer.playingClass)},updatePlayhead:function(b){var a=this.settings.createPlayer,c=j(a.scrubberClass,this.wrapper);j(a.progressClass,this.wrapper).style.width= -c.offsetWidth*b+"px";a=j(a.playedClass,this.wrapper);c=this.duration*b;b=Math.floor(c/60);c=Math.floor(c%60);a.innerHTML=(b<10?"0":"")+b+":"+(c<10?"0":"")+c}},create:function(b,a){a=a||{};return b.length?this.createAll(a,b):this.newInstance(b,a)},createAll:function(b,a){var c=a||document.getElementsByTagName("audio"),d=[];b=b||{};for(var e=0,i=c.length;e<i;e++)d.push(this.newInstance(c[e],b));return d},newInstance:function(b,a){var c=this.helpers.clone(this.settings),d="audiojs"+this.instanceCount, -e="audiojs_wrapper"+this.instanceCount;this.instanceCount++;if(b.getAttribute("autoplay")!=null)c.autoplay=true;if(b.getAttribute("loop")!=null)c.loop=true;if(b.getAttribute("preload")=="none")c.preload=false;a&&this.helpers.merge(c,a);if(c.createPlayer.markup)b=this.createPlayer(b,c.createPlayer,e);else b.parentNode.setAttribute("id",e);e=new g[o](b,c);c.css&&this.helpers.injectCss(e,c.css);if(c.useFlash&&c.hasFlash){this.injectFlash(e,d);this.attachFlashEvents(e.wrapper,e)}else c.useFlash&&!c.hasFlash&& -this.settings.flashError.apply(e);if(!c.useFlash||c.useFlash&&c.hasFlash)this.attachEvents(e.wrapper,e);return this.instances[d]=e},createPlayer:function(b,a,c){var d=document.createElement("div"),e=b.cloneNode(true);d.setAttribute("class","audiojs");d.setAttribute("className","audiojs");d.setAttribute("id",c);if(e.outerHTML&&!document.createElement("audio").canPlayType){e=this.helpers.cloneHtml5Node(b);d.innerHTML=a.markup;d.appendChild(e);b.outerHTML=d.outerHTML;d=document.getElementById(c)}else{d.appendChild(e); -d.innerHTML+=a.markup;b.parentNode.replaceChild(d,b)}return d.getElementsByTagName("audio")[0]},attachEvents:function(b,a){if(a.settings.createPlayer){var c=a.settings.createPlayer,d=j(c.playPauseClass,b),e=j(c.scrubberClass,b);g[h].events.addListener(d,"click",function(){a.playPause.apply(a)});g[h].events.addListener(e,"click",function(i){i=i.clientX;var f=this,k=0;if(f.offsetParent){do k+=f.offsetLeft;while(f=f.offsetParent)}a.skipTo((i-k)/e.offsetWidth)});if(!a.settings.useFlash){g[h].events.trackLoadProgress(a); -g[h].events.addListener(a.element,"timeupdate",function(){a.updatePlayhead.apply(a)});g[h].events.addListener(a.element,"ended",function(){a.trackEnded.apply(a)});g[h].events.addListener(a.source,"error",function(){clearInterval(a.readyTimer);clearInterval(a.loadTimer);a.settings.loadError.apply(a)})}}},attachFlashEvents:function(b,a){a.swfReady=false;a.load=function(c){a.mp3=c;a.swfReady&&a.element.load(c)};a.loadProgress=function(c,d){a.loadedPercent=c;a.duration=d;a.settings.loadStarted.apply(a); -a.settings.loadProgress.apply(a,[c])};a.skipTo=function(c){if(!(c>a.loadedPercent)){a.updatePlayhead.call(a,[c]);a.element.skipTo(c)}};a.updatePlayhead=function(c){a.settings.updatePlayhead.apply(a,[c])};a.play=function(){if(!a.settings.preload){a.settings.preload=true;a.element.init(a.mp3)}a.playing=true;a.element.pplay();a.settings.play.apply(a)};a.pause=function(){a.playing=false;a.element.ppause();a.settings.pause.apply(a)};a.setVolume=function(c){a.element.setVolume(c)};a.loadStarted=function(){a.swfReady= -true;a.settings.preload&&a.element.init(a.mp3);a.settings.autoplay&&a.play.apply(a)}},injectFlash:function(b,a){var c=this.flashSource.replace(/\$1/g,a);c=c.replace(/\$2/g,b.settings.swfLocation);c=c.replace(/\$3/g,+new Date+Math.random());var d=b.wrapper.innerHTML,e=document.createElement("div");e.innerHTML=c+d;b.wrapper.innerHTML=e.innerHTML;b.element=this.helpers.getSwf(a)},helpers:{merge:function(b,a){for(attr in a)if(b.hasOwnProperty(attr)||a.hasOwnProperty(attr))b[attr]=a[attr]},clone:function(b){if(b== -null||typeof b!=="object")return b;var a=new b.constructor,c;for(c in b)a[c]=arguments.callee(b[c]);return a},addClass:function(b,a){RegExp("(\\s|^)"+a+"(\\s|$)").test(b.className)||(b.className+=" "+a)},removeClass:function(b,a){b.className=b.className.replace(RegExp("(\\s|^)"+a+"(\\s|$)")," ")},injectCss:function(b,a){for(var c="",d=document.getElementsByTagName("style"),e=a.replace(/\$1/g,b.settings.imageLocation),i=0,f=d.length;i<f;i++){var k=d[i].getAttribute("title");if(k&&~k.indexOf("audiojs")){f= -d[i];if(f.innerHTML===e)return;c=f.innerHTML;break}}d=document.getElementsByTagName("head")[0];i=d.firstChild;f=document.createElement("style");if(d){f.setAttribute("type","text/css");f.setAttribute("title","audiojs");if(f.styleSheet)f.styleSheet.cssText=c+e;else f.appendChild(document.createTextNode(c+e));i?d.insertBefore(f,i):d.appendChild(styleElement)}},cloneHtml5Node:function(b){var a=document.createDocumentFragment(),c=a.createElement?a:document;c.createElement("audio");c=c.createElement("div"); -a.appendChild(c);c.innerHTML=b.outerHTML;return c.firstChild},getSwf:function(b){b=document[b]||window[b];return b.length>1?b[b.length-1]:b}},events:{memoryLeaking:false,listeners:[],addListener:function(b,a,c){if(b.addEventListener)b.addEventListener(a,c,false);else if(b.attachEvent){this.listeners.push(b);if(!this.memoryLeaking){window.attachEvent("onunload",function(){if(this.listeners)for(var d=0,e=this.listeners.length;d<e;d++)g[h].events.purge(this.listeners[d])});this.memoryLeaking=true}b.attachEvent("on"+ -a,function(){c.call(b,window.event)})}},trackLoadProgress:function(b){if(b.settings.preload){var a,c;b=b;var d=/(ipod|iphone|ipad)/i.test(navigator.userAgent);a=setInterval(function(){if(b.element.readyState>-1)d||b.init.apply(b);if(b.element.readyState>1){b.settings.autoplay&&b.play.apply(b);clearInterval(a);c=setInterval(function(){b.loadProgress.apply(b);b.loadedPercent>=1&&clearInterval(c)})}},10);b.readyTimer=a;b.loadTimer=c}},purge:function(b){var a=b.attributes,c;if(a)for(c=0;c<a.length;c+= -1)if(typeof b[a[c].name]==="function")b[a[c].name]=null;if(a=b.childNodes)for(c=0;c<a.length;c+=1)purge(b.childNodes[c])},ready:function(){return function(b){var a=window,c=false,d=true,e=a.document,i=e.documentElement,f=e.addEventListener?"addEventListener":"attachEvent",k=e.addEventListener?"removeEventListener":"detachEvent",n=e.addEventListener?"":"on",m=function(l){if(!(l.type=="readystatechange"&&e.readyState!="complete")){(l.type=="load"?a:e)[k](n+l.type,m,false);if(!c&&(c=true))b.call(a,l.type|| -l)}},q=function(){try{i.doScroll("left")}catch(l){setTimeout(q,50);return}m("poll")};if(e.readyState=="complete")b.call(a,"lazy");else{if(e.createEventObject&&i.doScroll){try{d=!a.frameElement}catch(r){}d&&q()}e[f](n+"DOMContentLoaded",m,false);e[f](n+"readystatechange",m,false);a[f](n+"load",m,false)}}}()}};g[o]=function(b,a){this.element=b;this.wrapper=b.parentNode;this.source=b.getElementsByTagName("source")[0]||b;this.mp3=function(c){var d=c.getElementsByTagName("source")[0];return c.getAttribute("src")|| -(d?d.getAttribute("src"):null)}(b);this.settings=a;this.loadStartedCalled=false;this.loadedPercent=0;this.duration=1;this.playing=false};g[o].prototype={updatePlayhead:function(){this.settings.updatePlayhead.apply(this,[this.element.currentTime/this.duration])},skipTo:function(b){if(!(b>this.loadedPercent)){this.element.currentTime=this.duration*b;this.updatePlayhead()}},load:function(b){this.loadStartedCalled=false;this.source.setAttribute("src",b);this.element.load();this.mp3=b;g[h].events.trackLoadProgress(this)}, -loadError:function(){this.settings.loadError.apply(this)},init:function(){this.settings.init.apply(this)},loadStarted:function(){if(!this.element.duration)return false;this.duration=this.element.duration;this.updatePlayhead();this.settings.loadStarted.apply(this)},loadProgress:function(){if(this.element.buffered!=null&&this.element.buffered.length){if(!this.loadStartedCalled)this.loadStartedCalled=this.loadStarted();this.loadedPercent=this.element.buffered.end(this.element.buffered.length-1)/this.duration; -this.settings.loadProgress.apply(this,[this.loadedPercent])}},playPause:function(){this.playing?this.pause():this.play()},play:function(){/(ipod|iphone|ipad)/i.test(navigator.userAgent)&&this.element.readyState==0&&this.init.apply(this);if(!this.settings.preload){this.settings.preload=true;this.element.setAttribute("preload","auto");g[h].events.trackLoadProgress(this)}this.playing=true;this.element.play();this.settings.play.apply(this)},pause:function(){this.playing=false;this.element.pause();this.settings.pause.apply(this)}, -setVolume:function(b){this.element.volume=b},trackEnded:function(){this.skipTo.apply(this,[0]);this.settings.loop||this.pause.apply(this);this.settings.trackEnded.apply(this)}};var j=function(b,a){var c=[];a=a||document;if(a.getElementsByClassName)c=a.getElementsByClassName(b);else{var d,e,i=a.getElementsByTagName("*"),f=RegExp("(^|\\s)"+b+"(\\s|$)");d=0;for(e=i.length;d<e;d++)f.test(i[d].className)&&c.push(i[d])}return c.length>1?c:c[0]}})("audiojs","audiojsInstance",this); +(function(g,n,f){var i;a:{var k=/audio(.min)?.js.*/,m=document.getElementsByTagName("script");i=0;for(var j=m.length;i<j;i++){var o=m[i].getAttribute("src");if(k.test(o)){i=o.replace(k,"");break a}}i=void 0}k=' <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="$1" width="1" height="1" name="$1" style="position: absolute; left: -1px;"> <param name="movie" value="$2?playerInstance='+g+'.instances[\'$1\']&datetime=$3"> <param name="allowscriptaccess" value="always"> <embed name="$1" src="$2?playerInstance='+ +g+'.instances[\'$1\']&datetime=$3" width="1" height="1" allowscriptaccess="always"> </object>';m=i+"player-graphics.gif";i+="audiojs.swf";j=document.createElement("audio");j=!(j.canPlayType&&j.canPlayType("audio/mpeg;").replace(/no/,""));f[g]={instanceCount:0,instances:{},flashSource:k,settings:{autoplay:!1,loop:!1,preload:!0,initialVolume:0.5,imageLocation:m,swfLocation:i,useFlash:j,hasFlash:function(){if(navigator.plugins&&navigator.plugins.length&&navigator.plugins["Shockwave Flash"])return!0; +if(navigator.mimeTypes&&navigator.mimeTypes.length){var a=navigator.mimeTypes["application/x-shockwave-flash"];return a&&a.enabledPlugin}try{return new ActiveXObject("ShockwaveFlash.ShockwaveFlash"),!0}catch(b){}return!1}(),createPlayer:{markup:' <div class="play-pause"> <p class="play"></p> <p class="pause"></p> <p class="loading"></p> <p class="error"></p> </div> <div class="scrubber"> <div class="progress"></div> <div class="loaded"></div> </div> <div class="time"> <em class="played">00:00</em>/<strong class="duration">00:00</strong> </div> <div class="volume"> <div class="level"></div> </div> <div class="error-message"></div>', +playPauseClass:"play-pause",scrubberClass:"scrubber",progressClass:"progress",loaderClass:"loaded",timeClass:"time",durationClass:"duration",playedClass:"played",errorMessageClass:"error-message",playingClass:"playing",loadingClass:"loading",errorClass:"error",volumeClass:"volume",levelClass:"level"},trackEnded:function(){},flashError:function(){var a=this.settings.createPlayer,b=h(a.errorMessageClass,this.wrapper),c='Missing <a href="http://get.adobe.com/flashplayer/">flash player</a> plugin.';this.mp3&& +(c+=' <a href="'+this.mp3+'">Download audio file</a>.');f[g].helpers.removeClass(this.wrapper,a.loadingClass);f[g].helpers.addClass(this.wrapper,a.errorClass);b.innerHTML=c},loadError:function(){var a=this.settings.createPlayer,b=h(a.errorMessageClass,this.wrapper);f[g].helpers.removeClass(this.wrapper,a.loadingClass);f[g].helpers.addClass(this.wrapper,a.errorClass);b.innerHTML='Error loading: "'+this.mp3+'"'},init:function(){f[g].helpers.addClass(this.wrapper,this.settings.createPlayer.loadingClass)}, +loadStarted:function(){var a=this.settings.createPlayer,b=h(a.durationClass,this.wrapper),c=Math.floor(this.duration/60),d=Math.floor(this.duration%60);f[g].helpers.removeClass(this.wrapper,a.loadingClass);b.innerHTML=(10>c?"0":"")+c+":"+(10>d?"0":"")+d},loadProgress:function(a){h(this.settings.createPlayer.loaderClass,this.wrapper).style.width=100*a+"%"},playPause:function(){this.playing?this.settings.play():this.settings.pause()},play:function(){f[g].helpers.addClass(this.wrapper,this.settings.createPlayer.playingClass)}, +pause:function(){f[g].helpers.removeClass(this.wrapper,this.settings.createPlayer.playingClass)},updatePlayhead:function(a){var b=this.settings.createPlayer;h(b.progressClass,this.wrapper).style.width=100*a+"%";var b=h(b.playedClass,this.wrapper),c=this.duration*a,a=Math.floor(c/60),c=Math.floor(c%60);b.innerHTML=(10>a?"0":"")+a+":"+(10>c?"0":"")+c},volume:function(a){var b=this.settings.createPlayer,c=h(b.volumeClass,this.wrapper);h(b.levelClass,this.wrapper).style.width=c.offsetWidth*a+"px"}},create:function(a, +b){b=b||{};return a.length?this.createAll(b,a):this.newInstance(a,b)},createAll:function(a,b){for(var c=b||document.getElementsByTagName("audio"),d=[],a=a||{},e=/audiojs_wrapper\d+/,f=0,g=c.length;f<g;f++){var l=c[f].parentNode,q=!1;l&&l.getAttribute&&(l=l.getAttribute("id"),null!=l&&e.test(l)&&(q=!0));q||d.push(this.newInstance(c[f],a))}return d},newInstance:function(a,b){var c=this.helpers.clone(this.settings),d="audiojs"+this.instanceCount,e="audiojs_wrapper"+this.instanceCount;this.instanceCount++; +null!=a.getAttribute("autoplay")&&(c.autoplay=!0);null!=a.getAttribute("loop")&&(c.loop=!0);"none"==a.getAttribute("preload")&&(c.preload=!1);b&&this.helpers.merge(c,b);c.createPlayer.markup?a=this.createPlayer(a,c.createPlayer,e):a.parentNode.setAttribute("id",e);e=new f[n](a,c);c.useFlash&&c.hasFlash?(this.injectFlash(e,d),this.attachFlashEvents(e.wrapper,e)):c.useFlash&&!c.hasFlash&&this.settings.flashError.apply(e);(!c.useFlash||c.useFlash&&c.hasFlash)&&this.attachEvents(e.wrapper,e);c.useFlash|| +e.setVolume.call(e,c.initialVolume);return this.instances[d]=e},createPlayer:function(a,b,c){var d=document.createElement("div"),e=a.cloneNode(!0);d.setAttribute("class","audiojs");d.setAttribute("className","audiojs");d.setAttribute("id",c);e.outerHTML&&!document.createElement("audio").canPlayType?(e=this.helpers.cloneHtml5Node(a),d.innerHTML=b.markup,d.appendChild(e),a.outerHTML=d.outerHTML,d=document.getElementById(c)):(d.appendChild(e),d.innerHTML+=b.markup,a.parentNode.replaceChild(d,a));return d.getElementsByTagName("audio")[0]}, +attachEvents:function(a,b){if(b.settings.createPlayer){var c=b.settings.createPlayer,d=h(c.playPauseClass,a),e=h(c.scrubberClass,a),i=h(c.volumeClass,a),p=function(b){if(b.getBoundingClientRect){var b=b.getBoundingClientRect(),a=document.body,c=document.documentElement;return Math.round(b.left+(window.pageXOffset||c.scrollLeft||a.scrollLeft)-(c.clientLeft||a.clientLeft||0))}a=0;if(b.offsetParent){do a+=b.offsetLeft;while(b=b.offsetParent)}return a};f[g].events.addListener(d,"click",function(){b.playPause.apply(b)}); +f[g].events.addListener(e,"click",function(a){a=a.clientX-p(this);b.skipTo(a/e.offsetWidth)});f[g].events.addListener(i,"click",function(a){a=a.clientX-p(this);b.setVolume(a/i.offsetWidth)});b.settings.useFlash||(f[g].events.trackLoadProgress(b),f[g].events.addListener(b.element,"timeupdate",function(){b.updatePlayhead.apply(b)}),f[g].events.addListener(b.element,"ended",function(){b.trackEnded.apply(b)}),f[g].events.addListener(b.source,"error",function(){clearInterval(b.readyTimer);clearInterval(b.loadTimer); +b.settings.loadError.apply(b)}))}},attachFlashEvents:function(a,b){b.swfReady=!1;b.load=function(a){b.mp3=a;b.swfReady&&b.element.load(a)};b.loadProgress=function(a,d){b.loadedPercent=a;b.duration=d;b.settings.loadStarted.apply(b);b.settings.loadProgress.apply(b,[a])};b.skipTo=function(a){a>b.loadedPercent||(b.updatePlayhead.call(b,[a]),b.element.skipTo(a))};b.updatePlayhead=function(a){b.settings.updatePlayhead.apply(b,[a])};b.play=function(){b.settings.preload||(b.settings.preload=!0,b.element.init(b.mp3)); +b.playing=!0;b.element.pplay();b.settings.play.apply(b)};b.pause=function(){b.playing=!1;b.element.ppause();b.settings.pause.apply(b)};b.setVolume=function(a){b.element.setVolume(a);b.settings.volume.call(b,[a])};b.loadStarted=function(){b.swfReady=!0;b.settings.preload&&b.element.init(b.mp3);b.settings.autoplay&&b.play.apply(b)}},injectFlash:function(a,b){var c=this.flashSource.replace(/\$1/g,b),c=c.replace(/\$2/g,a.settings.swfLocation),c=c.replace(/\$3/g,+new Date+Math.random()),d=a.wrapper.innerHTML, +e=document.createElement("div");e.innerHTML=c+d;a.wrapper.innerHTML=e.innerHTML;a.element=this.helpers.getSwf(b)},helpers:{merge:function(a,b){for(attr in b)if(a.hasOwnProperty(attr)||b.hasOwnProperty(attr))a[attr]=b[attr]},clone:function(a){if(null==a||"object"!==typeof a)return a;var b=new a.constructor,c;for(c in a)b[c]=arguments.callee(a[c]);return b},addClass:function(a,b){RegExp("(\\s|^)"+b+"(\\s|$)").test(a.className)||(a.className+=" "+b)},removeClass:function(a,b){a.className=a.className.replace(RegExp("(\\s|^)"+ +b+"(\\s|$)")," ")},cloneHtml5Node:function(a){var b=document.createDocumentFragment(),c=b.createElement?b:document;c.createElement("audio");c=c.createElement("div");b.appendChild(c);c.innerHTML=a.outerHTML;return c.firstChild},getSwf:function(a){a=document[a]||window[a];return 1<a.length?a[a.length-1]:a}},events:{memoryLeaking:!1,listeners:[],addListener:function(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&(this.listeners.push(a),this.memoryLeaking||(window.attachEvent("onunload", +function(){if(this.listeners)for(var a=0,b=this.listeners.length;a<b;a++)f[g].events.purge(this.listeners[a])}),this.memoryLeaking=!0),a.attachEvent("on"+b,function(){c.call(a,window.event)}))},trackLoadProgress:function(a){if(a.settings.preload){var b,c,d=/(ipod|iphone|ipad)/i.test(navigator.userAgent);b=setInterval(function(){-1<a.element.readyState&&(d||a.init.apply(a));1<a.element.readyState&&(a.settings.autoplay&&a.play.apply(a),clearInterval(b),c=setInterval(function(){a.loadProgress.apply(a); +1<=a.loadedPercent&&clearInterval(c)}))},10);a.readyTimer=b;a.loadTimer=c}},purge:function(a){var b=a.attributes,c;if(b)for(c=0;c<b.length;c+=1)"function"===typeof a[b[c].name]&&(a[b[c].name]=null);if(b=a.childNodes)for(c=0;c<b.length;c+=1)purge(a.childNodes[c])},ready:function(a){var b=window,c=!1,d=!0,e=b.document,f=e.documentElement,g=e.addEventListener?"addEventListener":"attachEvent",i=e.addEventListener?"removeEventListener":"detachEvent",h=e.addEventListener?"":"on",j=function(d){if(!("readystatechange"== +d.type&&"complete"!=e.readyState)&&(("load"==d.type?b:e)[i](h+d.type,j,!1),!c&&(c=!0)))a.call(b,d.type||d)},k=function(){try{f.doScroll("left")}catch(a){setTimeout(k,50);return}j("poll")};if("complete"==e.readyState)a.call(b,"lazy");else{if(e.createEventObject&&f.doScroll){try{d=!b.frameElement}catch(m){}d&&k()}e[g](h+"DOMContentLoaded",j,!1);e[g](h+"readystatechange",j,!1);b[g](h+"load",j,!1)}}}};f[n]=function(a,b){this.element=a;this.wrapper=a.parentNode;this.source=a.getElementsByTagName("source")[0]|| +a;var c=a.getElementsByTagName("source")[0];this.mp3=a.getAttribute("src")||(c?c.getAttribute("src"):null);this.settings=b;this.loadStartedCalled=!1;this.loadedPercent=0;this.duration=1;this.playing=!1};f[n].prototype={updatePlayhead:function(){this.settings.updatePlayhead.apply(this,[this.element.currentTime/this.duration])},skipTo:function(a){a>this.loadedPercent||(this.element.currentTime=this.duration*a,this.updatePlayhead())},load:function(a){this.loadStartedCalled=!1;this.source.setAttribute("src", +a);this.element.load();this.mp3=a;f[g].events.trackLoadProgress(this)},loadError:function(){this.settings.loadError.apply(this)},init:function(){this.settings.init.apply(this)},loadStarted:function(){if(!this.element.duration)return!1;this.duration=this.element.duration;this.updatePlayhead();this.settings.loadStarted.apply(this)},loadProgress:function(){null!=this.element.buffered&&this.element.buffered.length&&(this.loadStartedCalled||(this.loadStartedCalled=this.loadStarted()),this.loadedPercent= +this.element.buffered.end(this.element.buffered.length-1)/this.duration,this.settings.loadProgress.apply(this,[this.loadedPercent]))},playPause:function(){this.playing?this.pause():this.play()},play:function(){/(ipod|iphone|ipad)/i.test(navigator.userAgent)&&0==this.element.readyState&&this.init.apply(this);this.settings.preload||(this.settings.preload=!0,this.element.setAttribute("preload","auto"),f[g].events.trackLoadProgress(this));this.playing=!0;this.element.play();this.settings.play.apply(this)}, +pause:function(){this.playing=!1;this.element.pause();this.settings.pause.apply(this)},setVolume:function(a){this.element.volume=a;this.settings.volume.apply(this,[a])},trackEnded:function(){this.skipTo.apply(this,[0]);this.settings.loop||this.pause.apply(this);this.settings.trackEnded.apply(this)}};var h=function(a,b){var c=[],b=b||document;if(b.getElementsByClassName)c=b.getElementsByClassName(a);else{var d,e,f=b.getElementsByTagName("*"),g=RegExp("(^|\\s)"+a+"(\\s|$)");d=0;for(e=f.length;d<e;d++)g.test(f[d].className)&& +c.push(f[d])}return 1<c.length?c:c[0]}})("audiojs","audiojsInstance",this); diff --git a/public/admin/js/audiojs/audiojs/audiojs.as b/public/admin/js/audiojs/audiojs/audiojs.as new file mode 100644 index 00000000000..e118a64a3f5 --- /dev/null +++ b/public/admin/js/audiojs/audiojs/audiojs.as @@ -0,0 +1,146 @@ +package { + +import flash.display.Sprite; +import flash.external.ExternalInterface; +import flash.net.URLRequest; +import flash.media.Sound; +import flash.media.SoundChannel; +import flash.media.SoundTransform; +import flash.events.Event; +import flash.errors.IOError; +import flash.events.IOErrorEvent; +import flash.events.ProgressEvent; +import flash.events.TimerEvent; +import flash.utils.Timer; +import flash.system.Security; + +public class audiojs extends Sprite { + + private var _channel:SoundChannel; + private var sound:Sound; + private var duration:Number; + private var playerInstance:String; + + private var pausePoint:Number = 0; + private var playing:Boolean = false; + private var volume:Number = 1; + private var timer:Timer = new Timer(250, 0); + + + private function get channel():SoundChannel { + return this._channel; + } + + private function set channel(channel:SoundChannel):void { + this._channel = channel; + this._channel.addEventListener(Event.SOUND_COMPLETE, this.soundEnded); + } + + public function audiojs():void { + Security.allowDomain("*"); + + this.playerInstance = root.loaderInfo.parameters.playerInstance+'.'; + + ExternalInterface.addCallback('init', init); + ExternalInterface.addCallback('load', load); + ExternalInterface.addCallback('playPause', playPause); + ExternalInterface.addCallback('pplay', play); + ExternalInterface.addCallback('ppause', pause); + ExternalInterface.addCallback('skipTo', skipTo); + ExternalInterface.addCallback('setVolume', setVolume); + + ExternalInterface.call(this.playerInstance+'loadStarted'); + } + + private function updatePlayhead(e:TimerEvent = null):void { + var targetPosition:Number = e ? this.channel.position : this.pausePoint; + var playProgress:Number = targetPosition / this.duration; + + if (playProgress > 1) playProgress = 1; + if (playProgress > 0) { + ExternalInterface.call(this.playerInstance+'updatePlayhead', playProgress); + } + } + + private function loadProgress(e:ProgressEvent):void { + this.duration = (e.bytesTotal / (e.bytesLoaded / this.sound.length)) + var loadPercent:Number = e.bytesLoaded / e.bytesTotal; + + if (loadPercent > 1) loadPercent = 1; + if (loadPercent > 0) { + ExternalInterface.call(this.playerInstance+'loadProgress', loadPercent, (this.duration/1000)); + } + } + + private function init(mp3:String):void { + this.load(mp3); + } + + private function load(mp3:String):void { + if (this.channel) this.channel.stop(); + if (this.sound) this.sound.removeEventListener(ProgressEvent.PROGRESS, this.loadProgress); + + this.channel = new SoundChannel(); + this.sound = new Sound(new URLRequest(mp3)); + + this.pausePoint = 0; + this.sound.addEventListener(IOErrorEvent.IO_ERROR, this.loadError); + this.sound.addEventListener(ProgressEvent.PROGRESS, this.loadProgress); + + this.timer.addEventListener(TimerEvent.TIMER, this.updatePlayhead); + this.timer.start(); + } + + private function loadError(e:IOErrorEvent):void { + ExternalInterface.call(this.playerInstance+'loadError'); + } + + private function play():void { + this.channel = this.sound.play(this.pausePoint); + this.setVolume(this.volume); + this.playing = true; + this.timer.start(); + } + + private function pause():void { + this.pausePoint = this.channel.position; + this.channel.stop(); + this.playing = false; + this.timer.stop(); + } + + private function playPause():void { + if (this.playing) { + this.pause(); + } else { + this.play(); + } + } + + private function skipTo(percent:Number):void { + this.channel.stop(); + this.pausePoint = this.duration * percent; + if (this.playing) { + this.channel = this.sound.play(this.pausePoint); + this.setVolume(this.volume); + } else { + this.updatePlayhead(); + } + } + + private function setVolume(vol:Number):void { + this.volume = vol; + var transform:SoundTransform = this.channel.soundTransform; + if (vol < 0) vol = 0; + if (vol > 1) vol = 1; + transform.volume = vol; + channel.soundTransform = transform; + } + + private function soundEnded(e:Event):void { + ExternalInterface.call(this.playerInstance+'trackEnded'); + } + +} + +} \ No newline at end of file diff --git a/public/admin/js/audiojs/audiojs/audiojs.swf b/public/admin/js/audiojs/audiojs/audiojs.swf index 483599fc8273d0ccaaa935aa115a65e05ffe27ec..cc8086dcc05da3960770a4549799d6fc9dff6955 100644 GIT binary patch literal 1733 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 bf4%`z(WjdfCFjNadi7t&GcNxZ>Idt1uSZ>G literal 1644 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 diff --git a/public/admin/js/audiojs/audiojs/audiojs2.swf b/public/admin/js/audiojs/audiojs/audiojs2.swf new file mode 100644 index 0000000000000000000000000000000000000000..cc8086dcc05da3960770a4549799d6fc9dff6955 GIT binary patch literal 1733 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 bf4%`z(WjdfCFjNadi7t&GcNxZ>Idt1uSZ>G literal 0 HcmV?d00001 diff --git a/public/admin/js/audiojs/audiojs/player-graphics_blue.gif b/public/admin/js/audiojs/audiojs/player-graphics_blue.gif new file mode 100644 index 0000000000000000000000000000000000000000..612059173fe52e27969e9c5b63617c951a481cdf GIT binary patch literal 3546 zcmdVcYdD(+8wc>9Rq5o3h$YclS7$Y=s#dLP2Zv~sHLR`D>H%q^)wgDJBqNElupo&X z5E3GBmMAKvrAi%3F<MGdr_eZ6y<59o>l@nc@LumeZ}0u#`SM)X^L+SS_y7L8V9>Uo zoIeEOgPK9>qe7P3a^#2k@}qc;N1^;=Fef}sLavo3vTM^C<$Ot_q_(ZLwzjdcu}wLT z<PVfHE`PK><B!JW<KyFUxqRbG|Kp+mauawf2nDiOf4BZm(B{`WO=tmuIr!r8pl7#( zEqX$)jD?pkeYf<wk-vu}S>F2ojysKyHmg!UI8WeD<)~1M4)FF`9#FtlYQpN0B(~UE z9wa&Biu<*%%4|zPO}K*sJLf}c7{~a8#3X8R%J;O?v~)UynZaUnxS3hmybL4^fB>)% z1_Dx43=yRv^PmVM0t(N7L7-WAWvrqyB)o=RZ;Z@m)ZR3LLST$m8M>;0Sy)np&K2Yr z<cy6^Je{1Ho|%=;%|BBtEG}6ip&`$2rQQe5RmgJl0K~5f`(d{EhoZ}nDsKZ@SAKrv zYt<7?V(6ea!f^i1<2Gr2YwAu%svf3N*v>G6NW*lcbafWYGO((7&sS(S%>%fuQr*c5 z-6%V8SA;5~&`n?v-n1MTipHuss_A49bS`-ctvQ}y)Z=sSmF>?#^D-+-hpyxMi+wv; zExPVkty^05{pc}zleS3k6(UPUGs6>JR1*d&TpJT1M=)+26aSqt7^i<7kyTE2S{mS^ zSb^3T-E#KF(f0W`&AEt=+PU8H*1mk7dWLk5Pe=^Xt_~a7A${y}b+{~IORL*Rhz964 zMKEY9$PASJM$v?YS1S5BS8J<Z?+(>6GZ%cQvyfXu{ye&G&X1jIiFY(|M*BN>`>Ssi z6`o%a7MFG_%4d0-H>dfP*4Gyu4jOBGzvA)IPxVnfOFzFRQ=(&H<K8K{zESffAt2mL zh%pIC-%w+)h)OoI0vL%dMlwiTDXct7l2B9<Us-G{ghz9-s-x5BOfl_#ch7^~zWyHu z1|L2e8h&hog!(?|A{GFc++xZsfarKioaIi(wq(aHi`qIAKar<q_;a_z;B966J24t? z^V4k-!QBKc5(?%x{-qWiY3k5>zE>Tcy3Hy!<r@ztG;RAw>BGB{CWNl(X3r#{7^y!w z^?)NSz#1OV#lsP1e$izJT^KHg=Dr<OMg8LbJQUq0(OkcTDDfM}f8Q*p+*w8&ncu89 z!a3hb^Ubn}8-ibrY<7=eS^Q8JzB(@p>(n}XI`-FB)6ZNa;Je>x`D5$Z%ja8@^etJZ z(NbK;ncY7|)^p=8G&1ZG)Negq1^4fB0R4lNxD}8ZfK*gsT9(5Vn80OZ4!7Ju9GS+X z{ZVOT^vS16sEKz_^8kV_kDlkQ#I$9{u8N*7Fa1oO?W6dac5jkh{awk>HM_7m5vBTV zH0J>xMx~|L*u*OmDFJ%l8`v_UUL^JcuA1hjSf{;bab3wf)e?We^cii>G7NlWp~e(r zGff>u$6TdKC2YQHHKGMO;NS(ujb0Bc$tibSAv?bs5PDhq<GPKK2TM=Y?CQ%&dls|% zNcBbW{Aj1w(b$F#4He)JUZQ_DQY#sovUM4JFY1FVa(03h&YWdzIoM^gI@X%)6>f6q zmCIavwq>q{%KwKG1a2a%Ci}uOc`<P1Lj9N1`a(_gyj`f@ojBZ11^vY|abZcM$~&@! z%CimL(y;68HYuGBOP@jw{WM0ve$j?#vx7Fna@*&I>Wr^#S=42ewh(P+ZYB9Hq7ujB zSX)yyKc|Z^%%EUa6}Tz|o9lE%q$i^nwX8ewTnBt~9KGJd8CQiJeOOMojc74E5qOe$ z?iRDayT8<@DtJ_Mk{DeMt=l~$D(kpWan>HDT4!z)zDLj$ul1vcMYNUq9aBBE_#lUn z9j&aQbD|NBb=G}~A@PjL@Sga-&#+$q&VK3i&ka6UhFK*fp%O?aqre3yAy-VS&B|Vn zz82b_f^THhKq)oeO?VT1a{!`iiZI8WjpcB89rV@Z2*sj^(j`!<-kqKF^%L!P!M9H3 zkp#2aw7AJix?-U7!L}>GI&(0`cH8aF8KIkATIKVYs1rB$wO0aeT$H0aN_Kq;V{-sA z_=~p*zDKa%gL+I>mAA1{JfDxL`XzA^?Y^4{A9>lINqP#-(owWmoN4P8dfO}v-MI2q zp}o~Zmr>T`UeD3a8x=V|)tV~Tj^icg8lyC`uw4mO>a8T0C2NH9+`kj2cln+I_sw{F zZeX~Hh2INkKOb`zxMi^E?_4V6#)+c9-(IK~AuNFdkl=6;2STDt7^L-!RmkS@QTbdE z5s{V2BP*fq(*As+M%JOm?h}Ln21&o!-ihd(B*-&oVq3UvlojskPl`p#^laaR+C_)c zH~w&<3|)`;IcZYtzHkdD)o|W|-oEXNkmfymzeK~f+cU4#<7bWHnHHGh(n)PmOR9>) zjGi~$-96o!$a*QWmb)=_dYJIq)=v~R-!s`S@sfT?tYopb_&C%{5Po~dnong3Qfh^x z*`KOe7}mibZC<nb7Uy%_b9H{S#58*BSlq9wCPt626Q3qH8$G!m{`FXcsord$rVPL} zq<_>ZJA{gv(#f{=w^`A3#`k5~i%-B*{{|==9Dw<feBltbF%y6rD9axNU~KdVK8yrF z@{s}(yPRE8W>x`^3dE*GOg7Xww~~xtw{oJ9u+sGWzeqoR9tv4npD94xpC-<?%46=e z$E>o~$g9AT;OX=y?0_A1pG`F;{d{kuOKhZHUQ4oTN}_(SX(Bjvn?NqdPx`l~p|IS0 zD`u)whtu^IB+cV{FLbcOE)0$w-b=>hnjNp~jnEc9*y}{u)*`D6I3h-^r(bpP@yi~X zxR0wcun+CeHq3*GI#6$s|8eSC$l#27RnS03Tvpx!xbD;CrqH^77mqcN*PKwL#aa_h zvA}lEkp!tmt574CY;m#@+!3+UUz9iW+`lL2AT&pl5QlF@efb(2srzCEuK#y+3RoNh z!eSWsMj`<S6mb*|WD;RHW>5$xk|#t$01~U5MN)D}qeRfcVp2tpF`@_}BxbNWAjXt5 z9=(<JTk}(P3T1!iLVb}_l%jl8wwSB{5D)r@3f6o~dspn5WR<YA@=5@2D`(ezGx<x> zsW;8<tri^JtW^tdc4|$*h6Yznq#GU9G@WFJ>a2JKw0(c=gdZLZFX%kDH}I04E<d1$ zv1@2*UxYQDEBGw=$uSHa*Ppy`tEw;6n8iyFeXfbmc2t~MBk!kPRCr2v-6dF^>Yo{^ t4xGI0eg~01Qe(L|>{~qeR;&J!QY-qMR>5Cs$(zI^;cZRAYLXVn?mz$Lh<E@1 literal 0 HcmV?d00001 diff --git a/public/admin/js/audiojs/audiojs/style-dark.css b/public/admin/js/audiojs/audiojs/style-dark.css new file mode 100644 index 00000000000..4c54a1e46bd --- /dev/null +++ b/public/admin/js/audiojs/audiojs/style-dark.css @@ -0,0 +1,189 @@ +.audiojs audio { + position: absolute; + left: -1px; +} +.audiojs { + width: 500px; + height: 36px; + background: #404040; + overflow: hidden; + font-family: monospace; + font-size: 12px; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #444), color-stop(0.5, #555), color-stop(0.51, #444), color-stop(1, #444)); + background-image: -moz-linear-gradient(center top, #444 0%, #555 50%, #444 51%, #444 100%); + -webkit-box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.3); + -o-box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.3); + box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.3); +} +.audiojs .play-pause { + width: 25px; + height: 40px; + padding: 4px 6px; + margin: 0px; + float: left; + overflow: hidden; + border-right: 1px solid #000; +} +.audiojs p { + display: none; + width: 25px; + height: 40px; + margin: 0px; + cursor: pointer; +} +.audiojs .play { + display: block +} +.audiojs .scrubber { + position: relative; + float: left; + width: 280px; + background: #5a5a5a; + height: 14px; + margin: 10px; + border-top: 1px solid #3f3f3f; + border-left: 0px; + border-bottom: 0px; + overflow: hidden; +} +.audiojs .progress { + position: absolute; + top: 0px; + left: 0px; + height: 14px; + width: 0px; + background: #ccc; + z-index: 1; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ccc), color-stop(0.5, #ddd), color-stop(0.51, #ccc), color-stop(1, #ccc)); + background-image: -moz-linear-gradient(center top, #ccc 0%, #ddd 50%, #ccc 51%, #ccc 100%); +} +.audiojs .loaded { + position: absolute; + top: 0px; + left: 0px; + height: 14px; + width: 0px; + background: #000; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #222), color-stop(0.5, #333), color-stop(0.51, #222), color-stop(1, #222)); + background-image: -moz-linear-gradient(center top, #222 0%, #333 50%, #222 51%, #222 100%); +} +.audiojs .time { + float: left; + height: 36px; + line-height: 36px; + margin: 0px 0px 0px 6px; + padding: 0px 6px 0px 12px; + border-left: 1px solid #000; + color: #ddd; + text-shadow: 1px 1px 0px rgba(0, 0, 0, 0.5); +} +.audiojs .time em { + padding: 0px 2px 0px 0px; + color: #f9f9f9; + font-style: normal; +} +.audiojs .time strong { + padding: 0px 0px 0px 2px; + font-weight: normal; +} +.audiojs .level { + position: absolute; + top: 0; + left: 0; + height: 12px; + width: 100%; + background: url("./vol-graphics.png") -10px -27px no-repeat; +} +.audiojs .error-message { + float: left; + display: none; + margin: 0px 10px; + height: 36px; + width: 400px; + overflow: hidden; + line-height: 36px; + white-space: nowrap; + color: #fff; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + -icab-text-overflow: ellipsis; + -khtml-text-overflow: ellipsis; + -moz-text-overflow: ellipsis; + -webkit-text-overflow: ellipsis; +} +.audiojs .error-message a { + color: #eee; + text-decoration: none; + padding-bottom: 1px; + border-bottom: 1px solid #999; + white-space: wrap; +} +.audiojs .play, +.audiojs .loading, +.audiojs .error, +.audiojs .pause { + background-image: url("./player-graphics.gif"); + background-repeat: no-repeat; +} +.audiojs .play { + background-position: -2px -1px +} +.audiojs .loading { + background-position: -2px -31px +} +.audiojs .error { + background-position: -2px -61px +} +.audiojs .pause { + background-position: -2px -91px +} +.audiojs.playing .play, +.audiojs.playing .loading, +.audiojs.playing .error { + display: none +} +.audiojs.playing .pause { + display: block +} +.audiojs.loading .play, +.audiojs.loading .pause, +.audiojs.loading .error { + display: none +} +.audiojs.loading .loading { + display: block +} +.audiojs.error .time, +.audiojs.error .play, +.audiojs.error .pause, +.audiojs.error .scrubber, +.audiojs.error .loading { + display: none +} +.audiojs.error .error { + display: block +} +.audiojs.error .play-pause p { + cursor: auto +} +.audiojs.error .error-message { + display: block +} +.audiojs .volume { + position: relative; + float: left; + width: 28px; + background: url("./vol-graphics.png") -10px -7px no-repeat; + height: 12px; + overflow: hidden; + margin: 10px; +} +.audiojs.error .time, +.error .play, +.error .pause, +.error .scrubber, +.error .loading, +.error .volume { + display: none +} diff --git a/public/admin/js/audiojs/audiojs/style-light.css b/public/admin/js/audiojs/audiojs/style-light.css new file mode 100644 index 00000000000..bce466ebe0b --- /dev/null +++ b/public/admin/js/audiojs/audiojs/style-light.css @@ -0,0 +1,188 @@ +.audiojs audio { + display: none; +} +.audiojs { + width: 500px; + height: 22px; + background: none; + border: 1px solid LightGrey; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 4px; + overflow: hidden; + font-family: monospace; + font-size: 12px; + color: #8D8D8D; + -webkit-box-shadow: none; + -moz-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + padding: 1px 0px; + margin: 5px 0px; +} +.audiojs .play-pause { + width: 22px; + height: 22px; + padding: 0; + margin: 0px; + float: left; + overflow: hidden; + border-right: 1px solid #CECECE; +} +.audiojs p { + display: none; + width: 22px; + height: 22px; + margin: 0px; + cursor: pointer; +} +.audiojs .volume { + position: relative; + float: left; + width: 28px; + background: url("./player-graphics_blue.gif") -10px -143px no-repeat; + height: 12px; + overflow: hidden; + margin: 5px; +} +.audiojs .play { + display: block +} +.audiojs .scrubber { + position: relative; + float: left; + width: 320px; + background: #CECECE; + height: 12px; + margin: 5px 5px; + border-left: 0px; + border-bottom: 0px solid #F9F9F9; + border-top: 0px solid #AEAEAE; + overflow: hidden; +} +.audiojs .progress { + position: absolute; + top: 0px; + left: 0px; + height: 12px; + width: 0px; + background: #338ce4; + z-index: 1; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #509dea), color-stop(1, #1c72dd)); + background-image: -moz-linear-gradient(center top, #509dea 0%, #1c72dd 100%); +} +.audiojs .loaded { + position: absolute; + top: 0px; + left: 0px; + height: 12px; + width: 0px; + background: #BABABA; +} +.audiojs .time { + float: left; + text-align: center; + width: 91px; + height: 22px; + line-height: 22px; + margin: 0px 0px 0px 0px; + padding: 0px 5px; + border-left: 1px solid #CECECE; + border-right: 1px solid #CECECE; +} +.audiojs .time em { + padding: 0px 2px 0px 0px; + color: #526f9a; + font-style: normal; + text-shadow: none; +} +.audiojs .time strong { + padding: 0px 0px 0px 2px; + color: #8D8D8D; + font-weight: normal; + text-shadow: none; +} +.audiojs .level { + position: absolute; + top: 0; + left: 0; + height: 12px; + width: 100%; + background: url("./player-graphics_blue.gif") -10px -123px no-repeat; +} +.audiojs .error-message { + float: left; + display: none; + margin: 0px 10px; + height: 21px; + width: 375px; + overflow: hidden; + line-height: 21px; + white-space: nowrap; + color: #8D8D8D; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + -icab-text-overflow: ellipsis; + -khtml-text-overflow: ellipsis; + -moz-text-overflow: ellipsis; + -webkit-text-overflow: ellipsis; +} +.audiojs .error-message a { + color: #338ce4; + text-decoration: none; + white-space: wrap; +} +.audiojs .play { + background: url("./player-graphics_blue.gif") -3px -3px no-repeat +} +.audiojs .loading { + background: url("./player-graphics_blue.gif") -3px -33px no-repeat +} +.audiojs .error { + background: url("./player-graphics_blue.gif") -3px -63px no-repeat +} +.audiojs .pause { + background: url("./player-graphics_blue.gif") -3px -93px no-repeat +} +.audiojs .pause:hover, +.audiojs .pause:focus { + background: url("./player-graphics_blue.gif") -33px -93px no-repeat +} +.audiojs .play:hover, +.audiojs .play:focus { + background: url("./player-graphics_blue.gif") -33px -3px no-repeat +} +.audiojs.playing .play, +.playing .loading, +.playing .error { + display: none +} +.audiojs.playing .pause { + display: block +} +.audiojs.loading .play, +.loading .pause, +.loading .error { + display: none +} +.audiojs.loading .loading { + display: block +} +.audiojs.error .time, +.error .play, +.error .pause, +.error .scrubber, +.error .loading, +.error .volume { + display: none +} +.audiojs.error .error { + display: block +} +.audiojs.error .play-pause p { + cursor: auto +} +.audiojs.error .error-message { + display: block +} diff --git a/public/admin/js/audiojs/audiojs/vol-graphics.png b/public/admin/js/audiojs/audiojs/vol-graphics.png new file mode 100644 index 0000000000000000000000000000000000000000..847e7abe0bec98c22099c890c0d81105da8136a7 GIT binary patch literal 1091 zcmV-J1ibr+P)<h;3K|Lk000e1NJLTq001`t001lq1^@s6!O9>W0009XX+uL$Nkc;* zP;zf(X>4Tx0C)j~RNrgUP!#^!Wu36$i#lf!2|j3%Ze&w*L!7p2SGvtw>Nd9_NSmf@ zT$;ut?S8Na*^6&F#dq-sKKTa>*@JI;k`2ZbVfd_wB24xov!0tYO(#<Wx%a!@`R+L< z=j2|X`Egp)6fX}HRZ~yJ!u-VK6yNdzUK~R!{Af*!h89XDM?eqLvU%^b^9~-yY;^8# z->d#()tZ$I5%3%!zLYh@BH>w}X<XEF6X4c~@0~F<!p%%`Sf>ODA7?mkV}ap}jU$$3 zG&Mk)3Bm`(LOM&hKscCb;PVaG&Vdx<Cnl+qE{i;?MN%*2WJR(J_V6EbgYsXnsFdlO zt>+MpZJHTQ(R_;DA31$+jOGB<!9QOZy+OF0a9B3uqcwg)%_Oc7CcWqGbZMCFWtx{+ zDH0_dB)no&t}|?D<_iOfn(^iYzppESQTGg<TF?NF5j>oLXk_De?ey1m!ik&_4G zH9n^))_*|$z4!HUisgBd@awc5jn(v9k~&t~+vLrrBg4dZQ9lDnLV}JQWGLW~LJVP= zW5lZXOcog;N~F?hbX0k=IMzETla}oqM|jC!4!B+x^;@#I_Tc-T-6hwKycLDTx1-om z?X`jFy0R0R8-I0SrK4`)H@W4T8*Qr#2vPou<*`U!Wy(*2QP*`g=8#jD{B;Y@GL-Hm zb`n?&x~%YC_$q7)PlXr4m%r4=&fcvN%Ybn#KC7Nn&Bp8{(oE9pWVpYI^+LuN`H(R~ zTAjWmO`M83^4d@fCkA(d>*nHIFV_d2yUbnT`nd?LE^;G|!WZ>Ld?E0@Grm4ww{M7H zr`x{MWb30bTI;*hk-DO>dX$gbC-yy#suLNqvA(f>RtPJ!qGM`Gvvf}Y10`)vm-7Xa z?-7Ixe2A_siI1ydSCCID3U8SVUY86>uSnT0use_K1GZDvUFK<Db2;-WaOoTU!|N_L zRR&%ez|nIq7oanB<O#5RUM%Ys+aElhw}6p5+heUgZDG2LK31#SbS_&S0lN>Y)t}F* z)!pahe+zh{{06Bb3f97*Uorpy010qNS#tmY3ljhU3ljkVnw%H_007HLL_t(&1?`xz z4S+BZ0|{cPv<$&8)C|KAv{@^NlFCT%#2C{)ir#;AK%Z)@o$Ax83OjUJ+*j$EoXHVR zU})XbI4!4d(YDU%sh*s<rzZLKInw09GZ&dD<OFGQ7KiY&)^BI7Wv0+jrELkxF_ZZ< zx#Tqi;!j$azECWV)OD~elY=87eL<QW{6mR`Qc5}PP;$=Rp<Efdv@NB@g=a1@Q^=aq z<SY*1XRY7PT+2+Mp-S5ll4B<GYjWP9ApER#=?lf;SZ#;;+5x&vDP2!V25kTU002ov JPDHLkV1hQ{25<lX literal 0 HcmV?d00001 diff --git a/public/admin/js/audiojs/demos/test1.html b/public/admin/js/audiojs/demos/test1.html new file mode 100644 index 00000000000..24d1d5e5623 --- /dev/null +++ b/public/admin/js/audiojs/demos/test1.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Test 1 - audio.js</title> + <style> + p { clear: both; } + </style> + <script src="../audiojs/audio.js"></script> + <script> + audiojs.events.ready(function() { + var as = audiojs.createAll(); + }); + </script> + <link rel="stylesheet" type="text/css" href="../audiojs/style-light.css"> + </head> + <body> + <h1>audiojs.createAll()</h1> + <p>Load from remote URL</p> + <audio controls="controls"> + <source src="http://s3.amazonaws.com/audiojs/02-juicy-r.mp3"> + </audio> + </body> +</html> diff --git a/public/admin/js/audiojs/demos/test4.html b/public/admin/js/audiojs/demos/test4.html new file mode 100644 index 00000000000..a6e515060ee --- /dev/null +++ b/public/admin/js/audiojs/demos/test4.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Test 4 - audio.js</title> + <style> + p { clear: both; } + </style> + <script src="../audiojs/audio.js"></script> + <script> + audiojs.events.ready(function() { + var as = audiojs.createAll(); + as[1].load({ + mp3: "http://s3.amazonaws.com/audiojs/02-juicy-r.mp3", + ogg: "http://s3.amazonaws.com/audiojs/02-juicy-r.ogg" + }); + }); + </script> + </head> + <body> + <h1>audiojs.create(element, settings)</h1> + <p>.ogg fallback</p> + <audio src="http://s3.amazonaws.com/audiojs/02-juicy-r.mp3" preload> + <source src="http://s3.amazonaws.com/audiojs/02-juicy-r.ogg"> + </audio> + <p>Dynamically-loaded audio file with .ogg fallback</p> + <audio preload="none"></audio> + </body> +</html> \ No newline at end of file diff --git a/public/admin/js/audiojs/demos/test6.html b/public/admin/js/audiojs/demos/test6.html new file mode 100644 index 00000000000..c45956a96f4 --- /dev/null +++ b/public/admin/js/audiojs/demos/test6.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Test 6 - audio.js</title> + <style> + p { clear: both; } + </style> + <script src="../audiojs/audio.js"></script> + <script> + audiojs.events.ready(function() { + var as = audiojs.createAll(), + audio = as[0], + ids = ['vol-0', 'vol-10', 'vol-40', 'vol-70', 'vol-100']; + for (var i = 0, ii = ids.length; i < ii; i++) { + var elem = document.getElementById(ids[i]), + volume = ids[i].split('-')[1]; + elem.setAttribute('data-volume', volume / 100) + elem.onclick = function(e) { + audio.setVolume(this.getAttribute('data-volume')); + e.preventDefault(); + return false; + } + } + + }); + </script> + </head> + <body> + <h1>audiojs.create(element, settings)</h1> + <p>Volume</p> + <audio src="http://s3.amazonaws.com/audiojs/02-juicy-r.mp3"></audio> + <p><a href="#" id="vol-0">Volume: 0.0</a></p> + <p><a href="#" id="vol-10">Volume: 0.1</a></p> + <p><a href="#" id="vol-40">Volume: 0.4</a></p> + <p><a href="#" id="vol-70">Volume: 0.7</a></p> + <p><a href="#" id="vol-100">Volume: 1.0</a></p> + </body> +</html> \ No newline at end of file diff --git a/public/admin/js/audiojs/includes/divider.png b/public/admin/js/audiojs/includes/divider.png new file mode 100644 index 0000000000000000000000000000000000000000..a342afdfddf44c497d45592fe7ad6aa0154cbf0b GIT binary patch literal 379 zcmeAS@N?(olHy`uVBq!ia0y~yU<?MbnK_t&q-2f^D~Kv_jVKAuPb(=;EJ|f?Ovz75 zRq)JBOiv9;O-!jQJeg_(RAe0B6XJT~#@V}fE<JyC_tC@aAKpK|c;V=q*N;Abdj0L| z+jnoDzI^fE>eW-XZ(Vru_}1l1$M4_2`s4eDBL(vp0JRI21o;L3M*|G1YiA|_B@cSK zIEGZ*S~EG4@2~=o3+EC61MheBx1_8^130#XDqFs1?)-S8+2W<}rvv-%CY`t=d|5=x zxke?a<H+Jgsa1=ZA4Og?Y+PY`S*(cp-*YxIp=tlc(+*y-&TBcW>Tx*biS^g&hqhwA zcfx(7-XHn&*vVO_<#bz{s)H5(-Vdv{tyt!(k(HpaX89otPg~)6R>wC>U*9$}^X8Pd z=AyGYc+9r-n}xZ$8ne2)l>`>bh;n>QHjH;k`{)sNNZu-(`(Xj^XUzi)i3$eguL_HE QfSzISboFyt=akR{0QbVNY5)KL literal 0 HcmV?d00001 diff --git a/public/admin/js/audiojs/includes/index.css b/public/admin/js/audiojs/includes/index.css index bb076576afc..259fb8f7f9f 100644 --- a/public/admin/js/audiojs/includes/index.css +++ b/public/admin/js/audiojs/includes/index.css @@ -1,4 +1,4 @@ -@font-face { font-family: 'bpreplay'; font-weight: normal; font-style: normal; src: url('BPreplay-webfont.eot'); src: local('☺'), url('BPreplay-webfont.woff') format('woff'), url('BPreplay-webfont.ttf') format('truetype'), url('BPreplay-webfont.svg#webfontgzJ8Cr4g') format('svg'); } +@font-face { font-family: 'bpreplay'; font-weight: normal; font-style: normal; } body { width: 480px; margin: 40px auto; font-family: sans-serif; background: #f6f6f0; color: #330; line-height: 1.5; } header { display: block; background: url('./divider.png') bottom center no-repeat; padding: 10px 0px; margin: 0px 0px 20px; text-align: center; } @@ -11,7 +11,7 @@ h2 { font-family: 'bpreplay', sans-serif; font-weight: normal; font-size: 24px; .download { background: url('./divider.png') top center no-repeat, url('./divider.png') bottom center no-repeat; margin: 30px 0px; padding: 20px 0px; text-align: center; } .download a em { color: rgba(255, 255, 255, 0.8); font-style: normal; } .download a em:before { content: '⬇ '; font-size: 0.8em; padding: 0px 4px 0px 0px; } -.download a { display: block; color: #f6f6f0; width: 190px; margin: 5px auto; padding: 8px 2px 8px 0px; font-size: 14px; border-bottom: 0px; background: #da1c5c; +.download a { display: block; color: #f6f6f0; width: 190px; margin: 5px auto; padding: 8px 2px 8px 0px; font-size: 14px; border-bottom: 0px; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; -o-border-radius: 5px; background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.2, #da1c5c), color-stop(0.5, #C81C5C), color-stop(0.51, #da1c5c), color-stop(1, #da1c5c)); background-image: -moz-linear-gradient(center top, #da1c5c 0%, #C81C5C 50%, #da1c5c 51%, #da1c5c 100%); } @@ -21,24 +21,16 @@ h3 { margin: 30px 0px 8px; } p { font-size: 13px; margin: 0px 0px 5px; padding: 0px 0px 1px; } em { font-style: normal; color: #b1aca0; padding-right: 3px; } a { color: #330; text-decoration: none; border-bottom: 1px solid; } -blockquote { font-size: 13px; font-style: italic; border-left: 2px solid #b1aca0; padding: 0px 0px 2px 10px; margin: 0px 0px 10px; } -cite:before { content: "From:\00a0"; } -cite { border-top: 1px dotted #999; padding-top: 0.5em; display: block; word-wrap: break-word; } -ol { padding: 0px; font-size: 12px; color: #b1aca0; } -ol li { margin: 0px 0px 20px; } +ol { padding: 0px; font-size: 11px; color: #C5C1B3; } ol li p { color: #330; } -ul { font-size: 13px; margin: 6px 0px; padding: 0px; list-style: none; } -ul li { position: relative; } -ul li:before { content: '\2022'; position: absolute; left: -1.8ex; } - pre, code { background: #EFEEE6; color: #552; font-family: Monaco, Consolas, 'Lucida Console', monospace; font-size: 12px; padding: 0px 3px; } -pre { margin: 0px; padding: 4px 8px; } +pre { padding: 4px 8px; } -footer { display: block; margin: 30px 0px 0px; color: #b1aca0; text-align: center; margin: 50px 0px 0px; } -footer a { color: #b1aca0; } +footer { display: block; margin: 30px 0px 0px; color: #C1BDB0; text-align: center; } +footer a { color: #C1BDB0; border-bottom: 1px solid; margin: 0px 3px; } footer em { display: block; font-size: 1.2em; font-style: normal; } -footer .ab-c { font-family: 'Andale Mono', 'Courier New', courier; font-size: 0.75em; margin: 30px 0px 0px; padding: 20px 0px; border-top: 1px solid #EFEEE6; } -footer .ab-c a { padding: 0px; } \ No newline at end of file +footer .ab-c { font-family: 'Andale Mono', 'Courier New', courier; font-size: 0.75em; margin: 50px 0px 0px; padding: 20px 0px; border-top: 1px solid #EFEEE6; } +footer .ab-c a { padding: 0px; } diff --git a/public/admin/js/audiojs/index.html b/public/admin/js/audiojs/index.html index fdad851f794..2b7b9dc184e 100644 --- a/public/admin/js/audiojs/index.html +++ b/public/admin/js/audiojs/index.html @@ -3,8 +3,8 @@ <head> <meta charset="utf-8"> <title>audio.js</title> - <script>var _gaq=[['_setAccount','UA-20257902-1'],['_trackPageview']];(function(d,t){ var g=d.createElement(t),s=d.getElementsByTagName(t)[0]; g.async=1;g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'))</script> - <script src="./audiojs/audio.min.js"></script> + <link rel="stylesheet" href="./audiojs/style-light.css" media="screen"> + <script src="./audiojs/audio.js"></script> <link rel="stylesheet" href="./includes/index.css" media="screen"> <script> audiojs.events.ready(function() { @@ -19,22 +19,14 @@ <audio src="http://s3.amazonaws.com/audiojs/02-juicy-r.mp3" preload="auto"></audio> - <h2>audio.js is a drop-in javascript library that allows HTML5’s <audio> tag to be used anywhere.</h2> - - <p>It uses native <audio> where available and an invisible flash player to emulate <audio> for other browsers. It provides a consistent html player UI to all browsers which can be styled used standard css.</audio> - - <div class="download"> - <a href="http://kolber.github.com/audiojs/audiojs.zip" class="button"><em>Download</em> audio.js</a> - </div> - <h3>Installation</h3> <ol> <li> <p>Put <code>audio.js</code>, <code>player-graphics.gif</code> & <code>audiojs.swf</code> in the same folder.</p> </li> <li> - <p>Include the <code>audio.js</code> file:</p> - <pre><code><script src="/audiojs/audio.min.js"></script></code></pre> + <p>Include audio.js:</p> + <pre><code><script src="/audiojs/audio.js"></script></code></pre> </li> <li> <p>Initialise audio.js:</p> @@ -52,10 +44,22 @@ <h3>Examples</h3> <p>A series of API tests & examples for using and extending audio.js</p> - <p><em>Example 1</em> <a href="http://kolber.github.com/audiojs/demos/test1.html">Test multiple load types</a></p> - <p><em>Example 2</em> <a href="http://kolber.github.com/audiojs/demos/test2.html">Custom markup/css</a></p> - <p><em>Example 3</em> <a href="http://kolber.github.com/audiojs/demos/test3.html">Multiple players, testing <code>preload</code>, <code>loop</code> & <code>autoplay</code> attributes</a></p> - <p><em>Example 4</em> <a href="http://kolber.github.com/audiojs/demos/test5.html">Customised player</a></p> + <p><em>Example 1</em> <a href="http://dotzero.github.com/audiojs/demos/test1.html">Test multiple load types</a></p> + <p><em>Example 2</em> <a href="http://dotzero.github.com/audiojs/demos/test2.html">Custom markup/css</a></p> + <p><em>Example 3</em> <a href="http://dotzero.github.com/audiojs/demos/test3.html">Multiple players, testing <code>preload</code>, <code>loop</code> & <code>autoplay</code> attributes</a></p> + <p><em>Example 4</em> <a href="http://dotzero.github.com/audiojs/demos/test5.html">Customised player</a></p> + <p><em>Example 5</em> <a href="http://dotzero.github.com/audiojs/demos/test6.html">Customised playlist player</a></p> + + <h3>Source code</h3> + <p>All efforts have been made to keep the source as clean and readable as possible. Until we release more detailed documentation, the annotated source is the best reference for usage.</p> + <p><a href="http://dotzero.github.com/audiojs/docs/">Annotated source</a> / <a href="http://github.com/dotzero/audiojs">Source on Github</a></p> + + <footer> + <p class="ab-c"><em>ℜ</em> Another <a href='http://ab-c.com.au'>ab+c</a> joint</p> + </footer> + </body> +</html> +://kolber.github.com/audiojs/demos/test5.html">Customised player</a></p> <p><em>Example 5</em> <a href="http://kolber.github.com/audiojs/demos/test6.html">Customised playlist player</a></p> <!--<p><em>Example 6</em> <a href="http://kolber.github.com/audiojs/demos/test4.html">.ogg fallback</a></p>--> diff --git a/tests/library/ZendAfi/View/Helper/AudioJSPlayerTest.php b/tests/library/ZendAfi/View/Helper/AudioJSPlayerTest.php index 14f46a31c65..dd045bf0b61 100644 --- a/tests/library/ZendAfi/View/Helper/AudioJSPlayerTest.php +++ b/tests/library/ZendAfi/View/Helper/AudioJSPlayerTest.php @@ -19,17 +19,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -class ZendAfi_View_Helper_AudioJsPlayerTest extends PHPUnit_Framework_TestCase { +class ZendAfi_View_Helper_AudioJsPlayerTest extends ViewHelperTestCase { /** * @var ZendAfi_View_Helper_AudioJsPlayer */ private $_helper; + private $_html; - protected function setUp() { + public function setUp() { Class_ScriptLoader::resetInstance(); $this->_helper = new ZendAfi_View_Helper_AudioJsPlayer(); $this->_helper->setView(new Zend_View()); - $this->_helper->audioJsPlayer(); + $this->_html = $this->_helper->audioJsPlayer('http://alter-l/si-veriash.mp3'); } /** @test */ @@ -43,6 +44,12 @@ class ZendAfi_View_Helper_AudioJsPlayerTest extends PHPUnit_Framework_TestCase { public function audioJSShouldBeCreated() { $this->assertContains('audiojs.createAll', Class_ScriptLoader::getInstance()->html()); } + + + /** @test */ + public function audioTagShouldContainsSrc() { + $this->assertXPath($this->_html, '//audio/source[@src="http://alter-l/si-veriash.mp3"]', $this->_html); + } } ?> \ No newline at end of file -- GitLab