diff --git a/demo/index.html b/demo/index.html
index ed301f2..ec7128d 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -59,34 +59,31 @@
-
+ ])">ap.addAudio(...)
With playlist
-
+
With lyrics
With playlist and lyrics
diff --git a/src/js/controller.js b/src/js/controller.js
index 9e3f23e..22e03be 100644
--- a/src/js/controller.js
+++ b/src/js/controller.js
@@ -32,7 +32,7 @@ class Controller {
}
const musicIndex = parseInt(target.getElementsByClassName('aplayer-list-index')[0].innerHTML) - 1;
if (musicIndex !== this.player.playIndex) {
- this.player.setMusic(musicIndex);
+ this.player.setAudio(musicIndex);
this.player.play();
}
else {
diff --git a/src/js/player.js b/src/js/player.js
index 5d633b4..6bacd30 100644
--- a/src/js/player.js
+++ b/src/js/player.js
@@ -24,23 +24,10 @@ class APlayer {
constructor (options) {
this.options = handleOption(options);
this.container = this.options.container;
-
this.audios = [];
- this.mode = this.options.mode;
-
- this.events = new Events();
-
- // multiple music
this.playIndex = 0;
- this.music = this.options.music[this.playIndex];
-
- // add class aplayer-withlrc
- if (this.options.showlrc) {
- this.container.classList.add('aplayer-withlrc');
- }
- if (this.options.music.length > 1) {
- this.container.classList.add('aplayer-withlist');
- }
+ this.mode = this.options.mode;
+ this.paused = true;
// Assume "circulation" mode if single music is loaded and mode isn't already "circulation" or "order".
if (!this.isMultiple() && this.mode !== 'circulation' && this.mode !== 'order') {
@@ -48,17 +35,19 @@ class APlayer {
}
this.getRandomOrder();
- this.user = new User(this);
-
+ if (this.options.showlrc) {
+ this.container.classList.add('aplayer-withlrc');
+ }
+ if (this.options.music.length > 1) {
+ this.container.classList.add('aplayer-withlist');
+ }
if (utils.isMobile) {
this.container.classList.add('aplayer-mobile');
}
-
this.arrow = this.container.offsetWidth <= 300;
if (this.arrow) {
this.container.classList.add('aplayer-arrow');
}
-
if (this.options.narrow) {
this.container.classList.add('aplayer-narrow');
}
@@ -92,26 +81,20 @@ class APlayer {
player: this,
});
}
-
+ this.events = new Events();
+ this.user = new User(this);
this.bar = new Bar(this.template);
-
this.controller = new Controller(this);
-
this.timer = new Timer(this);
- this.paused = true;
-
this.initAudio();
-
if (this.mode === 'random') {
- this.setMusic(this.randomOrder[0]);
+ this.setAudio(this.randomOrder[0]);
}
else {
- this.setMusic(0);
+ this.setAudio(0);
}
- this.volume(this.user.get('volume'), true, true);
-
// autoplay
if (this.options.autoplay) {
this.play();
@@ -124,57 +107,58 @@ class APlayer {
this.audio = document.createElement('audio');
this.audio.preload = this.options.preload ? this.options.preload : 'auto';
- this.audio.addEventListener('play', () => {
- if (this.paused) {
- this.play();
- }
- });
-
- this.audio.addEventListener('pause', () => {
- if (!this.paused) {
- this.pause();
- }
- });
-
for (let i = 0; i < this.events.audioEvents.length; i++) {
this.audio.addEventListener(this.events.audioEvents[i], () => {
this.events.trigger(this.events.audioEvents[i]);
});
}
+ this.on('play', () => {
+ if (this.paused) {
+ this.play();
+ }
+ });
+
+ this.on('pause', () => {
+ if (!this.paused) {
+ this.pause();
+ }
+ });
+
// show audio time: the metadata has loaded or changed
- this.audio.addEventListener('durationchange', () => {
+ this.on('durationchange', () => {
+ console.log('durationchange');
if (this.audio.duration !== 1) { // compatibility: Android browsers will output 1 at first
this.template.dtime.innerHTML = utils.secondToTime(this.audio.duration);
}
});
// show audio loaded bar: to inform interested parties of progress downloading the media
- this.audio.addEventListener('progress', () => {
+ this.on('progress', () => {
const percentage = this.audio.buffered.length ? this.audio.buffered.end(this.audio.buffered.length - 1) / this.audio.duration : 0;
this.bar.set('loaded', percentage, 'width');
});
// audio download error: an error occurs
- this.audio.addEventListener('error', () => {
+ this.on('error', () => {
this.template.author.innerHTML = ` - Error happens ╥﹏╥`;
});
// multiple music play
- this.audio.addEventListener('ended', () => {
+ this.on('ended', () => {
if (this.isMultiple()) {
if (this.audio.currentTime !== 0) {
if (this.mode === 'random') {
- this.setMusic(this.nextRandomNum());
+ this.setAudio(this.nextRandomNum());
this.play();
}
else if (this.mode === 'single') {
- this.setMusic(this.playIndex);
+ this.setAudio(this.playIndex);
this.play();
}
else if (this.mode === 'order') {
if (this.playIndex < this.options.music.length - 1) {
- this.setMusic(++this.playIndex);
+ this.setAudio(++this.playIndex);
this.play();
}
else {
@@ -183,7 +167,7 @@ class APlayer {
}
else if (this.mode === 'circulation') {
this.playIndex = (this.playIndex + 1) % this.options.music.length;
- this.setMusic(this.playIndex);
+ this.setAudio(this.playIndex);
this.play();
}
}
@@ -195,46 +179,44 @@ class APlayer {
}
});
- // control volume
- this.audio.volume = parseInt(this.template.volume.style.height) / 100;
-
- // loop
- this.audio.loop = !(this.isMultiple() || this.mode === 'order');
+ this.volume(this.user.get('volume'), true, true);
}
/**
* Set music
*/
- setMusic (index) {
- // get this.music
+ setAudio (index) {
if (typeof index !== 'undefined') {
this.playIndex = index;
}
- const indexMusic = this.playIndex;
- this.music = this.options.music[indexMusic];
// set html
- if (this.music.pic) {
- this.template.pic.style.backgroundImage = `url('${this.music.pic}')`;
+ if (this.options.music[this.playIndex].pic) {
+ this.template.pic.style.backgroundImage = `url('${this.options.music[this.playIndex].pic}')`;
}
else {
this.template.pic.style.backgroundImage = '';
}
- this.template.title.innerHTML = this.music.title;
- this.template.author.innerHTML = this.music.author ? ' - ' + this.music.author : '';
+ this.template.title.innerHTML = this.options.music[this.playIndex].title;
+ this.template.author.innerHTML = this.options.music[this.playIndex].author ? ' - ' + this.options.music[this.playIndex].author : '';
const light = this.container.getElementsByClassName('aplayer-list-light')[0];
if (light) {
light.classList.remove('aplayer-list-light');
}
- this.template.listItems[indexMusic].classList.add('aplayer-list-light');
+ this.container.querySelectorAll('.aplayer-list li')[this.playIndex].classList.add('aplayer-list-light');
- this.template.list.scrollTop = indexMusic * 33;
+ this.template.list.scrollTop = this.playIndex * 33;
- this.pause();
- this.audio.currentTime = 0;
- this.audio.src = this.music.url;
+ this.audio.src = this.options.music[this.playIndex].url;
+ this.seek(0);
+ if (this.paused) {
+ this.pause();
+ }
+ else {
+ this.play();
+ }
- this.lrc && this.lrc.switch(indexMusic);
+ this.lrc && this.lrc.switch(this.playIndex);
// set duration time
if (this.audio.duration !== 1) { // compatibility: Android browsers will output 1 at first
@@ -369,7 +351,7 @@ class APlayer {
/**
* get random order, using Fisher–Yates shuffle
*/
- getRandomOrder () {
+ getRandomOrder (length = this.options.music.length) {
function random (min, max) {
if (max) {
max = min;
@@ -388,7 +370,7 @@ class APlayer {
return shuffled;
}
if (this.isMultiple()) {
- this.randomOrder = shuffle([...Array(this.options.music.length)].map(function (item, i) {
+ this.randomOrder = shuffle([...Array(length)].map(function (item, i) {
return i;
}));
}
@@ -412,75 +394,12 @@ class APlayer {
}
}
- /**
- * Remove song from playlist
- */
- removeSong (indexOfSong) {
- if (this.options.music[indexOfSong]) { // Check if song exists
- if (this.options.music[indexOfSong + 1] || this.options.music[indexOfSong - 1]) {
- if (indexOfSong === this.playIndex) {
- if (this.options.music[indexOfSong + 1]) { // Play next song if it exists.
- this.setMusic(indexOfSong + 1);
- this.playIndex = this.playIndex - 1; // Adjust play index for removed song
- }
- else if (!this.options.music[indexOfSong + 1]) { // Play previous song if it exists.
- this.setMusic(indexOfSong - 1);
- }
- }
- else {
- if (indexOfSong < this.playIndex) {
- this.playIndex = this.playIndex - 1;
- }
- }
- if (this.template.list[indexOfSong + 1]) {
- const targetSong = this.template.list[indexOfSong - 1];
- targetSong.getElementsByClassName('aplayer-list-index')[0].textContent = indexOfSong;
- }
- else {
- for (let i = 1; i < this.template.list.length; i++) {
- if (this.template.list[indexOfSong + i]) {
- const targetSong = this.template.list[indexOfSong + i];
- targetSong.getElementsByClassName('aplayer-list-index')[0].textContent = indexOfSong + i;
- }
- }
- }
- this.options.music.splice(indexOfSong, 1); // Delete song from music array
- this.audios.splice(indexOfSong, 1); // Delete song from audios array
- this.template.list[indexOfSong].remove();
- if (this.options.music[0] && this.options.music[1]) {
- this.multiple = false;
- this.container.classList.remove('aplayer-withlist');
- }
- }
- const listHeight = parseInt(this.template.list.style.height, 10);
- this.template.list.style.height = listHeight - 33 + "px";
- }
- else {
- console.error("ERROR: Song does not exist");
- }
- }
-
- /**
- * destroy this player
- */
- destroy () {
- instances.splice(instances.indexOf(this), 1);
- this.pause();
- this.container.innerHTML = '';
- clearInterval(this.playedTime);
- for (const key in this) {
- if (this.hasOwnProperty(key)) {
- delete this[key];
- }
- }
- }
-
/**
* add music dynamically
*
* @param {Array} newMusic
*/
- addMusic (newMusic) {
+ addAudio (newMusic) {
const wasSingle = !this.isMultiple();
this.options.music = this.options.music.concat(newMusic);
@@ -501,11 +420,58 @@ class APlayer {
this.container.classList.add('aplayer-withlist');
this.audio.loop = false;
}
- const songListLength = this.template.listItems.length;
+ const songListLength = this.container.querySelectorAll('.aplayer-list li').length;
this.template.list.style.height = songListLength * 33 + 'px';
this.getRandomOrder();
}
+
+ /**
+ * Remove song from playlist
+ */
+ removeAudio (index) {
+ if (this.options.music[index] && this.options.music.length > 1) {
+ const list = this.container.querySelectorAll('.aplayer-list li');
+ if (index === this.playIndex) {
+ if (this.options.music[index + 1]) {
+ this.setAudio(index + 1);
+ }
+ else {
+ this.setAudio(index - 1);
+ }
+ }
+ if (this.playIndex > index) {
+ this.playIndex--;
+ }
+
+ this.options.music.splice(index, 1);
+ this.audios.splice(index, 1);
+
+ list[index].remove();
+ for (let i = index; i < list.length; i++) {
+ list[i].getElementsByClassName('aplayer-list-index')[0].textContent = i;
+ }
+ if (this.options.music.length === 1) {
+ this.container.classList.remove('aplayer-withlist');
+ }
+ this.template.list.style.height = parseInt(this.template.list.style.height, 10) - 33 + 'px';
+ }
+ }
+
+ /**
+ * destroy this player
+ */
+ destroy () {
+ instances.splice(instances.indexOf(this), 1);
+ this.pause();
+ this.container.innerHTML = '';
+ clearInterval(this.playedTime);
+ for (const key in this) {
+ if (this.hasOwnProperty(key)) {
+ delete this[key];
+ }
+ }
+ }
}
export default APlayer;
diff --git a/src/js/template.js b/src/js/template.js
index b0a6252..5039650 100644
--- a/src/js/template.js
+++ b/src/js/template.js
@@ -24,7 +24,6 @@ class Template {
this.button = this.container.querySelector('.aplayer-button');
this.list = this.container.querySelector('.aplayer-list');
this.listOl = this.container.querySelector('.aplayer-list ol');
- this.listItems = this.container.querySelectorAll('.aplayer-list li');
this.played = this.container.querySelector('.aplayer-played');
this.loaded = this.container.querySelector('.aplayer-loaded');
this.thumb = this.container.querySelector('.aplayer-thumb');