Обратите внимание, что первый объект (Audio) служит исключительно в качестве эмуляции элемента аудио (чтобы можно было запустить пример).
/**
* Эмуляция аудио объекта
* @param {string} src
* @constructor
*/
var Audio = function (src) {
this._time = Audio.randomInt(1000, 4000);
this._timer = null;
this._timeStart = null;
this._events = {};
this.src = src;
var that = this;
setTimeout(function () {
that._trigger("canplay");
}, Audio.randomInt(0, 500));
};
/**
* подписка на события
* @param {string} event
* @param {function} handler
*/
Audio.prototype.addEventListener = function (event, handler) {
if (!this._events[event]) this._events[event] = [];
this._events[event].push(handler);
};
/**
* Запускаем проигрывание
*/
Audio.prototype.play = function () {
var that = this;
this._trigger("play");
this._timeStart = Date.now();
this._timer = setTimeout(function () {
that._trigger("ended")
}, this._time);
};
/**
* Ставим на паузу
*/
Audio.prototype.pause = function () {
if (this._timer) {
clearTimeout(this._timer);
this._timer = null;
this._time = Date.now() - this._timeStart;
this._timeStart = null;
}
};
/**
* Снимаем обработчики
* @param {string} event
* @param {function} handler
*/
Audio.prototype.removeEventListener = function (event, handler) {
if (this._events[event]) {
this._events[event] = this._events[event].filter(function ($handler) {
return $handler != handler;
});
}
};
/**
* Запускаем событие
* @param event
* @private
*/
Audio.prototype._trigger = function (event) {
if (this._events[event]) {
this._events[event].forEach(function (handler) {
handler.call(this);
}, this);
}
};
/**
* Генерируем целое рандомное число
* @param {number} min
* @param {number} max
* @returns {number}
*/
Audio.randomInt = function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
/**
* Менеджер треков
* @param {string[]} tracks
* @constructor
*/
var TrackManager = function (tracks) {
this._active = 0;
this._collection = [];
this._createTracks(tracks);
};
/**
* Запускаем проигрывание треков
*/
TrackManager.prototype.play = function () {
if (this._active in this._collection) {
this._collection[this._active].play();
}
};
/**
* Создаем треки и подписываемся на события
* @param {string[]} tracks
* @private
*/
TrackManager.prototype._createTracks = function (tracks) {
tracks.forEach(function (src) {
var audio = new Audio(src), that = this;
audio.addEventListener("canplay", function () {
console.log(this.src + " canplay");
});
audio.addEventListener("play", function () {
console.log(this.src + " play");
});
audio.addEventListener("ended", function () {
alert(this.src + " ended");
that._onEnd();
});
this._collection.push(audio);
}, this);
};
/**
* Запускаем следующий трек когда заканчивается предыдущий;
* @private
*/
TrackManager.prototype._onEnd = function () {
this._active++;
this.play();
};
new TrackManager(["some1.mp3", "some2.mp3", "some3.mp3", "some4.mp3"]).play();