mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-01-07 23:38:14 +08:00
aa84077ac4
Additional code refactoring
719 lines
No EOL
25 KiB
JavaScript
719 lines
No EOL
25 KiB
JavaScript
// ----------------------------------------------------------------------------
|
|
// Buzz, a Javascript HTML5 Audio library
|
|
// v1.1.8 - Built 2015-01-12 11:08
|
|
// Licensed under the MIT license.
|
|
// http://buzz.jaysalvat.com/
|
|
// ----------------------------------------------------------------------------
|
|
// Copyright (C) 2010-2015 Jay Salvat
|
|
// http://jaysalvat.com/
|
|
// ----------------------------------------------------------------------------
|
|
|
|
(function(context, factory) {
|
|
"use strict";
|
|
if (typeof module !== "undefined" && module.exports) {
|
|
module.exports = factory();
|
|
} else if (typeof define === "function" && define.amd) {
|
|
define([], factory);
|
|
} else {
|
|
context.buzz = factory();
|
|
}
|
|
})(this, function() {
|
|
"use strict";
|
|
var AudioContext = window.AudioContext || window.webkitAudioContext;
|
|
var buzz = {
|
|
audioCtx: window.AudioContext ? new AudioContext() : null,
|
|
defaults: {
|
|
autoplay: false,
|
|
duration: 5e3,
|
|
formats: [],
|
|
loop: false,
|
|
placeholder: "--",
|
|
preload: "metadata",
|
|
volume: 80,
|
|
webAudioApi: false,
|
|
document: window.document
|
|
},
|
|
types: {
|
|
mp3: "audio/mpeg",
|
|
ogg: "audio/ogg",
|
|
wav: "audio/wav",
|
|
aac: "audio/aac",
|
|
m4a: "audio/x-m4a"
|
|
},
|
|
sounds: [],
|
|
el: document.createElement("audio"),
|
|
sound: function(src, options) {
|
|
options = options || {};
|
|
var doc = options.document || buzz.defaults.document;
|
|
var pid = 0, events = [], eventsOnce = {}, supported = buzz.isSupported();
|
|
this.load = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.sound.load();
|
|
return this;
|
|
};
|
|
this.play = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.sound.play();
|
|
return this;
|
|
};
|
|
this.togglePlay = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
if (this.sound.paused) {
|
|
this.sound.play();
|
|
} else {
|
|
this.sound.pause();
|
|
}
|
|
return this;
|
|
};
|
|
this.pause = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.sound.pause();
|
|
return this;
|
|
};
|
|
this.isPaused = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
return this.sound.paused;
|
|
};
|
|
this.stop = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.setTime(0);
|
|
this.sound.pause();
|
|
return this;
|
|
};
|
|
this.isEnded = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
return this.sound.ended;
|
|
};
|
|
this.loop = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.sound.loop = "loop";
|
|
this.bind("ended.buzzloop", function() {
|
|
this.currentTime = 0;
|
|
this.play();
|
|
});
|
|
return this;
|
|
};
|
|
this.unloop = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.sound.removeAttribute("loop");
|
|
this.unbind("ended.buzzloop");
|
|
return this;
|
|
};
|
|
this.mute = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.sound.muted = true;
|
|
return this;
|
|
};
|
|
this.unmute = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.sound.muted = false;
|
|
return this;
|
|
};
|
|
this.toggleMute = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.sound.muted = !this.sound.muted;
|
|
return this;
|
|
};
|
|
this.isMuted = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
return this.sound.muted;
|
|
};
|
|
this.setVolume = function(volume) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
if (volume < 0) {
|
|
volume = 0;
|
|
}
|
|
if (volume > 100) {
|
|
volume = 100;
|
|
}
|
|
this.volume = volume;
|
|
this.sound.volume = volume / 100;
|
|
return this;
|
|
};
|
|
this.getVolume = function() {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
return this.volume;
|
|
};
|
|
this.increaseVolume = function(value) {
|
|
return this.setVolume(this.volume + (value || 1));
|
|
};
|
|
this.decreaseVolume = function(value) {
|
|
return this.setVolume(this.volume - (value || 1));
|
|
};
|
|
this.setTime = function(time) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
var set = true;
|
|
this.whenReady(function() {
|
|
if (set === true) {
|
|
set = false;
|
|
this.sound.currentTime = time;
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
this.getTime = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
var time = Math.round(this.sound.currentTime * 100) / 100;
|
|
return isNaN(time) ? buzz.defaults.placeholder : time;
|
|
};
|
|
this.setPercent = function(percent) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
return this.setTime(buzz.fromPercent(percent, this.sound.duration));
|
|
};
|
|
this.getPercent = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
var percent = Math.round(buzz.toPercent(this.sound.currentTime, this.sound.duration));
|
|
return isNaN(percent) ? buzz.defaults.placeholder : percent;
|
|
};
|
|
this.setSpeed = function(duration) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.sound.playbackRate = duration;
|
|
return this;
|
|
};
|
|
this.getSpeed = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
return this.sound.playbackRate;
|
|
};
|
|
this.getDuration = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
var duration = Math.round(this.sound.duration * 100) / 100;
|
|
return isNaN(duration) ? buzz.defaults.placeholder : duration;
|
|
};
|
|
this.getPlayed = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
return timerangeToArray(this.sound.played);
|
|
};
|
|
this.getBuffered = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
return timerangeToArray(this.sound.buffered);
|
|
};
|
|
this.getSeekable = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
return timerangeToArray(this.sound.seekable);
|
|
};
|
|
this.getErrorCode = function() {
|
|
if (supported && this.sound.error) {
|
|
return this.sound.error.code;
|
|
}
|
|
return 0;
|
|
};
|
|
this.getErrorMessage = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
switch (this.getErrorCode()) {
|
|
case 1:
|
|
return "MEDIA_ERR_ABORTED";
|
|
|
|
case 2:
|
|
return "MEDIA_ERR_NETWORK";
|
|
|
|
case 3:
|
|
return "MEDIA_ERR_DECODE";
|
|
|
|
case 4:
|
|
return "MEDIA_ERR_SRC_NOT_SUPPORTED";
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
};
|
|
this.getStateCode = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
return this.sound.readyState;
|
|
};
|
|
this.getStateMessage = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
switch (this.getStateCode()) {
|
|
case 0:
|
|
return "HAVE_NOTHING";
|
|
|
|
case 1:
|
|
return "HAVE_METADATA";
|
|
|
|
case 2:
|
|
return "HAVE_CURRENT_DATA";
|
|
|
|
case 3:
|
|
return "HAVE_FUTURE_DATA";
|
|
|
|
case 4:
|
|
return "HAVE_ENOUGH_DATA";
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
};
|
|
this.getNetworkStateCode = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
return this.sound.networkState;
|
|
};
|
|
this.getNetworkStateMessage = function() {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
switch (this.getNetworkStateCode()) {
|
|
case 0:
|
|
return "NETWORK_EMPTY";
|
|
|
|
case 1:
|
|
return "NETWORK_IDLE";
|
|
|
|
case 2:
|
|
return "NETWORK_LOADING";
|
|
|
|
case 3:
|
|
return "NETWORK_NO_SOURCE";
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
};
|
|
this.set = function(key, value) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.sound[key] = value;
|
|
return this;
|
|
};
|
|
this.get = function(key) {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
return key ? this.sound[key] : this.sound;
|
|
};
|
|
this.bind = function(types, func) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
types = types.split(" ");
|
|
var self = this, efunc = function(e) {
|
|
func.call(self, e);
|
|
};
|
|
for (var t = 0; t < types.length; t++) {
|
|
var type = types[t], idx = type;
|
|
type = idx.split(".")[0];
|
|
events.push({
|
|
idx: idx,
|
|
func: efunc
|
|
});
|
|
this.sound.addEventListener(type, efunc, true);
|
|
}
|
|
return this;
|
|
};
|
|
this.unbind = function(types) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
types = types.split(" ");
|
|
for (var t = 0; t < types.length; t++) {
|
|
var idx = types[t], type = idx.split(".")[0];
|
|
for (var i = 0; i < events.length; i++) {
|
|
var namespace = events[i].idx.split(".");
|
|
if (events[i].idx === idx || namespace[1] && namespace[1] === idx.replace(".", "")) {
|
|
this.sound.removeEventListener(type, events[i].func, true);
|
|
events.splice(i, 1);
|
|
}
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
this.bindOnce = function(type, func) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
var self = this;
|
|
eventsOnce[pid++] = false;
|
|
this.bind(type + "." + pid, function() {
|
|
if (!eventsOnce[pid]) {
|
|
eventsOnce[pid] = true;
|
|
func.call(self);
|
|
}
|
|
self.unbind(type + "." + pid);
|
|
});
|
|
return this;
|
|
};
|
|
this.trigger = function(types, detail) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
types = types.split(" ");
|
|
for (var t = 0; t < types.length; t++) {
|
|
var idx = types[t];
|
|
for (var i = 0; i < events.length; i++) {
|
|
var eventType = events[i].idx.split(".");
|
|
if (events[i].idx === idx || eventType[0] && eventType[0] === idx.replace(".", "")) {
|
|
var evt = doc.createEvent("HTMLEvents");
|
|
evt.initEvent(eventType[0], false, true);
|
|
evt.originalEvent = detail;
|
|
this.sound.dispatchEvent(evt);
|
|
}
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
this.fadeTo = function(to, duration, callback) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
if (duration instanceof Function) {
|
|
callback = duration;
|
|
duration = buzz.defaults.duration;
|
|
} else {
|
|
duration = duration || buzz.defaults.duration;
|
|
}
|
|
var from = this.volume, delay = duration / Math.abs(from - to), self = this;
|
|
this.play();
|
|
function doFade() {
|
|
setTimeout(function() {
|
|
if (from < to && self.volume < to) {
|
|
self.setVolume(self.volume += 1);
|
|
doFade();
|
|
} else if (from > to && self.volume > to) {
|
|
self.setVolume(self.volume -= 1);
|
|
doFade();
|
|
} else if (callback instanceof Function) {
|
|
callback.apply(self);
|
|
}
|
|
}, delay);
|
|
}
|
|
this.whenReady(function() {
|
|
doFade();
|
|
});
|
|
return this;
|
|
};
|
|
this.fadeIn = function(duration, callback) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
return this.setVolume(0).fadeTo(100, duration, callback);
|
|
};
|
|
this.fadeOut = function(duration, callback) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
return this.fadeTo(0, duration, callback);
|
|
};
|
|
this.fadeWith = function(sound, duration) {
|
|
if (!supported) {
|
|
return this;
|
|
}
|
|
this.fadeOut(duration, function() {
|
|
this.stop();
|
|
});
|
|
sound.play().fadeIn(duration);
|
|
return this;
|
|
};
|
|
this.whenReady = function(func) {
|
|
if (!supported) {
|
|
return null;
|
|
}
|
|
var self = this;
|
|
if (this.sound.readyState === 0) {
|
|
this.bind("canplay.buzzwhenready", function() {
|
|
func.call(self);
|
|
});
|
|
} else {
|
|
func.call(self);
|
|
}
|
|
};
|
|
this.addSource = function(src) {
|
|
var self = this, source = doc.createElement("source");
|
|
source.src = src;
|
|
if (buzz.types[getExt(src)]) {
|
|
source.type = buzz.types[getExt(src)];
|
|
}
|
|
this.sound.appendChild(source);
|
|
source.addEventListener("error", function(e) {
|
|
self.sound.networkState = 3;
|
|
self.trigger("sourceerror", e);
|
|
});
|
|
return source;
|
|
};
|
|
function timerangeToArray(timeRange) {
|
|
var array = [], length = timeRange.length - 1;
|
|
for (var i = 0; i <= length; i++) {
|
|
array.push({
|
|
start: timeRange.start(i),
|
|
end: timeRange.end(i)
|
|
});
|
|
}
|
|
return array;
|
|
}
|
|
function getExt(filename) {
|
|
return filename.split(".").pop();
|
|
}
|
|
if (supported && src) {
|
|
for (var i in buzz.defaults) {
|
|
if (buzz.defaults.hasOwnProperty(i)) {
|
|
if (options[i] === undefined) {
|
|
options[i] = buzz.defaults[i];
|
|
}
|
|
}
|
|
}
|
|
this.sound = doc.createElement("audio");
|
|
if (options.webAudioApi && buzz.audioCtx) {
|
|
this.source = buzz.audioCtx.createMediaElementSource(this.sound);
|
|
this.source.connect(buzz.audioCtx.destination);
|
|
}
|
|
if (src instanceof Array) {
|
|
for (var j in src) {
|
|
if (src.hasOwnProperty(j)) {
|
|
this.addSource(src[j]);
|
|
}
|
|
}
|
|
} else if (options.formats.length) {
|
|
for (var k in options.formats) {
|
|
if (options.formats.hasOwnProperty(k)) {
|
|
this.addSource(src + "." + options.formats[k]);
|
|
}
|
|
}
|
|
} else {
|
|
this.addSource(src);
|
|
}
|
|
if (options.loop) {
|
|
this.loop();
|
|
}
|
|
if (options.autoplay) {
|
|
this.sound.autoplay = "autoplay";
|
|
}
|
|
if (options.preload === true) {
|
|
this.sound.preload = "auto";
|
|
} else if (options.preload === false) {
|
|
this.sound.preload = "none";
|
|
} else {
|
|
this.sound.preload = options.preload;
|
|
}
|
|
this.setVolume(options.volume);
|
|
buzz.sounds.push(this);
|
|
}
|
|
},
|
|
group: function(sounds) {
|
|
sounds = argsToArray(sounds, arguments);
|
|
this.getSounds = function() {
|
|
return sounds;
|
|
};
|
|
this.add = function(soundArray) {
|
|
soundArray = argsToArray(soundArray, arguments);
|
|
for (var a = 0; a < soundArray.length; a++) {
|
|
sounds.push(soundArray[a]);
|
|
}
|
|
};
|
|
this.remove = function(soundArray) {
|
|
soundArray = argsToArray(soundArray, arguments);
|
|
for (var a = 0; a < soundArray.length; a++) {
|
|
for (var i = 0; i < sounds.length; i++) {
|
|
if (sounds[i] === soundArray[a]) {
|
|
sounds.splice(i, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
this.load = function() {
|
|
fn("load");
|
|
return this;
|
|
};
|
|
this.play = function() {
|
|
fn("play");
|
|
return this;
|
|
};
|
|
this.togglePlay = function() {
|
|
fn("togglePlay");
|
|
return this;
|
|
};
|
|
this.pause = function(time) {
|
|
fn("pause", time);
|
|
return this;
|
|
};
|
|
this.stop = function() {
|
|
fn("stop");
|
|
return this;
|
|
};
|
|
this.mute = function() {
|
|
fn("mute");
|
|
return this;
|
|
};
|
|
this.unmute = function() {
|
|
fn("unmute");
|
|
return this;
|
|
};
|
|
this.toggleMute = function() {
|
|
fn("toggleMute");
|
|
return this;
|
|
};
|
|
this.setVolume = function(volume) {
|
|
fn("setVolume", volume);
|
|
return this;
|
|
};
|
|
this.increaseVolume = function(value) {
|
|
fn("increaseVolume", value);
|
|
return this;
|
|
};
|
|
this.decreaseVolume = function(value) {
|
|
fn("decreaseVolume", value);
|
|
return this;
|
|
};
|
|
this.loop = function() {
|
|
fn("loop");
|
|
return this;
|
|
};
|
|
this.unloop = function() {
|
|
fn("unloop");
|
|
return this;
|
|
};
|
|
this.setSpeed = function(speed) {
|
|
fn("setSpeed", speed);
|
|
return this;
|
|
};
|
|
this.setTime = function(time) {
|
|
fn("setTime", time);
|
|
return this;
|
|
};
|
|
this.set = function(key, value) {
|
|
fn("set", key, value);
|
|
return this;
|
|
};
|
|
this.bind = function(type, func) {
|
|
fn("bind", type, func);
|
|
return this;
|
|
};
|
|
this.unbind = function(type) {
|
|
fn("unbind", type);
|
|
return this;
|
|
};
|
|
this.bindOnce = function(type, func) {
|
|
fn("bindOnce", type, func);
|
|
return this;
|
|
};
|
|
this.trigger = function(type) {
|
|
fn("trigger", type);
|
|
return this;
|
|
};
|
|
this.fade = function(from, to, duration, callback) {
|
|
fn("fade", from, to, duration, callback);
|
|
return this;
|
|
};
|
|
this.fadeIn = function(duration, callback) {
|
|
fn("fadeIn", duration, callback);
|
|
return this;
|
|
};
|
|
this.fadeOut = function(duration, callback) {
|
|
fn("fadeOut", duration, callback);
|
|
return this;
|
|
};
|
|
function fn() {
|
|
var args = argsToArray(null, arguments), func = args.shift();
|
|
for (var i = 0; i < sounds.length; i++) {
|
|
sounds[i][func].apply(sounds[i], args);
|
|
}
|
|
}
|
|
function argsToArray(array, args) {
|
|
return array instanceof Array ? array : Array.prototype.slice.call(args);
|
|
}
|
|
},
|
|
all: function() {
|
|
return new buzz.group(buzz.sounds);
|
|
},
|
|
isSupported: function() {
|
|
return !!buzz.el.canPlayType;
|
|
},
|
|
isOGGSupported: function() {
|
|
return !!buzz.el.canPlayType && buzz.el.canPlayType('audio/ogg; codecs="vorbis"');
|
|
},
|
|
isWAVSupported: function() {
|
|
return !!buzz.el.canPlayType && buzz.el.canPlayType('audio/wav; codecs="1"');
|
|
},
|
|
isMP3Supported: function() {
|
|
return !!buzz.el.canPlayType && buzz.el.canPlayType("audio/mpeg;");
|
|
},
|
|
isAACSupported: function() {
|
|
return !!buzz.el.canPlayType && (buzz.el.canPlayType("audio/x-m4a;") || buzz.el.canPlayType("audio/aac;"));
|
|
},
|
|
toTimer: function(time, withHours) {
|
|
var h, m, s;
|
|
h = Math.floor(time / 3600);
|
|
h = isNaN(h) ? "--" : h >= 10 ? h : "0" + h;
|
|
m = withHours ? Math.floor(time / 60 % 60) : Math.floor(time / 60);
|
|
m = isNaN(m) ? "--" : m >= 10 ? m : "0" + m;
|
|
s = Math.floor(time % 60);
|
|
s = isNaN(s) ? "--" : s >= 10 ? s : "0" + s;
|
|
return withHours ? h + ":" + m + ":" + s : m + ":" + s;
|
|
},
|
|
fromTimer: function(time) {
|
|
var splits = time.toString().split(":");
|
|
if (splits && splits.length === 3) {
|
|
time = parseInt(splits[0], 10) * 3600 + parseInt(splits[1], 10) * 60 + parseInt(splits[2], 10);
|
|
}
|
|
if (splits && splits.length === 2) {
|
|
time = parseInt(splits[0], 10) * 60 + parseInt(splits[1], 10);
|
|
}
|
|
return time;
|
|
},
|
|
toPercent: function(value, total, decimal) {
|
|
var r = Math.pow(10, decimal || 0);
|
|
return Math.round(value * 100 / total * r) / r;
|
|
},
|
|
fromPercent: function(percent, total, decimal) {
|
|
var r = Math.pow(10, decimal || 0);
|
|
return Math.round(total / 100 * percent * r) / r;
|
|
}
|
|
};
|
|
return buzz;
|
|
}); |