1/** 2 * 3 * SoundManager 2 Demo: Play MP3 links "in-place" 4 * ---------------------------------------------- 5 * 6 * http://schillmania.com/projects/soundmanager2/ 7 * 8 * A simple demo making MP3s playable "inline" 9 * and easily styled/customizable via CSS. 10 * 11 * Requires SoundManager 2 Javascript API. 12 * 13 */ 14 15function InlinePlayer() { 16 var self = this; 17 var pl = this; 18 var sm = soundManager; // soundManager instance 19 var isIE = (navigator.userAgent.match(/msie/i)); 20 this.playableClass = 'inline-playable'; // CSS class for forcing a link to be playable (eg. doesn't have .MP3 in it) 21 this.excludeClass = 'inline-exclude'; // CSS class for ignoring MP3 links 22 this.links = []; 23 this.sounds = []; 24 this.soundsByURL = []; 25 this.indexByURL = []; 26 this.lastSound = null; 27 this.soundCount = 0; 28 29 this.config = { 30 playNext: false, // stop after one sound, or play through list until end 31 autoPlay: false // start playing the first sound right away 32 } 33 34 this.css = { 35 // CSS class names appended to link during various states
36 sDefault: 'sm2_link', // default state 37 sLoading: 'sm2_loading', 38 sPlaying: 'sm2_playing', 39 sPaused: 'sm2_paused' 40 } 41 42 this.addEventHandler = (typeof window.addEventListener !== 'undefined' ? function(o, evtName, evtHandler) { 43 return o.addEventListener(evtName,evtHandler,false); 44 } : function(o, evtName, evtHandler) { 45 o.attachEvent('on'+evtName,evtHandler); 46 }); 47 48 this.removeEventHandler = (typeof window.removeEventListener !== 'undefined' ? function(o, evtName, evtHandler) { 49 return o.removeEventListener(evtName,evtHandler,false); 50 } : function(o, evtName, evtHandler) { 51 return o.detachEvent('on'+evtName,evtHandler); 52 }); 53 54 this.classContains = function(o,cStr) { 55 return (typeof(o.className)!='undefined'?o.className.match(new RegExp('(\\s|^)'+cStr+'(\\s|$)')):false); 56 } 57 58 this.addClass = function(o,cStr) { 59 if (!o || !cStr || self.classContains(o,cStr)) return false; 60 o.className = (o.className?o.className+' ':'')+cStr; 61 } 62 63 this.removeClass = function(o,cStr) { 64 if (!o || !cStr || !self.classContains(o,cStr)) return false; 65 o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),''); 66 } 67 68 this.getSoundByURL = function(sURL) { 69 return (typeof self.soundsByURL[sURL] != 'undefined'?self.soundsByURL[sURL]:null); 70 } 71 72 this.isChildOfNode = function(o,sNodeName) { 73 if (!o || !o.parentNode) { 74 return false; 75 } 76 sNodeName = sNodeName.toLowerCase(); 77 do { 78 o = o.parentNode; 79 } while (o && o.parentNode && o.nodeName.toLowerCase() != sNodeName); 80 return (o.nodeName.toLowerCase() == sNodeName?o:null); 81 } 82 83 this.events = { 84 85 // handlers for sound events as they're started/stopped/played 86 87 play: function() { 88 pl.removeClass(this._data.oLink,this._data.className); 89 this._data.className = pl.css.sPlaying; 90 pl.addClass(this._data.oLink,this._data.className); 91 }, 92 93 stop: function() { 94 pl.removeClass(this._data.oLink,this._data.className); 95 this._data.className = ''; 96 }, 97 98 pause: function() { 99 pl.removeClass(this._data.oLink,this._data.className); 100 this._data.className = pl.css.sPaused; 101 pl.addClass(this._data.oLink,this._data.className); 102 }, 103 104 resume: function() { 105 pl.removeClass(this._data.oLink,this._data.className); 106 this._data.className = pl.css.sPlaying; 107 pl.addClass(this._data.oLink,this._data.className); 108 }, 109 110 finish: function() { 111 pl.removeClass(this._data.oLink,this._data.className); 112 this._data.className = ''; 113 if (pl.config.playNext) { 114 var nextLink = (pl.indexByURL[this._data.oLink.href]+1); 115 if (nextLink<pl.links.length) { 116 pl.handleClick({'target':pl.links[nextLink]}); 117 } 118 } 119 } 120 121 } 122 123 this.stopEvent = function(e) { 124 if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') { 125 e.preventDefault(); 126 } else if (typeof event != 'undefined' && typeof event.returnValue != 'undefined') { 127 event.returnValue = false; 128 } 129 return false; 130 } 131 132 this.getTheDamnLink = (isIE)?function(e) { 133 // I really didn't want to have to do this. 134 return (e && e.target?e.target:window.event.srcElement); 135 }:function(e) { 136 return e.target; 137 } 138 139 this.handleClick = function(e) { 140 // a sound link was clicked 141 if (typeof e.button != 'undefined' && e.button>1) { 142 // ignore right-click 143 return true; 144 } 145 var o = self.getTheDamnLink(e); 146 if (o.nodeName.toLowerCase() != 'a') { 147 o = self.isChildOfNode(o,'a'); 148 if (!o) return true; 149 } 150 var sURL = o.getAttribute('href'); 151 if (!o.href || (!sm.canPlayLink(o) && !self.classContains(o,self.playableClass)) || self.classContains(o,self.excludeClass)) { 152 return true; // pass-thru for non-MP3/non-links 153 } 154 var soundURL = (o.href); 155 var thisSound = self.getSoundByURL(soundURL); 156 if (thisSound) { 157 // already exists 158 if (thisSound == self.lastSound) { 159 // and was playing (or paused) 160 thisSound.togglePause(); 161 } else { 162 // different sound 163 sm._writeDebug('sound different than last sound: '+self.lastSound.id); 164 if (self.lastSound) { 165 self.stopSound(self.lastSound); 166 } 167 thisSound.togglePause(); // start playing current 168 } 169 } else { 170 // stop last sound 171 if (self.lastSound) { 172 self.stopSound(self.lastSound); 173 } 174 // create sound 175 thisSound = sm.createSound({ 176 id:'inlineMP3Sound'+(self.soundCount++), 177 url:soundURL, 178 onplay:self.events.play, 179 onstop:self.events.stop, 180 onpause:self.events.pause, 181 onresume:self.events.resume, 182 onfinish:self.events.finish 183 }); 184 // tack on some custom data 185 thisSound._data = { 186 oLink: o, // DOM node for reference within SM2 object event handlers 187 className: self.css.sPlaying 188 }; 189 self.soundsByURL[soundURL] = thisSound; 190 self.sounds.push(thisSound); 191 thisSound.play(); 192 } 193 194 self.lastSound = thisSound; // reference for next call 195 196 if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') { 197 e.preventDefault(); 198 } else { 199 event.returnValue = false;
200 } 201 return false; 202 } 203 204 this.stopSound = function(oSound) { 205 soundManager.stop(oSound.id); 206 soundManager.unload(oSound.id); 207 } 208 209 this.init = function() { 210 sm._writeDebug('inlinePlayer.init()'); 211 var oLinks = document.getElementsByTagName('a'); 212 // grab all links, look for .mp3 213 var foundItems = 0; 214 for (var i=0, j=oLinks.length; i<j; i++) { 215 if ((sm.canPlayLink(oLinks[i]) || self.classContains(oLinks[i],self.playableClass)) && !self.classContains(oLinks[i],self.excludeClass)) { 216 self.addClass(oLinks[i],self.css.sDefault); // add default CSS decoration 217 self.links[foundItems] = (oLinks[i]); 218 self.indexByURL[oLinks[i].href] = foundItems; // hack for indexing 219 foundItems++; 220 } 221 } 222 if (foundItems>0) { 223 self.addEventHandler(document,'click',self.handleClick); 224 if (self.config.autoPlay) { 225 self.handleClick({target:self.links[0],preventDefault:function(){}}); 226 } 227 } 228 sm._writeDebug('inlinePlayer.init(): Found '+foundItems+' relevant items.'); 229 } 230 231 this.init(); 232 233} 234 235var inlinePlayer = null; 236 237soundManager.setup({ 238 // disable or enable debug output 239 debugMode: true, 240 // use HTML5 audio for MP3/MP4, if available 241 preferFlash: false, 242 useFlashBlock: true, 243 // path to directory containing SM2 SWF 244 url: 'view/99_noms_allah/content/swf/', 245 // optional: enable MPEG-4/AAC support (requires flash 9) 246 flashVersion: 9 247}); 248 249// ---- 250 251soundManager.onready(function() { 252 // soundManager.createSound() etc. may now be called 253 inlinePlayer = new InlinePlayer(); 254}); 255
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.