first commit

This commit is contained in:
GM-Script-Writer-62850 2014-06-01 13:32:48 -04:00
commit b63a787981
6 changed files with 388 additions and 0 deletions

17
README.md Normal file
View File

@ -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>

26
index.html Normal file
View File

@ -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="|&#x25c0;&#x25c0;"/>
<input id="next" type="button" value="&#9654;&#9654;|"/>
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>

BIN
overview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

118
player.css Normal file
View File

@ -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;
}

198
player.js Normal file
View File

@ -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';
}

29
playlist.php Normal file
View File

@ -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));
?>