html5-music-player/player.js

274 lines
7.4 KiB
JavaScript

"use strict";
var music = Array(),
track,
audio,
pic,
title,
shuffle,
repeat,
err,
playlist,
offset;
function getId(id) {
return document.getElementById(id);
}
function randInt(min, max) {
var rand = Math.round(Math.random() * (max - min + 1) + min);
if (rand == max + 1) {
return min;
}
return rand;
}
function sendEvt(element, event) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent(event, true, true);
return !element.dispatchEvent(evt);
}
function extToMime(ext) {
switch(ext) {
case "mp3":
return "audio/mpeg";
case "mp2":
return "audio/mpeg";
case "ogg":
return "audio/ogg";
case "aac":
return "audio/aac";
case "wav":
return "audio/wave";
case "webm":
return "audio/webm";
default:
"audio/" + ext;
}
}
function wait4It(fn) {// Dirty trick
try {
fn();
} catch(e) {
setTimeout(function() {
wait4It(fn);
}, 7);
}
}
function populateList(arr, e, dir) {
var li,
i,
x,
cover;
for (i in arr) {
if (i != "/") {
li = document.createElement('li');
li.className = "folder";
li.textContent = i;
e.appendChild(li);
li.addEventListener('click', function(event) {
event.stopPropagation();
if (this.className.indexOf("open") == -1) {
this.className = "open " + this.className;
} else {
this.className = this.className.substr(5);
}
}, false);
li.appendChild(document.createElement('ul'))
populateList(arr[i], li.childNodes[1], dir + i + '/');
} else {
cover = false;
for (x in arr[i]) {
if (arr[i][x].slice(0, arr[i][x].lastIndexOf('.')).toLowerCase() == "cover") {
cover = arr[i][x];
arr[i].splice(x, 1);
break;
}
}
for (x in arr[i]) {
li = document.createElement('li');
li.id = music.length;
li.className = "song";
li.textContent = arr[i][x].substr(0, arr[i][x].lastIndexOf('.'));
li.setAttribute('file', dir + arr[i][x]);
li.setAttribute('cover', cover ? dir + cover : '/icons/sound2.png');
li.addEventListener('click', function(event) {
event.stopPropagation();
var file = this.getAttribute('file'),
cover = this.getAttribute('cover'),
s = document.createElement('source'),
mime = extToMime(file.substr(-3)),
last = music[track];
if (last.className.indexOf('playing') > -1) {
while (last.id != 'playlist') {
last.className = last.className.slice(0, -8);
last = last.parentNode.parentNode;
}
}
pic.src = cover;
title.textContent = this.textContent;
if (!audio.canPlayType(mime)) {
err.textContent = "This browser does not support " + mime.substr(mime.indexOf('/') + 1).toUpperCase() + " audio."
err.className = 'open';
} else {
err.removeAttribute('class');
}
s.type = mime;
s.src = file;
audio.appendChild(s);
if (audio.childNodes.length > 1) {
audio.removeChild(audio.childNodes[0]);
}
audio.load();
audio.play();
track = parseInt(this.id);
if (mime == 'audio/mpeg' || mime == 'audio/aac') {
ID3.loadTags(file, function() {
var tags = ID3.getAllTags(file);
document.getElementById("artist").textContent = "Artist : " + tags.artist || "";
document.getElementById("album").textContent = "Album : " + tags.album || "";
window.document.title = title.textContent = tags.title || title.textContent;
});
} else {
document.getElementById("artist").textContent = "";
document.getElementById("album").textContent = "";
window.document.title = title.textContent;
}
last = music[track];
while (last.id != 'playlist') {
last.className += ' playing';
last = last.parentNode.parentNode;
}
}, false);
e.appendChild(li);
music.push(li);
}
}
}
}
function init() {
var ul = document.createElement('ul'),
config = localStorage.getItem("config");
audio = getId('audio');
title = getId('title');
pic = getId('cover');
shuffle = getId('shuffle');
repeat = getId('repeat');
err = getId('error');
offset = getId('player').offsetHeight + 32;
playlist = getId('playlist');
playlist.appendChild(ul);
sendEvt(window, 'resize');
populateList(library['music'], ul, library['path']);
config = config != null ? JSON.parse(config) : {// Default player settings
"volume" : .25,
"track" : 0,
"state" : false,
"time" : 0,
"shuffle" : true,
"repeat" : false
};
audio.addEventListener("ended", function() {
if (repeat.checked) {
audio.currentTime = 0;
return audio.play();
}
var next = track;
if (shuffle.checked) {
next = randInt(0, music.length - 1);
} else if (track + 1 < music.length) {
next++;
} else {
next = 0;
}
sendEvt(music[next], 'click');
}, false);
getId('next').addEventListener("click", function() {
if (track == music.length - 1) {
track = -1;
}
sendEvt(music[track + 1], 'click');
}, false);
getId('back').addEventListener("click", function() {
if (track == 0) {
track = music.length;
}
sendEvt(music[track - 1], 'click');
}, false);
shuffle.checked = config["shuffle"];
repeat.checked = config["repeat"];
track = config["track"];
if (config['time'] == 0 && track == 0) {
sendEvt(audio, 'ended');
} else {
sendEvt(music[track], 'click');
audio.pause();
wait4It(function() {
audio.currentTime = config["time"];
if (config["state"] === false) {
audio.play();
}
});
}
audio.volume = config["volume"];
window.onunload = function() {
if (isNaN(track) || isNaN(audio.currentTime) || isNaN(audio.volume)) {
return;
}
localStorage.setItem("config", JSON.stringify({
"volume" : audio.volume,
"track" : track,
"state" : audio.paused === true,
"time" : audio.currentTime,
"shuffle" : shuffle.checked === true,
"repeat" : repeat.checked === true
}));
}
document.addEventListener('keyup', function(event) {// keyboard shortcuts
switch(event.which) {
case 32:
audio[audio.paused?'play':'pause']();
return;
// spacebar
case 107:
audio.volume = audio.volume + .1 > 1 ? 1 : audio.volume + .1;
return;
// + (num pad)
case 109:
audio.volume = audio.volume - .1 < 0 ? 0 : audio.volume - .1;
return;
// - (num pad)
case 37:
getId('back').click();
return;
// left arrow
case 39:
getId('next').click();
return;
// right arrow
case 38:
audio.currentTime += 5;
return;
// up arrow
case 40:
audio.currentTime -= 5;
return;
// down arrow
case 83:
shuffle.checked = !shuffle.checked;
return;
// s
case 82:
repeat.checked = !repeat.checked;
return;
// r
}
}, false);
}
window.onresize = function() {
playlist.style.maxHeight = window.innerHeight - offset + 'px';
}