Best JavaScript code snippet using wpt
audio5.js
Source:audio5.js
1/*!2 * Audio5js: HTML5 Audio Compatibility Layer3 * https://github.com/zohararad/audio5js4 * License MIT (c) Zohar Arad 20135 */6(function ($win, ns, factory) {7 "use strict";8 /*global define */9 /*global swfobject */10 if (typeof (module) !== 'undefined' && module.exports) { // CommonJS11 module.exports = factory(ns, $win);12 } else if (typeof (define) === 'function' && define.amd) { // AMD13 define(function () {14 return factory(ns, $win);15 });16 } else { // <script>17 $win[ns] = factory(ns, $win);18 }19}(window, 'Audio5js', function (ns, $win) {20 "use strict";21 var ActiveXObject = $win.ActiveXObject;22 /**23 * AudioError Class24 * @param {String} message error message25 * @constructor26 */27 function AudioError(message) {28 this.message = message;29 }30 AudioError.prototype = new Error();31 /**32 * Clones an object33 * @param obj object to clone34 * @return {Object} cloned object35 */36 function cloneObject(obj) {37 var clone = {}, i;38 for (i in obj) {39 if (typeof (obj[i]) === "object") {40 clone[i] = cloneObject(obj[i]);41 } else {42 clone[i] = obj[i];43 }44 }45 return clone;46 }47 /**48 * Extend an object with a mixin49 * @param {Object} target target object to extend50 * @param {Object} mixin object to mix into target51 * @return {*} extended object52 */53 var extend = function (target, mixin) {54 var name, m = cloneObject(mixin);55 for (name in m) {56 if (m.hasOwnProperty(name)) {57 target[name] = m[name];58 }59 }60 return target;61 };62 /**63 * Extend an object's prototype with a mixin64 * @param {Object} target target object to extend65 * @param {Object} mixin object to mix into target66 * @return {*} extended object67 */68 var include = function (target, mixin) {69 return extend(target.prototype, mixin);70 };71 var Pubsub = {72 /**73 * Subscribe to event on a channel74 * @param {String} evt name of channel / event to subscribe75 * @param {Function} fn the callback to execute on message publishing76 * @param {Object} ctx the context in which the callback should be executed77 */78 on: function (evt, fn, ctx) {79 this.subscribe(evt, fn, ctx, false);80 },81 /**82 * Subscribe to a one-time event on a channel83 * @param {String} evt name of channel / event to subscribe84 * @param {Function} fn the callback to execute on message publishing85 * @param {Object} ctx the context in which the callback should be executed86 */87 one: function(evt, fn, ctx) {88 this.subscribe(evt, fn, ctx, true);89 },90 /**91 * Unsubscribe from an event on a channel92 * @param {String} evt name of channel / event to unsubscribe93 * @param {Function} fn the callback used when subscribing to the event94 */95 off: function (evt, fn) {96 if (this.channels[evt] === undefined) { return; }97 var i, l;98 for (i = 0, l = this.channels[evt].length; i < l; i++) {99 var sub = this.channels[evt][i].fn;100 if (sub === fn) {101 this.channels[evt].splice(i, 1);102 break;103 }104 }105 },106 /**107 * Add event subscription to channel. Called by `on` and `one`108 * @param {String} evt name of channel / event to subscribe109 * @param {Function} fn the callback to execute on message publishing110 * @param {Object} ctx the context in which the callback should be executed111 * @param {Boolean} once indicate if event should be triggered once or not112 */113 subscribe: function (evt, fn, ctx, once) {114 if (this.channels === undefined) {115 this.channels = {};116 }117 this.channels[evt] = this.channels[evt] || [];118 this.channels[evt].push({fn: fn, ctx: ctx, once: (once || false)});119 },120 /**121 * Publish a message on a channel. Accepts **args** after event name122 * @param {String} evt name of channel / event to trigger123 */124 trigger: function (evt) {125 if (this.channels && this.channels.hasOwnProperty(evt)) {126 var args = Array.prototype.slice.call(arguments, 1);127 var a = [];128 while(this.channels[evt].length > 0) {129 var sub = this.channels[evt].shift();130 if (typeof (sub.fn) === 'function') {131 sub.fn.apply(sub.ctx, args);132 }133 if ( !sub.once ){134 a.push(sub);135 }136 }137 this.channels[evt] = a;138 }139 }140 };141 var util = {142 /**143 * Flash embed code string with cross-browser support.144 */145 flash_embed_code: function (id, swf_location, ts) {146 var prefix;147 var s = '<param name="movie" value="' + swf_location + '?playerInstance=window.' + ns + '_flash.instances[\'' + id + '\']&datetime=' + ts + '/>' +148 '<param name="wmode" value="transparent"/>' +149 '<param name="allowscriptaccess" value="always" />' +150 '</object>';151 if (ActiveXObject) {152 prefix = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="1" height="1" id="' + id + '">';153 } else {154 prefix = '<object type="application/x-shockwave-flash" data="' + swf_location + '?playerInstance=window.' + ns + '_flash.instances[\'' + id + '\']&datetime=' + ts + '" width="1" height="1" id="' + id + '" >';155 }156 return prefix + s;157 },158 /**159 * Check if browser supports audio mime type.160 * @param {String} mime_type audio mime type to check161 * @return {Boolean} whether browser supports passed audio mime type162 */163 can_play: function (mime_type) {164 var a = document.createElement('audio');165 var mime_str;166 switch (mime_type) {167 case 'mp3':168 mime_str = 'audio/mpeg; codecs="mp3"';169 break;170 case 'vorbis':171 mime_str = 'audio/ogg; codecs="vorbis"';172 break;173 case 'opus':174 mime_str = 'audio/ogg; codecs="opus"';175 break;176 case 'webm':177 mime_str = 'audio/webm; codecs="vorbis"';178 break;179 case 'mp4':180 mime_str = 'audio/mp4; codecs="mp4a.40.5"';181 break;182 case 'wav':183 mime_str = 'audio/wav; codecs="1"';184 break;185 }186 if (mime_str === undefined) {187 throw new Error('Unspecified Audio Mime Type');188 } else {189 return !!a.canPlayType && a.canPlayType(mime_str) !== '';190 }191 },192 /**193 * Boolean flag indicating whether the browser has Flash installed or not194 */195 has_flash: (function () {196 var r = false;197 if (navigator.plugins && navigator.plugins.length && navigator.plugins['Shockwave Flash']) {198 r = true;199 } else if (navigator.mimeTypes && navigator.mimeTypes.length) {200 var mimeType = navigator.mimeTypes['application/x-shockwave-flash'];201 r = mimeType && mimeType.enabledPlugin;202 } else {203 try {204 var ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');205 r = typeof (ax) === 'object';206 } catch (e) {}207 }208 return r;209 }()),210 /**211 * Embed Flash MP3 player SWF to DOM212 * @param {String} swf_location location of MP3 player SWF213 * @param {String} id swf unique ID used for resolving callbacks from ExternalInterface to Javascript214 */215 embedFlash: function (swf_location, id) {216 var d = document.createElement('div');217 d.style.position = 'absolute';218 d.style.width = '1px';219 d.style.height = '1px';220 d.style.top = '1px';221 document.body.appendChild(d);222 if(typeof($win.swfobject) === 'object'){223 var fv = {224 playerInstance: 'window.'+ ns + '_flash.instances[\''+id+'\']'225 };226 var params = {227 allowscriptaccess: 'always',228 wmode: 'transparent'229 };230 d.innerHTML = '<div id="'+id+'"></div>';231 swfobject.embedSWF(swf_location + '?ts='+(new Date().getTime() + Math.random()), id, "1", "1", "9.0.0", null, fv, params);232 } else {233 var ts = new Date().getTime() + Math.random(); // Ensure swf is not pulled from cache234 d.innerHTML = this.flash_embed_code(id, swf_location, ts);235 }236 return document.getElementById(id);237 },238 /**239 * Formats seconds into a time string hh:mm:ss.240 * @param {Number} seconds seconds to format as string241 * @return {String} formatted time string242 */243 formatTime: function (seconds) {244 var hours = parseInt(seconds / 3600, 10) % 24;245 var minutes = parseInt(seconds / 60, 10) % 60;246 var secs = parseInt(seconds % 60, 10);247 var result, fragment = (minutes < 10 ? "0" + minutes : minutes) + ":" + (secs < 10 ? "0" + secs : secs);248 if (hours > 0) {249 result = (hours < 10 ? "0" + hours : hours) + ":" + fragment;250 } else {251 result = fragment;252 }253 return result;254 }255 };256 util.use_flash = util.can_play('mp3');257 var Audio5js, FlashAudioPlayer, HTML5AudioPlayer;258 /**259 * Common audio attributes object. Mixed into audio players.260 * @type {Object}261 */262 var AudioAttributes = {263 playing: false, /** {Boolean} player playback state */264 vol: 1, /** {Float} audio volume */265 duration: 0, /** {Float} audio duration (sec) */266 position: 0, /** {Float} audio position (sec) */267 load_percent: 0, /** {Float} audio file load percent (%) */268 seekable: false, /** {Boolean} is loaded audio seekable */269 ready: null /** {Boolean} is loaded audio seekable */270 };271 /**272 * Global object holding flash-based player instances.273 * Used to create a bridge between Flash's ExternalInterface calls and FlashAudioPlayer instances274 * @type {Object}275 */276 var globalAudio5Flash = $win[ns + '_flash'] = $win[ns + '_flash'] || {277 instances: { }, /** FlashAudioPlayer instance hash */278 count: 0 /** FlashAudioPlayer instance count */279 };280 /**281 * Flash MP3 Audio Player Class282 * @constructor283 */284 FlashAudioPlayer = function () {285 if (util.use_flash && !util.has_flash) {286 throw new Error('Flash Plugin Missing');287 }288 };289 FlashAudioPlayer.prototype = {290 /**291 * Initialize the player292 * @param {String} swf_src path to audio player SWF file293 */294 init: function (swf_src) {295 globalAudio5Flash.count += 1;296 this.id = ns + globalAudio5Flash.count;297 globalAudio5Flash.instances[this.id] = this;298 this.embed(swf_src);299 },300 /**301 * Embed audio player SWF in page and assign reference to audio instance variable302 * @param {String} swf_src path to audio player SWF file303 */304 embed: function (swf_src) {305 util.embedFlash(swf_src, this.id);306 },307 /**308 * ExternalInterface callback indicating SWF is ready309 */310 eiReady: function () {311 this.audio = document.getElementById(this.id);312 this.trigger('ready');313 },314 /**315 * ExternalInterface audio load started callback. Fires when audio starts loading.316 */317 eiLoadStart: function(){318 this.trigger('loadstart');319 },320 /**321 * ExternalInterface audio metadata loaded callback. Fires when audio ID3 tags have been loaded.322 */323 eiLoadedMetadata: function(){324 this.trigger('loadedmetadata');325 },326 /**327 * ExternalInterface audio can play callback. Fires when audio can be played.328 */329 eiCanPlay: function () {330 this.trigger('canplay');331 },332 /**333 * ExternalInterface timeupdate callback. Fires as long as playhead position is updated (audio is being played).334 * @param {Float} position audio playback position (sec)335 * @param {Float} duration audio total duration (sec)336 * @param {Boolean} seekable is audio seekable or not (download or streaming)337 */338 eiTimeUpdate: function (position, duration, seekable) {339 this.position = position;340 this.duration = duration;341 this.seekable = seekable;342 this.trigger('timeupdate', position, (this.seekable ? duration : null));343 },344 /**345 * ExternalInterface download progress callback. Fires as long as audio file is downloaded by browser.346 * @param {Float} percent audio download percent347 */348 eiProgress: function (percent) {349 this.load_percent = percent;350 this.trigger('progress', percent);351 },352 /**353 * ExternalInterface audio load error callback.354 * @param {String} msg error message355 */356 eiLoadError: function (msg) {357 this.trigger('error', msg);358 },359 /**360 * ExternalInterface audio play callback. Fires when audio starts playing.361 */362 eiPlay: function () {363 this.playing = true;364 this.trigger('play');365 },366 /**367 * ExternalInterface audio pause callback. Fires when audio is paused.368 */369 eiPause: function () {370 this.playing = false;371 this.trigger('pause');372 },373 /**374 * ExternalInterface audio ended callback. Fires when audio playback ended.375 */376 eiEnded: function () {377 this.pause();378 this.trigger('ended');379 },380 /**381 * ExternalInterface audio seeking callback. Fires when audio is being seeked.382 */383 eiSeeking: function(){384 this.trigger('seeking');385 },386 /**387 * ExternalInterface audio seeked callback. Fires when audio has been seeked.388 */389 eiSeeked: function(){390 this.trigger('seeked');391 },392 /**393 * Resets audio position and parameters. Invoked once audio is loaded.394 */395 reset: function () {396 this.seekable = false;397 this.duration = 0;398 this.position = 0;399 this.load_percent = 0;400 },401 /**402 * Load audio from url.403 * @param {String} url URL of audio to load404 */405 load: function (url) {406 this.reset();407 this.audio.load(url);408 },409 /**410 * Play audio411 */412 play: function () {413 this.audio.pplay();414 },415 /**416 * Pause audio417 */418 pause: function () {419 this.audio.ppause();420 },421 /**422 * Get / Set audio volume423 * @param {Float} v audio volume to set between 0 - 1.424 * @return {Float} current audio volume425 */426 volume: function (v) {427 if (v !== undefined && !isNaN(parseInt(v, 10))) {428 this.audio.setVolume(v);429 this.vol = v;430 } else {431 return this.vol;432 }433 },434 /**435 * Seek audio to position436 * @param {Float} position audio position in seconds to seek to.437 */438 seek: function (position) {439 try {440 this.audio.seekTo(position);441 this.position = position;442 } catch (e) {}443 }444 };445 include(FlashAudioPlayer, Pubsub);446 include(FlashAudioPlayer, AudioAttributes);447 /**448 * HTML5 Audio Player449 * @constructor450 */451 HTML5AudioPlayer = function () {};452 HTML5AudioPlayer.prototype = {453 /**454 * Initialize the player instance455 */456 init: function () {457 this.trigger('ready');458 },459 /**460 * Create new audio instance461 */462 createAudio: function(){463 this.audio = new Audio();464 this.audio.autoplay = false;465 this.audio.preload = 'auto';466 this.audio.autobuffer = true;467 this.bindEvents();468 },469 /**470 * Destroy current audio instance471 */472 destroyAudio: function(){473 if(this.audio){474 this.unbindEvents();475 delete this.audio;476 }477 },478 /**479 * Bind DOM events to Audio object480 */481 bindEvents: function () {482 this.audio.addEventListener('loadstart', this.onLoadStart.bind(this), false);483 this.audio.addEventListener('canplay', this.onLoad.bind(this), false);484 this.audio.addEventListener('loadedmetadata', this.onLoadedMetadata.bind(this), false);485 this.audio.addEventListener('play', this.onPlay.bind(this), false);486 this.audio.addEventListener('pause', this.onPause.bind(this), false);487 this.audio.addEventListener('ended', this.onEnded.bind(this), false);488 this.audio.addEventListener('error', this.onError.bind(this), false);489 this.audio.addEventListener('timeupdate', this.onTimeUpdate.bind(this), false);490 this.audio.addEventListener('seeking', this.onSeeking.bind(this), false);491 this.audio.addEventListener('seeked', this.onSeeked.bind(this), false);492 },493 /**494 * Unbind DOM events from Audio object495 */496 unbindEvents: function(){497 this.audio.removeEventListener('loadstart', this.onLoadStart.bind(this));498 this.audio.removeEventListener('canplay', this.onLoad.bind(this));499 this.audio.removeEventListener('loadedmetadata', this.onLoadedMetadata.bind(this));500 this.audio.removeEventListener('play', this.onPlay.bind(this));501 this.audio.removeEventListener('pause', this.onPause.bind(this));502 this.audio.removeEventListener('ended', this.onEnded.bind(this));503 this.audio.removeEventListener('error', this.onError.bind(this));504 this.audio.removeEventListener('timeupdate', this.onTimeUpdate.bind(this));505 this.audio.removeEventListener('seeking', this.onSeeking.bind(this));506 this.audio.removeEventListener('seeked', this.onSeeked.bind(this));507 },508 /**509 * Audio load start event handler. Triggered when audio starts loading510 */511 onLoadStart: function(){512 this.trigger('loadstart');513 },514 /**515 * Audio canplay event handler. Triggered when audio is loaded and can be played.516 * Resets player parameters and starts audio download progress timer.517 */518 onLoad: function () {519 if(!this.audio){520 return setTimeout(this.onLoad.bind(this), 100);521 }522 this.seekable = this.audio.seekable && this.audio.seekable.length > 0;523 if (this.seekable) {524 this.timer = setInterval(this.onProgress.bind(this), 250);525 }526 this.trigger('canplay');527 },528 /**529 * Audio ID3 load event handler. Triggered when ID3 metadata is loaded.530 */531 onLoadedMetadata: function(){532 this.trigger('loadedmetadata');533 },534 /**535 * Audio play event handler. Triggered when audio starts playing.536 */537 onPlay: function () {538 this.playing = true;539 this.trigger('play');540 },541 /**542 * Audio pause event handler. Triggered when audio is paused.543 */544 onPause: function () {545 this.playing = false;546 this.trigger('pause');547 },548 /**549 * Audio ended event handler. Triggered when audio playback has ended.550 */551 onEnded: function () {552 this.playing = false;553 this.trigger('ended');554 },555 /**556 * Audio timeupdate event handler. Triggered as long as playhead position is updated (audio is being played).557 */558 onTimeUpdate: function () {559 if (this.audio && this.audio.buffered !== null && this.audio.buffered.length && this.playing) {560 this.position = this.audio.currentTime;561 this.duration = this.audio.duration === Infinity ? null : this.audio.duration;562 this.trigger('timeupdate', this.position, this.duration);563 }564 },565 /**566 * Audio download progress timer callback. Check audio's download percentage.567 * Called periodically as soon as the audio loads and can be played.568 * Cancelled when audio has fully download or when a new audio file has been loaded to the player.569 */570 onProgress: function () {571 if (this.audio && this.audio.buffered !== null && this.audio.buffered.length) {572 this.load_percent = parseInt(((this.audio.buffered.end(this.audio.buffered.length - 1) / this.audio.duration) * 100), 10);573 this.trigger('progress', this.load_percent);574 if (this.load_percent >= 100) {575 this.clearLoadProgress();576 }577 }578 },579 /**580 * Audio error event handler581 * @param e error event582 */583 onError: function (e) {584 this.trigger('error', e);585 },586 /**587 * Audio seeking event handler. Triggered when audio seek starts.588 */589 onSeeking: function(){590 this.trigger('seeking');591 },592 /**593 * Audio seeked event handler. Triggered when audio has been seeked.594 */595 onSeeked: function(){596 this.trigger('seeked');597 },598 /**599 * Clears periodical audio download progress callback.600 */601 clearLoadProgress: function () {602 if (this.timer !== undefined) {603 clearInterval(this.timer);604 delete this.timer;605 }606 },607 /**608 * Resets audio position and parameters.609 */610 reset: function () {611 this.clearLoadProgress();612 this.seekable = false;613 this.duration = 0;614 this.position = 0;615 this.load_percent = 0;616 },617 /**618 * Load audio from url.619 * @param {String} url URL of audio to load620 */621 load: function (url) {622 this.reset();623 this.destroyAudio();624 this.createAudio();625 this.audio.setAttribute('src', url);626 this.audio.load();627 },628 /**629 * Play audio630 */631 play: function () {632 this.audio.play();633 },634 /**635 * Pause audio636 */637 pause: function () {638 this.audio.pause();639 },640 /**641 * Get / Set audio volume642 * @param {Float} v audio volume to set between 0 - 1.643 * @return {Float} current audio volume644 */645 volume: function (v) {646 if (v !== undefined && !isNaN(parseInt(v, 10))) {647 var vol = v < 0 ? 0 : Math.min(1, v);648 this.audio.volume = vol;649 this.vol = vol;650 } else {651 return this.vol;652 }653 },654 /**655 * Seek audio to position656 * @param {Float} position audio position in seconds to seek to.657 */658 seek: function (position) {659 var playing = this.playing;660 this.position = position;661 this.audio.currentTime = position;662 if (playing) {663 this.play();664 } else {665 if (this.audio.buffered !== null && this.audio.buffered.length) {666 this.trigger('timeupdate', this.position, this.duration);667 }668 }669 }670 };671 include(HTML5AudioPlayer, Pubsub);672 include(HTML5AudioPlayer, AudioAttributes);673 /**674 * Default settings object675 * @type {Object}676 */677 var settings = {678 /**679 * {String} path to Flash audio player SWF file680 */681 swf_path: '/swf/audiojs.swf',682 /**683 * {Boolean} flag indicating whether to throw errors to the page or trigger an error event684 */685 throw_errors: true,686 /**687 * {Boolean} flag indicating whether to format player duration and position to hh:mm:ss or pass as raw seconds688 */689 format_time: true,690 /**691 * {Array} list of codecs to try and use when initializing the player. Used to selectively initialize the internal audio player based on codec support692 */693 codecs: ['mp3']694 };695 /**696 * Audio5js Audio Player697 * @param {Object} s player settings object698 * @constructor699 */700 Audio5js = function (s) {701 s = s || {};702 var k;703 for (k in settings) {704 if (settings.hasOwnProperty(k) && !s.hasOwnProperty(k)) {705 s[k] = settings[k];706 }707 }708 this.init(s);709 };710 /**711 * Check if browser can play a given audio mime type.712 * @param {String} mime_type audio mime type to check.713 * @return {Boolean} is audio mime type supported by browser or not714 */715 Audio5js.can_play = function (mime_type) {716 return util.can_play(mime_type);717 };718 Audio5js.prototype = {719 /**720 * Initialize player instance.721 * @param {Object} s player settings object722 */723 init: function (s) {724 this.ready = false;725 this.settings = s;726 this.audio = this.getPlayer();727 this.bindAudioEvents();728 if (this.settings.use_flash) {729 this.audio.init(s.swf_path);730 } else {731 this.audio.init();732 }733 },734 /**735 * Gets a new audio player instance based on codec support as defined in settings.codecs array.736 * Defaults to MP3 player either HTML or Flash based.737 * @return {FlashAudioPlayer,HTML5AudioPlayer} audio player instance738 */739 getPlayer: function () {740 var i, l, player;741 for (i = 0, l = this.settings.codecs.length; i < l; i++) {742 var codec = this.settings.codecs[i];743 if (Audio5js.can_play(codec)) {744 player = new HTML5AudioPlayer();745 this.settings.use_flash = false;746 this.settings.player = {747 engine: 'html',748 codec: codec749 };750 break;751 }752 }753 if (player === undefined) {754 // here we double check for mp3 support instead of defaulting to Flash in case user overrode the settings.codecs array with an empty array.755 this.settings.use_flash = !Audio5js.can_play('mp3');756 player = this.settings.use_flash ? new FlashAudioPlayer() : new HTML5AudioPlayer();757 this.settings.player = {758 engine: (this.settings.use_flash ? 'flash' : 'html'),759 codec: 'mp3'760 };761 }762 return player;763 },764 /**765 * Bind events from audio object to internal callbacks766 */767 bindAudioEvents: function () {768 this.audio.on('ready', this.onReady, this);769 this.audio.on('loadstart', this.onLoadStart, this);770 this.audio.on('loadedmetadata', this.onLoadedMetadata, this);771 this.audio.on('play', this.onPlay, this);772 this.audio.on('pause', this.onPause, this);773 this.audio.on('ended', this.onEnded, this);774 this.audio.on('canplay', this.onCanPlay, this);775 this.audio.on('timeupdate', this.onTimeUpdate, this);776 this.audio.on('progress', this.onProgress, this);777 this.audio.on('error', this.onError, this);778 this.audio.on('seeking', this.onSeeking, this);779 this.audio.on('seeked', this.onSeeked, this);780 },781 /**782 * Load audio from URL783 * @param {String} url URL of audio to load784 */785 load: function (url) {786 var that = this,787 f = function(u){788 that.audio.load(u);789 that.trigger('load');790 };791 if(this.ready){792 f(url);793 } else {794 this.on('ready', f);795 }796 },797 /**798 * Play audio799 */800 play: function () {801 if(!this.playing){802 this.audio.play();803 }804 },805 /**806 * Pause audio807 */808 pause: function () {809 if(this.playing){810 this.audio.pause();811 }812 },813 /**814 * Toggle audio play / pause815 */816 playPause: function () {817 this[this.playing ? 'pause' : 'play']();818 },819 /**820 * Get / Set audio volume821 * @param {Float} v audio volume to set between 0 - 1.822 * @return {Float} current audio volume823 */824 volume: function (v) {825 if (v !== undefined && !isNaN(parseInt(v, 10))) {826 this.audio.volume(v);827 this.vol = v;828 } else {829 return this.vol;830 }831 },832 /**833 * Seek audio to position834 * @param {Float} position audio position in seconds to seek to.835 */836 seek: function (position) {837 this.audio.seek(position);838 this.position = position;839 },840 /**841 * Callback for audio ready event. Indicates audio is ready for playback.842 * Looks for ready callback in settings object and invokes it in the context of player instance843 */844 onReady: function () {845 this.ready = true;846 if (typeof (this.settings.ready) === 'function') {847 this.settings.ready.call(this, this.settings.player);848 }849 this.trigger('ready');850 },851 /**852 * Audio load start event handler853 */854 onLoadStart: function(){855 this.trigger('loadstart');856 },857 /**858 * Audio metadata loaded event handler859 */860 onLoadedMetadata: function(){861 this.trigger('loadedmetadata');862 },863 /**864 * Audio play event handler865 */866 onPlay: function () {867 this.playing = true;868 this.trigger('play');869 },870 /**871 * Audio pause event handler872 */873 onPause: function () {874 this.playing = false;875 this.trigger('pause');876 },877 /**878 * Playback end event handler879 */880 onEnded: function () {881 this.playing = false;882 this.trigger('ended');883 },884 /**885 * Audio error event handler886 */887 onError: function () {888 var error = new AudioError('Audio Error. Failed to Load Audio');889 if (this.settings.throw_errors) {890 throw error;891 } else {892 this.trigger('error', error);893 }894 },895 /**896 * Audio canplay event handler. Triggered when enough audio has been loaded to by played.897 */898 onCanPlay: function () {899 this.trigger('canplay');900 },901 /**902 * Audio seeking event handler903 */904 onSeeking: function(){905 this.trigger('seeking');906 },907 /**908 * Audio seeked event handler909 */910 onSeeked: function(){911 this.trigger('seeked');912 },913 /**914 * Playback time update event handler915 * @param {Float} position play head position (sec)916 * @param {Float} duration audio duration (sec)917 */918 onTimeUpdate: function (position, duration) {919 this.position = this.settings.format_time ? util.formatTime(position) : position;920 if (this.duration !== duration) {921 this.duration = this.settings.format_time && duration !== null ? util.formatTime(duration) : duration;922 }923 this.trigger('timeupdate', this.position, this.duration);924 },925 /**926 * Audio download progress event handler927 * @param {Float} loaded audio download percent928 */929 onProgress: function (loaded) {930 this.load_percent = loaded;931 this.trigger('progress', loaded);932 }933 };934 include(Audio5js, Pubsub);935 include(Audio5js, AudioAttributes);936 return Audio5js;...
CCAudio.js
Source:CCAudio.js
1/****************************************************************************2 Copyright (c) 2008-2010 Ricardo Quesada3 Copyright (c) 2011-2012 cocos2d-x.org4 Copyright (c) 2013-2014 Chukong Technologies Inc.5 http://www.cocos2d-x.org6 Permission is hereby granted, free of charge, to any person obtaining a copy7 of this software and associated documentation files (the "Software"), to deal8 in the Software without restriction, including without limitation the rights9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell10 copies of the Software, and to permit persons to whom the Software is11 furnished to do so, subject to the following conditions:12 The above copyright notice and this permission notice shall be included in13 all copies or substantial portions of the Software.14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN20 THE SOFTWARE.21 ****************************************************************************/22/**23 * Audio support in the browser24 *25 * MULTI_CHANNEL : Multiple audio while playing - If it doesn't, you can only play background music26 * WEB_AUDIO : Support for WebAudio - Support W3C WebAudio standards, all of the audio can be played27 * AUTOPLAY : Supports auto-play audio - if Donât support it, On a touch detecting background music canvas, and then replay28 * REPLAY_AFTER_TOUCH : The first music will fail, must be replay after touchstart29 * USE_EMPTIED_EVENT : Whether to use the emptied event to replace load callback30 * DELAY_CREATE_CTX : delay created the context object - only webAudio31 * NEED_MANUAL_LOOP : loop attribute failure, need to perform loop manually32 *33 * May be modifications for a few browser version34 */35(function(){36 var DEBUG = false;37 var sys = cc.sys;38 var version = sys.browserVersion;39 // check if browser supports Web Audio40 // check Web Audio's context41 var supportWebAudio = !!(window.AudioContext || window.webkitAudioContext || window.mozAudioContext);42 var support = {ONLY_ONE: false, WEB_AUDIO: supportWebAudio, DELAY_CREATE_CTX: false, ONE_SOURCE: false };43 if (sys.browserType === sys.BROWSER_TYPE_FIREFOX) {44 support.DELAY_CREATE_CTX = true;45 support.USE_LOADER_EVENT = 'canplay';46 }47 if (sys.os === sys.OS_ANDROID) {48 if (sys.browserType === sys.BROWSER_TYPE_UC) {49 support.ONE_SOURCE = true;50 }51 }52 window.__audioSupport = support;53 if(DEBUG){54 setTimeout(function(){55 cc.log("browse type: " + sys.browserType);56 cc.log("browse version: " + version);57 cc.log("MULTI_CHANNEL: " + window.__audioSupport.MULTI_CHANNEL);58 cc.log("WEB_AUDIO: " + window.__audioSupport.WEB_AUDIO);59 cc.log("AUTOPLAY: " + window.__audioSupport.AUTOPLAY);60 }, 0);61 }62})();63/**64 * Encapsulate DOM and webAudio65 */66cc.Audio = cc.Class.extend({67 src: null,68 _element: null,69 _AUDIO_TYPE: "AUDIO",70 ctor: function(url){71 this.src = url;72 },73 setBuffer: function (buffer) {74 this._AUDIO_TYPE = "WEBAUDIO";75 this._element = new cc.Audio.WebAudio(buffer);76 },77 setElement: function (element) {78 this._AUDIO_TYPE = "AUDIO";79 this._element = element;80 // Prevent partial browser from playing after the end does not reset the paused tag81 // Will cause the player to judge the status of the error82 element.addEventListener('ended', function () {83 if (!element.loop) {84 element.paused = true;85 }86 });87 },88 play: function (offset, loop) {89 if (!this._element) return;90 this._element.loop = loop;91 this._element.play();92 if (this._AUDIO_TYPE === 'AUDIO' && this._element.paused) {93 this.stop();94 cc.Audio.touchPlayList.push({ loop: loop, offset: offset, audio: this._element });95 }96 if (cc.Audio.bindTouch === false) {97 cc.Audio.bindTouch = true;98 // Listen to the touchstart body event and play the audio when necessary.99 cc.game.canvas.addEventListener('touchstart', cc.Audio.touchStart);100 }101 },102 getPlaying: function () {103 if (!this._element) return true;104 return !this._element.paused;105 },106 stop: function () {107 if (!this._element) return;108 this._element.pause();109 try{110 this._element.currentTime = 0;111 } catch (err) {}112 },113 pause: function () {114 if (!this._element) return;115 this._element.pause();116 },117 resume: function () {118 if (!this._element) return;119 this._element.play();120 },121 setVolume: function (volume) {122 if (!this._element) return;123 this._element.volume = volume;124 },125 getVolume: function () {126 if (!this._element) return;127 return this._element.volume;128 },129 cloneNode: function () {130 var audio = new cc.Audio(this.src);131 if (this._AUDIO_TYPE === "AUDIO") {132 var elem = document.createElement("audio");133 var sources = elem.getElementsByTagName('source');134 for (var i=0; i<sources.length; i++) {135 elem.appendChild(sources[i]);136 }137 elem.src = this.src;138 audio.setElement(elem);139 } else {140 audio.setBuffer(this._element.buffer);141 }142 return audio;143 }144});145cc.Audio.touchPlayList = [146 //{ offset: 0, audio: audio }147];148cc.Audio.bindTouch = false;149cc.Audio.touchStart = function () {150 var list = cc.Audio.touchPlayList;151 var item = null;152 while (item = list.pop()) {153 item.audio.loop = !!item.loop;154 item.audio.play(item.offset);155 }156};157cc.Audio.WebAudio = function (buffer) {158 this.buffer = buffer;159 this.context = cc.Audio._context;160 var volume = this.context['createGain']();161 volume['gain'].value = 1;162 volume['connect'](this.context['destination']);163 this._volume = volume;164 this._loop = false;165 // The time stamp on the audio time axis when the recording begins to play.166 this._startTime = -1;167 // Record the currently playing Source168 this._currentSource = null;169 // Record the time has been played170 this.playedLength = 0;171 this._currextTimer = null;172};173cc.Audio.WebAudio.prototype = {174 constructor: cc.Audio.WebAudio,175 get paused () {176 // If the current audio is a loop, then paused is false177 if (this._currentSource && this._currentSource.loop)178 return false;179 // StartTime does not have value, as the default -1, it does not begin to play180 if (this._startTime === -1)181 return true;182 // currentTime - startTime > durationTime183 return this.context.currentTime - this._startTime > this.buffer.duration;184 },185 set paused (bool) {},186 get loop () { return this._loop; },187 set loop (bool) { return this._loop = bool; },188 get volume () { return this._volume['gain'].value; },189 set volume (num) { return this._volume['gain'].value = num; },190 get currentTime () { return this.playedLength; },191 set currentTime (num) { return this.playedLength = num; },192 play: function (offset) {193 // If repeat play, you need to stop before an audio194 if (this._currentSource && !this.paused) {195 this._currentSource.stop(0);196 this.playedLength = 0;197 }198 var audio = this.context["createBufferSource"]();199 audio.buffer = this.buffer;200 audio["connect"](this._volume);201 audio.loop = this._loop;202 this._startTime = this.context.currentTime;203 offset = offset || this.playedLength;204 var duration = this.buffer.duration;205 if (!this._loop) {206 if (audio.start)207 audio.start(0, offset, duration - offset);208 else if (audio["notoGrainOn"])209 audio["noteGrainOn"](0, offset, duration - offset);210 else211 audio["noteOn"](0, offset, duration - offset);212 } else {213 if (audio.start)214 audio.start(0);215 else if (audio["notoGrainOn"])216 audio["noteGrainOn"](0);217 else218 audio["noteOn"](0);219 }220 this._currentSource = audio;221 // If the current audio context time stamp is 0222 // There may be a need to touch events before you can actually start playing audio223 // So here to add a timer to determine whether the real start playing audio, if not, then the incoming touchPlay queue224 if (this.context.currentTime === 0) {225 var self = this;226 clearTimeout(this._currextTimer);227 this._currextTimer = setTimeout(function () {228 if (self.context.currentTime === 0) {229 cc.Audio.touchPlayList.push({230 offset: offset,231 audio: self232 });233 }234 }, 10);235 }236 },237 pause: function () {238 // Record the time the current has been played239 this.playedLength = this.context.currentTime - this._startTime;240 //If the duration of playedLendth exceeds the audio, you should take the remainder241 this.playedLength %= this.buffer.duration;242 var audio = this._currentSource;243 this._currentSource = null;244 this._startTime = -1;245 if (audio)246 audio.stop(0);247 }248};249(function(polyfill){250 var SWA = polyfill.WEB_AUDIO, SWB = polyfill.ONLY_ONE;251 var support = [];252 (function(){253 var audio = document.createElement("audio");254 if(audio.canPlayType) {255 var ogg = audio.canPlayType('audio/ogg; codecs="vorbis"');256 if (ogg && ogg !== "") support.push(".ogg");257 var mp3 = audio.canPlayType("audio/mpeg");258 if (mp3 && mp3 !== "") support.push(".mp3");259 var wav = audio.canPlayType('audio/wav; codecs="1"');260 if (wav && wav !== "") support.push(".wav");261 var mp4 = audio.canPlayType("audio/mp4");262 if (mp4 && mp4 !== "") support.push(".mp4");263 var m4a = audio.canPlayType("audio/x-m4a");264 if (m4a && m4a !== "") support.push(".m4a");265 }266 })();267 try{268 if(SWA){269 var context = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();270 cc.Audio._context = context;271 if(polyfill.DELAY_CREATE_CTX)272 setTimeout(function(){273 context = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();274 cc.Audio._context = context;275 }, 0);276 }277 }catch(error){278 SWA = false;279 cc.log("browser don't support web audio");280 }281 var loader = {282 cache: {},283 useWebAudio: false,284 loadBuffer: function (url, cb) {285 if (!SWA) return; // WebAudio Buffer286 var request = new XMLHttpRequest();287 request.open("GET", url, true);288 request.responseType = "arraybuffer";289 // Our asynchronous callback290 request.onload = function () {291 context["decodeAudioData"](request.response, function(buffer){292 //success293 cb(null, buffer);294 //audio.setBuffer(buffer);295 }, function(){296 //error297 cb('decode error - ' + url);298 });299 };300 request.onerror = function(){301 cb('request error - ' + url);302 };303 request.send();304 },305 load: function(realUrl, url, res, cb){306 if(support.length === 0)307 return cb("can not support audio!");308 var audio = cc.loader.getRes(url);309 if (audio)310 return cb(null, audio);311 var i;312 if(cc.loader.audioPath)313 realUrl = cc.path.join(cc.loader.audioPath, realUrl);314 var extname = cc.path.extname(realUrl);315 var typeList = [extname];316 for(i=0; i<support.length; i++){317 if(extname !== support[i]){318 typeList.push(support[i]);319 }320 }321 audio = new cc.Audio(realUrl);322 cc.loader.cache[url] = audio;323 this.loadAudioFromExtList(realUrl, typeList, audio, cb);324 return audio;325 },326 loadAudioFromExtList: function(realUrl, typeList, audio, cb){327 if(typeList.length === 0){328 var ERRSTR = "can not found the resource of audio! Last match url is : ";329 ERRSTR += realUrl.replace(/\.(.*)?$/, "(");330 support.forEach(function(ext){331 ERRSTR += ext + "|";332 });333 ERRSTR = ERRSTR.replace(/\|$/, ")");334 return cb({status:520, errorMessage:ERRSTR}, null);335 }336 if (SWA && this.useWebAudio) {337 this.loadBuffer(realUrl, function (error, buffer) {338 if (error)339 cc.log(error);340 if (buffer)341 audio.setBuffer(buffer);342 cb(null, audio);343 });344 return;345 }346 var num = polyfill.ONE_SOURCE ? 1 : typeList.length;347 // å è½½ç»ä¸ä½¿ç¨dom348 var dom = document.createElement('audio');349 for (var i=0; i<num; i++) {350 var source = document.createElement('source');351 source.src = cc.path.changeExtname(realUrl, typeList[i]);352 dom.appendChild(source);353 }354 audio.setElement(dom);355 var timer = setTimeout(function(){356 if (dom.readyState === 0) {357 failure();358 } else {359 success();360 }361 }, 8000);362 var success = function () {363 dom.removeEventListener("canplaythrough", success, false);364 dom.removeEventListener("error", failure, false);365 dom.removeEventListener("emptied", success, false);366 if (polyfill.USE_LOADER_EVENT)367 dom.removeEventListener(polyfill.USE_LOADER_EVENT, success, false);368 clearTimeout(timer);369 cb(null, audio);370 };371 var failure = function () {372 cc.log('load audio failure - ' + realUrl);373 success();374 };375 dom.addEventListener("canplaythrough", success, false);376 dom.addEventListener("error", failure, false);377 if(polyfill.USE_LOADER_EVENT)378 dom.addEventListener(polyfill.USE_LOADER_EVENT, success, false);379 }380 };381 cc.loader.register(["mp3", "ogg", "wav", "mp4", "m4a"], loader);382 /**383 * cc.audioEngine is the singleton object, it provide simple audio APIs.384 * @namespace385 */386 cc.audioEngine = {387 _currMusic: null,388 _musicVolume: 1,389 features: polyfill,390 /**391 * Indicates whether any background music can be played or not.392 * @returns {boolean} <i>true</i> if the background music is playing, otherwise <i>false</i>393 */394 willPlayMusic: function(){return false;},395 /**396 * Play music.397 * @param {String} url The path of the music file without filename extension.398 * @param {Boolean} loop Whether the music loop or not.399 * @example400 * //example401 * cc.audioEngine.playMusic(path, false);402 */403 playMusic: function(url, loop){404 var bgMusic = this._currMusic;405 if (bgMusic && bgMusic.getPlaying()) {406 bgMusic.stop();407 }408 var audio = cc.loader.getRes(url);409 if (!audio) {410 cc.loader.load(url);411 audio = cc.loader.getRes(url);412 }413 audio.setVolume(this._musicVolume);414 audio.play(0, loop || false);415 this._currMusic = audio;416 },417 /**418 * Stop playing music.419 * @param {Boolean} [releaseData] If release the music data or not.As default value is false.420 * @example421 * //example422 * cc.audioEngine.stopMusic();423 */424 stopMusic: function(releaseData){425 var audio = this._currMusic;426 if (audio) {427 audio.stop();428 if (releaseData)429 cc.loader.release(audio.src);430 }431 },432 /**433 * Pause playing music.434 * @example435 * //example436 * cc.audioEngine.pauseMusic();437 */438 pauseMusic: function(){439 var audio = this._currMusic;440 if (audio)441 audio.pause();442 },443 /**444 * Resume playing music.445 * @example446 * //example447 * cc.audioEngine.resumeMusic();448 */449 resumeMusic: function(){450 var audio = this._currMusic;451 if (audio)452 audio.resume();453 },454 /**455 * Rewind playing music.456 * @example457 * //example458 * cc.audioEngine.rewindMusic();459 */460 rewindMusic: function(){461 var audio = this._currMusic;462 if (audio){463 audio.stop();464 audio.play();465 }466 },467 /**468 * The volume of the music max value is 1.0,the min value is 0.0 .469 * @return {Number}470 * @example471 * //example472 * var volume = cc.audioEngine.getMusicVolume();473 */474 getMusicVolume: function(){475 return this._musicVolume;476 },477 /**478 * Set the volume of music.479 * @param {Number} volume Volume must be in 0.0~1.0 .480 * @example481 * //example482 * cc.audioEngine.setMusicVolume(0.5);483 */484 setMusicVolume: function(volume){485 volume = volume - 0;486 if (isNaN(volume)) volume = 1;487 if (volume > 1) volume = 1;488 if (volume < 0) volume = 0;489 this._musicVolume = volume;490 var audio = this._currMusic;491 if (audio) {492 audio.setVolume(volume);493 }494 },495 /**496 * Whether the music is playing.497 * @return {Boolean} If is playing return true,or return false.498 * @example499 * //example500 * if (cc.audioEngine.isMusicPlaying()) {501 * cc.log("music is playing");502 * }503 * else {504 * cc.log("music is not playing");505 * }506 */507 isMusicPlaying: function(){508 var audio = this._currMusic;509 if (audio) {510 return audio.getPlaying();511 } else {512 return false;513 }514 },515 _audioPool: {},516 _maxAudioInstance: 10,517 _effectVolume: 1,518 /**519 * Play sound effect.520 * @param {String} url The path of the sound effect with filename extension.521 * @param {Boolean} loop Whether to loop the effect playing, default value is false522 * @return {Number|null} the audio id523 * @example524 * //example525 * var soundId = cc.audioEngine.playEffect(path);526 */527 playEffect: function(url, loop){528 if (SWB && this._currMusic && this._currMusic.getPlaying()) {529 cc.log('Browser is only allowed to play one audio');530 return null;531 }532 var effectList = this._audioPool[url];533 if (!effectList) {534 effectList = this._audioPool[url] = [];535 }536 var i;537 for (i = 0; i < effectList.length; i++) {538 if (!effectList[i].getPlaying()) {539 break;540 }541 }542 if (!SWA && i > this._maxAudioInstance) {543 var first = effectList.shift();544 first.stop();545 effectList.push(first);546 i = effectList.length - 1;547 // cc.log("Error: %s greater than %d", url, this._maxAudioInstance);548 }549 var audio;550 if (effectList[i]) {551 audio = effectList[i];552 audio.setVolume(this._effectVolume);553 audio.play(0, loop || false);554 return audio;555 }556 audio = cc.loader.getRes(url);557 if (audio && SWA && audio._AUDIO_TYPE === 'AUDIO') {558 cc.loader.release(url);559 audio = null;560 }561 if (audio) {562 if (SWA && audio._AUDIO_TYPE === 'AUDIO') {563 loader.loadBuffer(url, function (error, buffer) {564 audio.setBuffer(buffer);565 audio.setVolume(cc.audioEngine._effectVolume);566 if (!audio.getPlaying())567 audio.play(0, loop || false);568 });569 } else {570 audio = audio.cloneNode();571 audio.setVolume(this._effectVolume);572 audio.play(0, loop || false);573 effectList.push(audio);574 return audio;575 }576 }577 loader.useWebAudio = true;578 cc.loader.load(url, function (audio) {579 audio = cc.loader.getRes(url);580 audio = audio.cloneNode();581 audio.setVolume(cc.audioEngine._effectVolume);582 audio.play(0, loop || false);583 effectList.push(audio);584 });585 loader.useWebAudio = false;586 return audio;587 },588 /**589 * Set the volume of sound effects.590 * @param {Number} volume Volume must be in 0.0~1.0 .591 * @example592 * //example593 * cc.audioEngine.setEffectsVolume(0.5);594 */595 setEffectsVolume: function(volume){596 volume = volume - 0;597 if(isNaN(volume)) volume = 1;598 if(volume > 1) volume = 1;599 if(volume < 0) volume = 0;600 this._effectVolume = volume;601 var audioPool = this._audioPool;602 for(var p in audioPool){603 var audioList = audioPool[p];604 if(Array.isArray(audioList))605 for(var i=0; i<audioList.length; i++){606 audioList[i].setVolume(volume);607 }608 }609 },610 /**611 * The volume of the effects max value is 1.0,the min value is 0.0 .612 * @return {Number}613 * @example614 * //example615 * var effectVolume = cc.audioEngine.getEffectsVolume();616 */617 getEffectsVolume: function(){618 return this._effectVolume;619 },620 /**621 * Pause playing sound effect.622 * @param {Number} audio The return value of function playEffect.623 * @example624 * //example625 * cc.audioEngine.pauseEffect(audioID);626 */627 pauseEffect: function(audio){628 if(audio){629 audio.pause();630 }631 },632 /**633 * Pause all playing sound effect.634 * @example635 * //example636 * cc.audioEngine.pauseAllEffects();637 */638 pauseAllEffects: function(){639 var ap = this._audioPool;640 for(var p in ap){641 var list = ap[p];642 for(var i=0; i<ap[p].length; i++){643 if(list[i].getPlaying()){644 list[i].pause();645 }646 }647 }648 },649 /**650 * Resume playing sound effect.651 * @param {Number} audio The return value of function playEffect.652 * @audioID653 * //example654 * cc.audioEngine.resumeEffect(audioID);655 */656 resumeEffect: function(audio){657 if(audio)658 audio.resume();659 },660 /**661 * Resume all playing sound effect662 * @example663 * //example664 * cc.audioEngine.resumeAllEffects();665 */666 resumeAllEffects: function(){667 var ap = this._audioPool;668 for(var p in ap){669 var list = ap[p];670 for(var i=0; i<ap[p].length; i++){671 list[i].resume();672 }673 }674 },675 /**676 * Stop playing sound effect.677 * @param {Number} audio The return value of function playEffect.678 * @example679 * //example680 * cc.audioEngine.stopEffect(audioID);681 */682 stopEffect: function(audio){683 if(audio)684 audio.stop();685 },686 /**687 * Stop all playing sound effects.688 * @example689 * //example690 * cc.audioEngine.stopAllEffects();691 */692 stopAllEffects: function(){693 var ap = this._audioPool;694 for(var p in ap){695 var list = ap[p];696 for(var i=0; i<ap[p].length; i++){697 list[i].stop();698 }699 }700 },701 /**702 * Unload the preloaded effect from internal buffer703 * @param {String} url704 * @example705 * //example706 * cc.audioEngine.unloadEffect(EFFECT_FILE);707 */708 unloadEffect: function(url){709 if(!url){710 return;711 }712 cc.loader.release(url);713 var pool = this._audioPool[url];714 if(pool) pool.length = 0;715 delete this._audioPool[url];716 },717 /**718 * End music and effects.719 */720 end: function(){721 this.stopMusic();722 this.stopAllEffects();723 },724 _pauseCache: [],725 _pausePlaying: function(){726 var bgMusic = this._currMusic;727 if(bgMusic && bgMusic.getPlaying()){728 bgMusic.pause();729 this._pauseCache.push(bgMusic);730 }731 var ap = this._audioPool;732 for(var p in ap){733 var list = ap[p];734 for(var i=0; i<ap[p].length; i++){735 if(list[i].getPlaying()){736 list[i].pause();737 this._pauseCache.push(list[i]);738 }739 }740 }741 },742 _resumePlaying: function(){743 var list = this._pauseCache;744 for(var i=0; i<list.length; i++){745 list[i].resume();746 }747 list.length = 0;748 }749 };...
Irina_AntiAudioDelay.js
Source:Irina_AntiAudioDelay.js
1/*:2 * @plugindesc <AntiAudioDelay> for RPG Maker MV version 1.6.2.3 * @author RPG Maker Irina4 *5 * @help6 * *** Introduction ***7 *8 * When playing audio in RPG Maker MV events, there's a small delay when the9 * audio loads to when it's actually played. This can make some scenes lose10 * impact where an emotional piece of music is supposed to be played, but it11 * gets delayed instead and ruins the moment.12 *13 * What this plugin does is go through the currently running event's command14 * list by a certain amount and loads ahead of time the audio files it finds.15 * This way, the audio files are ready by the time the event runs, making it16 * transition smoothly.17 *18 * This plugin does not preload and store audio files forever because that's a19 * very quick way to get your game client to crash when it consumes more memory20 * than the player's computer can handle. Instead, it will save a designated21 * amount of audio files in its cache to keep them ready in case they're reused22 * but will flush them out of memory when the limit has been reached. This is23 * to ensure that memory doesn't overflow and crash the game.24 *25 *26 *27 * *** Plugin Parameters ***28 *29 * Load Ahead Index By30 *31 * This is how many event lines the plugin will look ahead to search for32 * audio files to load into the cache. Keep in mind this is lines, not actual33 * event commands. Events that have multiple lines like messages will count for34 * a different amount of lines. Therefore, it's safe to have this look ahead by35 * a large number like 10.36 *37 * Cache Limits38 *39 * Each of these for BGM, BGS, ME, and SE all do the same thing: store a40 * number of audio files in quick accessible memory for the game client to use41 * and call when needed. If the amount exceeds the limit declared on the plugin42 * parameter, then the oldest entries will be flushed out of memory until the43 * cache is at the limit amount.44 *45 *46 *47 * *** Plugin Commands ***48 * 49 * FlushAudioCache BGM50 * FlushAudioCache BGS51 * FlushAudioCache ME52 * FlushAudioCache SE53 * FlushAudioCache ALL54 * 55 * These will clear the audio caches for the written type of audio. If you56 * pick all, then all four types will be flushed out of memory. This will give57 * your game a clear slate for the the audio cache, which means the game may58 * lag a little bit upon reloading the new BGM files.59 * 60 * In my opinion, these plugin commands should never need to be used since61 * the plugin will automatically clear them once the cache goes over the limit,62 * but I'm just giving you control over the audio cache for your game just in63 * case you want to do something with it.64 *65 * 66 *67 * *** RPG Maker Version ***68 *69 * This plugin is made for and tested on RPG Maker MV with version 1.6.2.70 * I cannot guarantee if it works on lower versions.71 *72 *73 *74 * *** Terms of Use ***75 * 76 * 1. These plugins may be used in free or commercial games.77 * 2. 'RPG Maker Irina' must be given credit in your games.78 * 3. You are allowed to edit the code.79 * 4. Do NOT change the filename, parameters, and information of the plugin.80 * 5. You are NOT allowed to redistribute these Plugins.81 * 6. You may NOT take code for your own released Plugins.82 *83 * *** Help End ***84 *85 * @param 86 *87 * @param LoadAheadIndex88 * @text Load Ahead Index By89 * @desc Load BGM, BGS, ME, SE audio in a running event ahead by this count for the event index90 * @default 1091 *92 * @param93 *94 * @param CacheLimits95 * @text Cache Limits96 *97 * @param CacheLimitBgm98 * @text BGM99 * @parent CacheLimits100 * @desc Store this many BGM in the cache before removing the earlier ones101 * @default 10102 *103 * @param CacheLimitBgs104 * @text BGS105 * @parent CacheLimits106 * @desc Store this many BGS in the cache before removing the earlier ones107 * @default 10108 *109 * @param CacheLimitMe110 * @text ME111 * @parent CacheLimits112 * @desc Store this many ME in the cache before removing the earlier ones113 * @default 10114 *115 * @param CacheLimitSe116 * @text SE117 * @parent CacheLimits118 * @desc Store this many SE in the cache before removing the earlier ones119 * @default 10120 *121 */122//=============================================================================...
Using AI Code Generation
1const wptools = require('wptools');2let audio = wptools.page('Albert Einstein').get_audio();3audio.then(function(result){4 console.log(result);5});6const wptools = require('wptools');7let audio = wptools.page('Albert Einstein').get_audio();8audio.then(function(result){9 console.log(result);10}).catch(function(error){11 console.log(error);12});13const wptools = require('wptools');14let audio = wptools.page('Albert Einstein').get_audio();15audio.then(function(result){16 console.log(result);17}).catch(function(error){18 console.log(error);19});20const wptools = require('wptools');21let audio = wptools.page('Albert Einstein').get_audio();22audio.then(function(result){23 console.log(result);24}).catch(function(error){25 console.log(error);26});27const wptools = require('wptools');28let audio = wptools.page('Albert Einstein').get_audio();29audio.then(function(result){30 console.log(result);31}).catch(function(error){32 console.log(error);33});34const wptools = require('wptools');35let audio = wptools.page('Albert Einstein').get_audio();36audio.then(function(result){37 console.log(result);38}).catch(function(error){39 console.log(error);40});41const wptools = require('wptools');42let audio = wptools.page('Albert Einstein').get_audio();43audio.then(function(result){44 console.log(result);45}).catch(function(error){46 console.log(error);47});48const wptools = require('wptools');49let audio = wptools.page('Albert Einstein').get_audio();50audio.then(function(result){51 console.log(result);52}).catch(function(error){53 console.log(error);54});
Using AI Code Generation
1var wpt = require('wptoolkit');2var audio = new wpt.Audio();3audio.play('audio/test.wav', function(err) {4 if (err) {5 console.log(err);6 }7});
Using AI Code Generation
1var audio = require('audio');2audio.play('test.mp3', function (err, res) {3 if (err) {4 console.log('Error playing file: ' + err);5 } else {6 console.log('File played successfully');7 }8});9### audio.play(filename, callback)
Using AI Code Generation
1var wptools = require('wptools');2wptools.audio("Mars").then(function(result){3 console.log(result);4});5var wptools = require('wptools');6wptools.citations("Mars").then(function(result){7 console.log(result);8});9var wptools = require('wptools');10wptools.categories("Mars").then(function(result){11 console.log(result);12});13var wptools = require('wptools');14wptools.coordinates("Mars").then(function(result){15 console.log(result);16});17var wptools = require('wptools');18wptools.definitions("Mars").then(function(result){19 console.log(result);20});
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!