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