first commit
This commit is contained in:
commit
b63a787981
|
@ -0,0 +1,17 @@
|
||||||
|
This is a basic HTML5 music player
|
||||||
|
This was made to have the basic features in a music player as well as have a mobile friendly layout
|
||||||
|
|
||||||
|
Setup:
|
||||||
|
1. Add the index.html, player,js, player,css, and playlist.php files to a folder on your web server
|
||||||
|
2. Create a folder called library in that folder, this folder should contain your music
|
||||||
|
this folder can be a symlink to your main music folder
|
||||||
|
|
||||||
|
Any files/folders starting with a "." will be ignored
|
||||||
|
Cover images should be named cover (not case sensitive), they should be in png, jpg/jpeg, or gif format, basically anything a web browser can display
|
||||||
|
Cover images are optional
|
||||||
|
Any file not called cover will be treated as a audio file
|
||||||
|
All files should have a file extension (eg .png, .mp3, .ogg, etc)
|
||||||
|
This uses 3 icons from the apache web server, if you are using a different web service, grab these icons and save them as the following:
|
||||||
|
<a href="http://www.apache.org/icons/open.folder.png" target="_blank">/icons/open.folder.png</a>
|
||||||
|
<a href="http://www.apache.org/icons/folder.png" target="_blank">/icons/folder.png</a>
|
||||||
|
<a href="http://www.apache.org/icons/sound2.png" target="_blank">/icons/sound2.png</a>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<title>Music Player</title>
|
||||||
|
<link href="/icons/sound2.png" type="image/png" rel="shortcut icon">
|
||||||
|
<link href="player.css" type="text/css" rel="stylesheet"/>
|
||||||
|
<script src="playlist.php" type="application/javascript"></script>
|
||||||
|
<script src="player.js" type="application/javascript"></script>
|
||||||
|
</head>
|
||||||
|
<body onload="init();">
|
||||||
|
<div id="player">
|
||||||
|
<div>
|
||||||
|
<h4 id="title"></h4>
|
||||||
|
<input id="back" type="button" value="|◀◀"/>
|
||||||
|
<input id="next" type="button" value="▶▶|"/>
|
||||||
|
Shuffle: <input id="shuffle" type="checkbox"/><br/>
|
||||||
|
Repeat: <input id="repeat" type="checkbox"/>
|
||||||
|
<p id="error"></p>
|
||||||
|
</div>
|
||||||
|
<img id="cover"/><br/>
|
||||||
|
<audio id="audio" controls>This is your browser speaking, I don't support HTML5 cause I am too old to learn new tricks.</audio>
|
||||||
|
</div><br/>
|
||||||
|
<div id="playlist"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Binary file not shown.
After Width: | Height: | Size: 126 KiB |
|
@ -0,0 +1,118 @@
|
||||||
|
html,body{
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
body{
|
||||||
|
background:#383838;
|
||||||
|
color:white;
|
||||||
|
font-size:16px;
|
||||||
|
font-family:'open sans' sans serif;
|
||||||
|
font-weight:400;
|
||||||
|
font-variant:normal;
|
||||||
|
font-style:normal;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
body > div{
|
||||||
|
border:1px solid white;
|
||||||
|
border-radius:5px;
|
||||||
|
display:inline-block;
|
||||||
|
}
|
||||||
|
#player{
|
||||||
|
padding:10px;
|
||||||
|
text-align:right;
|
||||||
|
margin:10px 0;
|
||||||
|
width:300px;
|
||||||
|
}
|
||||||
|
#player > div{
|
||||||
|
width:195px;
|
||||||
|
display:inline-block;
|
||||||
|
text-align:right;
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
#player #cover{
|
||||||
|
width:100px;
|
||||||
|
height:100px;
|
||||||
|
background:white;
|
||||||
|
border-radius:5px;
|
||||||
|
margin-bottom:5px;
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
#player #title{
|
||||||
|
margin:0;
|
||||||
|
display:inline-block;
|
||||||
|
text-align:center;
|
||||||
|
width:195px;
|
||||||
|
word-wrap:break-word;
|
||||||
|
}
|
||||||
|
#player #back,
|
||||||
|
#player #next{
|
||||||
|
float:left;
|
||||||
|
margin:9px 5px 0 0;
|
||||||
|
font-family:Arial;
|
||||||
|
height:25px;
|
||||||
|
width:47px;
|
||||||
|
}
|
||||||
|
#player #error{
|
||||||
|
margin:0;
|
||||||
|
font-style:italic;
|
||||||
|
color:red;
|
||||||
|
font-size:small;
|
||||||
|
text-align:center;
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
#player #error.open{
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
#player audio{
|
||||||
|
width:100%;
|
||||||
|
max-height:30px;
|
||||||
|
display:inline-block;
|
||||||
|
font-size:small;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
#playlist{
|
||||||
|
min-height:300px;
|
||||||
|
overflow:auto;
|
||||||
|
text-align:left;
|
||||||
|
margin-bottom:6px;
|
||||||
|
width:320px;
|
||||||
|
}
|
||||||
|
#playlist ul{
|
||||||
|
list-style:none;
|
||||||
|
padding-left:0;
|
||||||
|
}
|
||||||
|
#playlist > ul{
|
||||||
|
margin:9px 0 9px 9px;
|
||||||
|
}
|
||||||
|
#playlist > ul ul{
|
||||||
|
height:0;
|
||||||
|
transition: max-height 1s;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
#playlist li{
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
padding-left:25px;
|
||||||
|
line-height:25px;
|
||||||
|
}
|
||||||
|
#playlist li:hover > ul,
|
||||||
|
#playlist li.open > ul{
|
||||||
|
height:auto;
|
||||||
|
}
|
||||||
|
#playlist .folder{
|
||||||
|
background-image:url(/icons/folder.png);
|
||||||
|
}
|
||||||
|
#playlist .folder.open{
|
||||||
|
background-image:url(/icons/folder.open.png);
|
||||||
|
}
|
||||||
|
#playlist .song{
|
||||||
|
background-image:url(/icons/sound2.png);
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
#playlist li{
|
||||||
|
font-style:italic;
|
||||||
|
color:lime;
|
||||||
|
}
|
||||||
|
#playlist li:not(.playing){
|
||||||
|
font-style:normal;
|
||||||
|
color:white;
|
||||||
|
}
|
|
@ -0,0 +1,198 @@
|
||||||
|
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){
|
||||||
|
evt = document.createEvent("HTMLEvents");
|
||||||
|
evt.initEvent(event, true, true );
|
||||||
|
return !element.dispatchEvent(evt);
|
||||||
|
}
|
||||||
|
function extToMime(ext){
|
||||||
|
switch(ext){
|
||||||
|
case "mp3":return "audio/mpeg";
|
||||||
|
case "ogg":return "audio/ogg";
|
||||||
|
case "aac":return "audio/aac";
|
||||||
|
case "wav":return "audio/wave";
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
populateList(libary,ul,'library/');// Folder containing music
|
||||||
|
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(){
|
||||||
|
var next=track;
|
||||||
|
if(!repeat.checked){
|
||||||
|
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
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.onresize=function(){
|
||||||
|
playlist.style.maxHeight=window.innerHeight-offset+'px';
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php header("content-type: application/javascript"); ?>
|
||||||
|
var libary=<?php
|
||||||
|
function tree($dir,$depth){
|
||||||
|
$json=new stdClass();
|
||||||
|
$scan=scandir($dir);
|
||||||
|
$files=array();
|
||||||
|
foreach($scan as $f){
|
||||||
|
if(substr($f,0,1)=="."){// Skip hidden files (UNIX defination)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(is_dir("$dir/$f")){
|
||||||
|
if($depth<10){// Max folder depth, this is to prevent a infinte loop
|
||||||
|
$json->{$f}=tree("$dir/$f",$depth+1);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$json->{$f}=array("Error: Too Deep"=>array("Infinite loop prevention"=>array()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
array_push($files,$f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(count($files)>0){
|
||||||
|
$json->{"/"}=$files;
|
||||||
|
}
|
||||||
|
return $json;
|
||||||
|
}
|
||||||
|
echo json_encode(tree('library',0));
|
||||||
|
?>
|
Loading…
Reference in New Issue