PageSourceSearch

https://sura-susso-w7hq.onrender.com/assets/js/mp3-player-button.js

js sura-susso-w7hq.onrender.com collected 2026-10-03 11:43:34 UTC 8,940 bytes, 288 lines download raw bytes

1/**
2 * SoundManager 2 Demo: Play MP3 links via button
3 * ----------------------------------------------
4 *
5 * http://schillmania.com/projects/soundmanager2/
6 *
7 * A simple demo making MP3s playable "inline"
8 * and easily styled/customizable via CSS.
9 *
10 * A variation of the "play mp3 links" demo.
11 *
12 * Requires SoundManager 2 Javascript API.
13 */
14
15(function() {
16
17  /* global document, window, soundManager, navigator */
18
19  'use strict';
20
21  function BasicMP3Player() {
22    var self = this,
23      pl = this,
24      sm = soundManager, // soundManager instance
25      isTouchDevice = (navigator.userAgent.match(/ipad|iphone/i)),
26      isIE = (navigator.userAgent.match(/msie/i));
27    this.excludeClass = 'button-exclude'; // CSS class for ignoring MP3 links
28    this.links = [];
29    this.sounds = [];
30    this.soundsByURL = {};
31    this.indexByURL = {};
32    this.lastSound = null;
33    this.soundCount = 0;
34
35    this.config = {
36      // configuration options
37      playNext: false, // stop after one sound, or play through list until end
38      autoPlay: false // start playing the first sound right away
39    };
40
41    this.css = {
42      // CSS class names appended to link during various states
43      sDefault: 'sm2_button', // default state
44      sLoading: 'sm2_loading',
45      sPlaying: 'sm2_playing',
46      sPaused: 'sm2_paused'
47    };
48
49    // event + DOM utils
50
51    this.includeClass = this.css.sDefault;
52
53    this.addEventHandler = (typeof window.addEventListener !== 'undefined' ? function(o, evtName, evtHandler) {
54      return o.addEventListener(evtName, evtHandler, false);
55    } : function(o, evtName, evtHandler) {
56      o.attachEvent('on' + evtName, evtHandler);
57    });
58
59    this.removeEventHandler = (typeof window.removeEventListener !== 'undefined' ? function(o, evtName, evtHandler) {
60      return o.removeEventListener(evtName, evtHandler, false);
61    } : function(o, evtName, evtHandler) {
62      return o.detachEvent('on' + evtName, evtHandler);
63    });
64
65    this.classContains = function(o, cStr) {
66      return (typeof o.className !== 'undefined' ? o.className.match(new RegExp('(\\s|^)' + cStr + '(\\s|$)')) : false);
67    };
68
69    this.addClass = function(o, cStr) {
70      if (!o || !cStr || self.classContains(o, cStr)) {
71        return;
72      }
73      o.className = (o.className ? o.className + ' ' : '') + cStr;
74    };
75
76    this.removeClass = function(o, cStr) {
77      if (!o || !cStr || !self.classContains(o, cStr)) {
78        return;
79      }
80      o.className = o.className.replace(new RegExp('( ' + cStr + ')|(' + cStr + ')', 'g'), '');
81    };
82
83    this.getSoundByURL = function(sURL) {
84      return (typeof self.soundsByURL[sURL] !== 'undefined' ? self.soundsByURL[sURL] : null);
85    };
86
87    this.isChildOfNode = function(o, sNodeName) {
88      if (!o || !o.parentNode) {
89        return null;
90      }
91      sNodeName = sNodeName.toLowerCase();
92      do {
93        o = o.parentNode;
94      } while (o && o.parentNode && o.nodeName.toLowerCase() !== sNodeName);
95      return (o.nodeName.toLowerCase() === sNodeName ? o : null);
96    };
97
98    this.events = {
99
100      // handlers for sound events as they're started/stopped/played
101
102      play: function() {
103        pl.removeClass(this._data.oLink, this._data.className);
104        this._data.className = pl.css.sPlaying;
105        pl.addClass(this._data.oLink, this._data.className);
106      },
107
108      stop: function() {
109        pl.removeClass(this._data.oLink, this._data.className);
110        this._data.className = '';
111      },
112
113      pause: function() {
114        pl.removeClass(this._data.oLink, this._data.className);
115        this._data.className = pl.css.sPaused;
116        pl.addClass(this._data.oLink, this._data.className);
117      },
118
119      resume: function() {
120        pl.removeClass(this._data.oLink, this._data.className);
121        this._data.className = pl.css.sPlaying;
122        pl.addClass(this._data.oLink, this._data.className);
123      },
124
125      finish: function() {
126        if ($('.record-key').hasClass('active')) {
127          $('.record-key').removeClass('active');
128        }
129
130        if ($('.player-main').hasClass('active')) {
131          $('.player-main').removeClass('active');
132        }
133
134        if ($('.bubble-wrap').hasClass('active')) {
135          $('.bubble-wrap').removeClass('active');
136        }
137
138        if ($('.bubble-wrap-right').hasClass('active')) {
139          $('.bubble-wrap-right').removeClass('active');
140        }
141
142        pl.removeClass(this._data.oLink, this._data.className);
143        this._data.className = '';
144        if (pl.config.playNext) {
145          var nextLink = (pl.indexByURL[this._data.oLink.href] + 1);
146          if (nextLink < pl.links.length) {
147            pl.handleClick({
148              target: pl.links[nextLink]
149            });
150          }
151        }
152      }
153
154    };
155
156    this.stopEvent = function(e) {
157      if (typeof e !== 'undefined' && typeof e.preventDefault !== 'undefined') {
158        e.preventDefault();
159      } else if (typeof window.event !== 'undefined') {
160        window.event.returnValue = false;
161      }
162      return false;
163    };
164
165    this.getTheDamnLink = (isIE) ? function(e) {
166      // I really didn't want to have to do this.
167      return (e && e.target ? e.target : window.event.srcElement);
168    } : function(e) {
169      return e.target;
170    };
171
172    this.handleClick = function(e) {
173      // a sound link was clicked
174      if (typeof e.button !== 'undefined' && e.button > 1) {
175        // ignore right-click
176        return true;
177      }
178      var o = self.getTheDamnLink(e),
179        soundURL,
180        thisSound;
181      if (o.nodeName.toLowerCase() !== 'a') {
182        o = self.isChildOfNode(o, 'a');
183        if (!o) {
184          return true;
185        }
186      }
187      if (!o.href || !soundManager.canPlayLink(o) || self.classContains(o, self.excludeClass)) {
188        return true; // pass-thru for non-MP3/non-links
189      }
190      if (!self.classContains(o, self.includeClass)) {
191        return true;
192      }
193      sm._writeDebug('handleClick()');
194      soundURL = (o.href);
195      thisSound = self.getSoundByURL(soundURL);
196      if (thisSound) {
197        // already exists
198        if (thisSound === self.lastSound) {
199          // and was playing (or paused)
200          thisSound.togglePause();
201        } else {
202          // different sound
203          thisSound.togglePause(); // start playing current
204          sm._writeDebug('sound different than last sound: ' + self.lastSound.id);
205          if (self.lastSound) {
206            self.stopSound(self.lastSound);
207          }
208        }
209      } else {
210        // create sound
211        thisSound = sm.createSound({
212          id: 'basicMP3Sound' + (self.soundCount++),
213          url: soundURL,
214          onplay: self.events.play,
215          onstop: self.events.stop,
216          onpause: self.events.pause,
217          onresume: self.events.resume,
218          onfinish: self.events.finish,
219          type: (o.type || null)
220        });
221        // tack on some custom data
222        thisSound._data = {
223          oLink: o, // DOM node for reference within SM2 object event handlers
224          className: self.css.sPlaying
225        };
226        self.soundsByURL[soundURL] = thisSound;
227        self.sounds.push(thisSound);
228        if (self.lastSound) {
229          // stop last sound
230          self.stopSound(self.lastSound);
231        }
232        thisSound.play();
233      }
234      self.lastSound = thisSound; // reference for next call
235      return self.stopEvent(e);
236    };
237
238    this.stopSound = function(oSound) {
239      soundManager.stop(oSound.id);
240      if (!isTouchDevice) { // iOS 4.2+ security blocks onfinish() -> playNext() if we set a .src in-between(?)
241        soundManager.unload(oSound.id);
242      }
243    };
244
245    this.init = function() {
246      sm._writeDebug('basicMP3Player.init()');
247      var i, j,
248        foundItems = 0,
249        oLinks = document.getElementsByTagName('a');
250      // grab all links, look for .mp3
251      for (i = 0, j = oLinks.length; i < j; i++) {
252        if (self.classContains(oLinks[i], self.css.sDefault) && !self.classContains(oLinks[i], self.excludeClass)) {
253          // self.addClass(oLinks[i],self.css.sDefault); // add default CSS decoration - good if you're lazy and want ALL MP3/playable links to do this
254          self.links[foundItems] = (oLinks[i]);
255          self.indexByURL[oLinks[i].href] = foundItems; // hack for indexing
256          foundItems++;
257        }
258      }
259      if (foundItems > 0) {
260        self.addEventHandler(document, 'click', self.handleClick);
261        if (self.config.autoPlay) {
262          self.handleClick({
263            target: self.links[0],
264            preventDefault: function() {}
265          });
266        }
267      }
268      sm._writeDebug('basicMP3Player.init(): Found ' + foundItems + ' relevant items.');
269    };
270
271    this.init();
272
273  }
274
275  var basicMP3Player = null;
276
277  window.basicMP3Player = basicMP3Player;
278
279  soundManager.setup({
280    preferFlash: false,
281    onready: function() {
282      basicMP3Player = new BasicMP3Player();
283    }
284
285
286  });
287
288}());

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.