var tools = require("../tools/tools");
var Howl = require("howler").Howl;
var warn = tools.warn;
var truthy = tools.truthy;
function Audio (asset, interpreter) {
var sources, i, len, j, jlen, current, track, trackName;
var trackFiles, href, type, source, tracks, bus, trackSettings;
bus = interpreter.bus;
this.interpreter = interpreter;
this.bus = bus;
this.name = asset.getAttribute("name");
this.tracks = {};
this.autopause = truthy(asset.getAttribute("autopause"));
this.loop = truthy(asset.getAttribute("loop"));
this.fade = truthy(asset.getAttribute("fade"));
this.fadeinDuration = parseInt(asset.getAttribute("fadein")) || 1000;
this.fadeoutDuration = parseInt(asset.getAttribute("fadeout")) || 1000;
this._playing = false;
tracks = asset.getElementsByTagName("track");
len = tracks.length;
if (len < 1) {
warn(this.bus, "No tracks defined for audio element '" + this.name + "'.", asset);
return {
doNext: true
};
}
for (i = 0; i < len; i += 1) {
current = tracks[i];
trackName = current.getAttribute("title");
if (trackName === null) {
warn(this.bus, "No title defined for track '" + trackName +
"' in audio element '" + this.name + "'.", asset);
continue;
}
sources = current.getElementsByTagName("source");
jlen = sources.length;
if (jlen < 1) {
warn(this.bus, "No sources defined for track '" + trackName +
"' in audio element '" + this.name + "'.", asset);
continue;
}
trackSettings = {
urls: [],
autoplay: false,
loop: this.loop || false,
onload: this.bus.trigger.bind(this.bus, "wse.assets.loading.decrease")
};
trackFiles = {};
for (j = 0; j < jlen; j += 1) {
source = sources[j];
href = source.getAttribute("href");
type = source.getAttribute("type");
if (href === null) {
warn(this.bus, "No href defined for source in track '" +
trackName + "' in audio element '" + this.name + "'.", asset);
continue;
}
if (type === null) {
warn(this.bus, "No type defined for source in track '" +
trackName + "' in audio element '" + this.name + "'.", asset);
continue;
}
trackFiles[type] = href;
trackSettings.urls.push(href);
}
this.bus.trigger("wse.assets.loading.increase");
track = new Howl(trackSettings);
this.tracks[trackName] = track;
}
this.play = function (command) {
var fadeDuration;
if (this._playing) {
return {
doNext: true
};
}
this._playing = true;
this._paused = false;
if (command.getAttribute("fadein")) {
this.interpreter.waitCounter += 1;
fadeDuration = +command.getAttribute("fadein");
this.tracks[this._currentTrack].volume(0);
this.tracks[this._currentTrack].play();
this.tracks[this._currentTrack].fade(0, 1, fadeDuration, function () {
this.interpreter.waitCounter -= 1;
}.bind(this));
}
else {
this.tracks[this._currentTrack].play();
}
return {
doNext: true
};
};
this.stop = function (command) {
var fadeDuration;
if (!this._currentTrack) {
return {
doNext: true
};
}
this._playing = false;
this._paused = false;
if (command && command.getAttribute("fadeout")) {
this.interpreter.waitCounter += 1;
fadeDuration = +command.getAttribute("fadeout");
this.tracks[this._currentTrack].fade(1, 0, fadeDuration, function () {
this.tracks[this._currentTrack].stop();
this.interpreter.waitCounter -= 1;
}.bind(this));
}
else {
this.tracks[this._currentTrack].stop();
}
this.bus.trigger("wse.assets.audio.stop", this);
return {
doNext: true
};
};
this.pause = function () {
if (!this._currentTrack || !this._playing) {
return {
doNext: true
};
}
this._paused = true;
this.tracks[this._currentTrack].pause();
return {
doNext: true
};
};
this.bus.trigger("wse.assets.audio.constructor", this);
this.bus.subscribe("wse.interpreter.restart", function () {
this.stop();
}.bind(this));
window.addEventListener("blur", function () {
if (this._playing) {
this.tracks[this._currentTrack].fade(1, 0, 200);
}
}.bind(this));
window.addEventListener("focus", function () {
if (this._playing) {
this.tracks[this._currentTrack].fade(0, 1, 200);
}
}.bind(this));
}
Audio.prototype.set = function (command) {
var wasPlaying = false;
if (this._playing) {
wasPlaying = true;
}
this.stop();
this._currentTrack = command.getAttribute("track");
if (wasPlaying) {
this.play(command);
}
return {
doNext: true
};
};
Audio.prototype.save = function () {
var obj = {
currentTrack: this._currentTrack,
playing: this._playing,
paused: this._paused
};
this.bus.trigger("wse.assets.audio.save", this);
return obj;
};
Audio.prototype.restore = function (vals) {
var key;
this._playing = vals.playing;
this._paused = vals.paused;
this._currentTrack = vals.currentTrack;
for (key in this.tracks) {
this.tracks[key].stop();
}
if (this._playing && !this._paused) {
this.tracks[this._currentTrack].play();
}
this.bus.trigger("wse.assets.audio.restore", this);
};
module.exports = Audio;