urlbase="mpd.lua?"
+minScrollHeight=200
function GetFilename(url)
{
return res;
}
+function SetSize() {
+ var w = window,
+ d = document,
+ e = d.documentElement,
+ g = d.getElementsByTagName('body')[0],
+ body_h = g.clientHeight,
+ window_h = w.innerHeight|| e.clientHeight|| g.clientHeight,
+ items = d.getElementById('items'),
+ current_h = items.clientHeight,
+ new_h=(window_h-body_h)+current_h;
+ if (new_h>minScrollHeight) {
+ items.style.height=new_h+"px";
+ }
+}
+
function RefreshPageStatus() {
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (this.readyState != 4 || this.status != 200) return;
var returnedData = JSON.parse(this.responseText);
- nowPlaying = GetFilename(returnedData['current_playing'])
- document.title='MPD Player: '+nowPlaying;
- nowPlaying = (1+Number(returnedData['song'])) + '/' + returnedData['playlistlength'] + ' '+nowPlaying;
+ trackName = GetFilename(returnedData['current_playing']);
+ trackNo = returnedData['song'];
+ document.title='MPD Player: '+trackName;
+ nowPlaying = (1+Number(trackNo)) + '/' + returnedData['playlistlength'] + ' '+trackName;
if (returnedData['state']=='stop') {
nowPlaying = '<font color="gray">' + nowPlaying+ '</font>'
}
document.getElementById('repeatstate').innerHTML="<img src=\"images/repeatoff.png\"></a>";
}
document.getElementById('volume_total').innerHTML="<div id=\"volume_actual\" style=\"width:"+returnedData["volume"]+"%\">";
+
+ var items = document.getElementById('items');
+ var table = items.getElementsByClassName('track');
+ var current_track="track_"+trackNo;
+ for (var i = 0; i < table.length; i++) {
+ console.log(table[i].id);
+ if (table[i].id==current_track) {
+ table[i].classList.add("itemActive");
+ } else {
+ table[i].classList.remove("itemActive")
+ }
+ }
+
};
req.open("GET", urlbase+"status", true);
req.send();
-
}
function RefreshPlaylist() {
if (this.readyState != 4 || this.status != 200) return;
var returnedData = JSON.parse(this.responseText);
- var text = "<div id=\"playlist_menu\">\
- <table>\
+ var playlistMenuText = "<table>\
<tr>\
<td><span class=\"button\" onclick=\"EditPlayList()\"><img width=\"20\" src=\"images/songs.png\"></span><td>\
<td><span class=\"button\" onclick=\"LoadPlayList()\"><img width=\"20\" src=\"images/lists.png\"></span><td>\
<td><span class=\"button\" onclick=\"SavePlayList()\"><img width=\"20\" src=\"images/save.png\"></span><td>\
<td><span class=\"button\" onclick=\"return confirm('Clear current playlist, are you sure?') ? PlaylistCommand('clear') : false;\" ><img width=\"20\" src=\"images/removeall.png\"></span><td>\
</tr>\
- </table>\
- </div>\
- <div id=\"items\">\
- <table>\
+ </table>";
+
+ var itemsText="<table>\
<tr id=\"items_heading\">\
- <td></td><td>Title</td><th colspan=\"4\">Controls</th>\
+ <td></td class=\"track_number\"><td class=\"file\">Title</td><td class=\"button\" colspan=\"3\">Controls</td>\
</tr>";
var even = 0;
even = ! even;
- text = text + "<tr id=\""+evText+"\">\
- <td id=\"track_number\">\
- <a name=\""+id+"\"></a></td>\
+ itemsText = itemsText + "<tr id=\"track_"+id+"\" class=\"track "+evText+"\">\
+ <td class=\"track_number\">\
+ <a name=\""+id+"\">"+(Number(id)+1)+"</a></td>\
</td>\
- <td id=\"file\">\
+ <td class=\"file\">\
<span class=\"button\" onclick=\"PlaylistCommand('playitem',"+id+")\">"+name+"</span>\
</td>\
- <td id=\"move\">\
+ <td class=\"move\">\
<span class=\"button\" onclick=\"PlaylistCommand('moveup',"+id+")\"><img width=\"15\" src=\"images/up.png\"></span>\
</td>\
- <td id=\"move\">\
+ <td class=\"move\">\
<span class=\"button\" onclick=\"PlaylistCommand('movedown',"+id+")\"><img width=\"15\" src=\"images/down.png\"></span>\
</td>\
- <td id=\"remove\">\
+ <td class=\"remove\">\
<span class=\"button\" onclick=\"PlaylistCommand('remove',"+id+")\"><img width=\"15\" src=\"images/remove.png\"></span>\
</td>\
</tr>";
}
- text = text + "</table>\
- </div>\
- <div id=\"playlist_menu\">\
- <table>\
- <tr>\
- <td><span class=\"button\" onclick=\"EditPlayList()\"><img width=\"20\" src=\"images/songs.png\"></span><td>\
- <td><span class=\"button\" onclick=\"LoadPlayList()\"><img width=\"20\" src=\"images/lists.png\"></span><td>\
- <td><span class=\"button\" onclick=\"SavePlayList()\"><img width=\"20\" src=\"images/save.png\"></span><td>\
- <td><span class=\"button\" onclick=\"return confirm('Clear current playlist, are you sure?') ? PlaylistCommand('clear') : false;\" ><img width=\"20\" src=\"images/removeall.png\"></span><td>\
- </tr>\
- </table>\
-</div>";
+ itemsText = itemsText + "</table>";
- document.getElementById('playlist').innerHTML=text;
+ document.getElementById('items').innerHTML=itemsText;
+ document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
+ document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
};
req.open("GET", urlbase+"playlist", true);
if (this.readyState != 4 || this.status != 200) return;
var returnedData = JSON.parse(this.responseText);
- var text = "<div id=\"playlist_menu\">\
- <table>\
+ var playlistMenuText = "<table>\
<tr>\
<td><span class=\"button\" onclick=\"RefreshPlaylist()\"><img width=\"20\" src=\"images/playlist.png\"></span><td>\
<td><span class=\"button\" onclick=\"return confirm('Add all to the list, are you sure?') ? PlaylistEditCommand('add','"+EscapeStr(dir)+"') : false;\" ><img width=\"20\" src=\"images/addall.png\"></span><td>\
</tr>\
- </table>\
- </div>\
- <div id=\"items\">\
- <table>\
+ </table>";
+
+ var itemsText= "<table>\
<tr id=\"items_heading\">\
- <td></td><td>Title</td><th colspan=\"2\">Controls</th>\
+ <td></td class=\"track_number\"><td class=\"file\">Title</td><td class=\"button\" colspan=\"2\">Controls</td>\
</tr>";
+ var even = 0;
if (dir) {
var lastSlash=dir.lastIndexOf("/");
if (lastSlash>0) {
} else {
var upperLevel="";
}
- var text = text + "<tr id=\"home\">\
- <td></td>\
- <td><span class=\"button\" onclick=\"EditPlayList('"+upperLevel+"')\"><img width=\"20\" src=\"images/left.png\"></span></td>\
+ even = ! even;
+ var itemsText = itemsText + "<tr class=\"itemOdd\">\
+ <td class=\"track_number\"></td>\
+ <td class=\"file\"><span class=\"button\" onclick=\"EditPlayList('"+upperLevel+"')\">..</span></td>\
<td></td><td></td>";
}
- var even = 0;
var i = 0;
for (var key in returnedData) {
var rec=returnedData[key];
i = i + 1;
even = ! even;
- text = text + "<tr id=\""+evText+"\">\
- <td id=\"track_number\">\
+ itemsText = itemsText + "<tr class=\""+evText+"\">\
+ <td class=\"track_number\">\
<a name=\""+i+"\"></a></td>\
</td>";
if (type == "directory") {
- text = text + "<td id=\"file\">\
+ itemsText = itemsText + "<td class=\"file\">\
<span class=\"button\" onclick=\"EditPlayList('"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\
<span class=\"button\" onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img width=\"15\" src=\"images/plus.png\"></span></td>";
};
if (type == "file") {
- text = text + "<td id=\"file\">\
+ itemsText = itemsText + "<td class=\"file\">\
<span class=\"button\" onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\
<span class=\"button\" onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img width=\"15\" src=\"images/plus.png\"></span></td>";
};
- text = text + "</tr>";
+ itemsText = itemsText + "</tr>";
}
}
- var text = text+"</table></div>\
- <div id=\"playlist_menu\">\
- <table>\
- <tr>\
- <td><span class=\"button\" onclick=\"RefreshPlaylist()\"><img width=\"20\" src=\"images/playlist.png\"></span><td>\
- <td><span class=\"button\" onclick=\"return confirm('Add all to the list, are you sure?') ? PlaylistEditCommand('addall','"+EscapeStr(dir)+"') : false;\" ><img width=\"20\" src=\"images/addall.png\"></span><td>\
- </tr>\
- </table>\
- </div>";
- document.getElementById('playlist').innerHTML=text;
+ var itemsText = itemsText+"</table>";
+ document.getElementById('items').innerHTML=itemsText;
+ document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
+ document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
};
if (!dir) { dir = ''; };
req.onreadystatechange = function () {
if (this.readyState != 4 || this.status != 200) return;
var returnedData = JSON.parse(this.responseText);
- text="<div id=\"playlist_menu\">\
- <table>\
+ playlistMenuText="<table>\
<tr>\
<td><span class=\"button\" onclick=\"RefreshPlaylist()\"><img width=\"20\" src=\"images/playlist.png\"></span><td>\
<td><span class=\"button\" onclick=\"confirm('Clear current playlist, are you sure?') ? PlaylistCommandRefStatus('clear') : false;\" ><img width=\"20\" src=\"images/removeall.png\"></span><td>\
</tr>\
- </table>\
- </div>\
- <div id=\"items\">\
- <table>\
+ </table>";
+ itemsText="<table>\
<tr id=\"items_heading\">\
- <td></td><td>Name</td><td>Controls</td>\
+ <td class=\"track_number\"></td><td class=\"file\">Name</td><td class=\"button\">Controls</td>\
</tr>";
var even = 0;
even = ! even;
- text = text + "<tr id=\""+evText+"\">\
- <td id=\"track_number\"><a name=\"0\"></a></td>\
- <td id=\"file\"><span class=\"button\" onclick=\"PlaylistEditCommandRefFull('load','"+EscapeStr(name)+"')\">"+name+"</td>\
- <td id=\"controls\"><span class=\"button\" onclick=\"confirm('Delete playlist "+name+", are you sure?') ? DelPlayList('"+EscapeStr(name)+"') : false;\"><img width=\"20\" src=\"images/minus.png\"></span></td>\
+ itemsText = itemsText + "<tr class=\""+evText+"\">\
+ <td class=\"track_number\"><a name=\"0\"></a></td>\
+ <td class=\"file\"><span class=\"button\" onclick=\"PlaylistEditCommandRefFull('load','"+EscapeStr(name)+"')\">"+name+"</td>\
+ <td class=\"controls\"><span class=\"button\" onclick=\"confirm('Delete playlist "+name+", are you sure?') ? DelPlayList('"+EscapeStr(name)+"') : false;\"><img width=\"20\" src=\"images/minus.png\"></span></td>\
</tr>";
}
- text=text+"</table></div><div id=\"playlist_menu\">\
- <table>\
- <tr>\
- <td><span class=\"button\" onclick=\"RefreshPlaylist()\"><img width=\"20\" src=\"images/playlist.png\"></span><td>\
- <td><span class=\"button\" onclick=\"confirm('Clear current playlist, are you sure?') ? PlaylistCommandRefStatus('clear') : false;\" ><img width=\"20\" src=\"images/removeall.png\"></span><td>\
- </tr>\
- </table>\
- </div>";
-
- document.getElementById('playlist').innerHTML=text;
+ itemsText=itemsText+"</table>";
+ document.getElementById('items').innerHTML=itemsText;
+ document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
+ document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
};
req.open("GET", urlbase+"lists|load", true);
req.onreadystatechange = function () {
if (this.readyState != 4 || this.status != 200) return;
- RefreshPageStatus();
LoadPlayList();
+ RefreshPageStatus();
};
req.open("GET", urlbase+"lists|delete|"+item, true);
}
function RefreshPageContent() {
-
- RefreshPageStatus();
RefreshPlaylist();
-
+ RefreshPageStatus();
}
function Command(cmd) {
}
-setInterval(RefreshPageStatus, 10000);
+function subscribe_status() {
+ var xhr = new XMLHttpRequest();
+
+ xhr.onreadystatechange = function() {
+ if (this.readyState != 4) return;
+ if (this.status == 200) {
+ RefreshPageStatus()
+ setTimeout(subscribe_status,1000)
+ } else {
+ setTimeout(subscribe_status,15000)
+ }
+ }
+ xhr.open("GET", urlbase+"idle", true);
+ xhr.send();
+}
+
+setTimeout(subscribe_status,5000)
-/*
-#525356
-*/
-
-
-
-* {
- margin:0;
-}
-
body {
+ margin: 0px;
text-align: center;
font-family: arial,sans-serif;
- margin-top: 15px;
- margin-bottom: 15px;
- color: #AEAEAE;
+ color: Snow;
}
a {
text-decoration: none;
- color: #AEAEAE;
+ color: White;
}
table
cursor: pointer;
}
-.trackno
-{
- text-align: right;
- vertical-align: top;
- padding: 0px 0px 5px 0px;
-}
-
-#heading_tbl {
- width: 400px
-}
-
#frame {
text-align: left;
- border: 1px solid #000;
- width: 400px;
- background: url(../images/bg.png) no-repeat #251616;
- margin: 0 auto;
+ border: 1px solid Black;
+ background: DarkSlateGray;
+ margin: 0;
}
-
#nowplaying_heading {
font-size: 1.3em;
- font-wieght: bold;
- height: 30px;
- background: url(../images/control_bg.png) repeat-x;
- border-bottom: 1px solid #525356;
+ font-weight: bold;
+ padding: 5px;
+ background: linear-gradient(DarkSlateGray,Black);
+ border-bottom: 1px solid Black;
+ border-top: 1px solid Black;
+}
+
+#heading_tbl {
+ width: 100%;
}
#nowplaying_content {
- margin: 10px 5px 10px 5px;
+ margin: 10px 10% 10px 10%;
text-align: center;
- border: 1px solid #525356;
- width: 380px;
- height: 60px;
+ border: 1px solid LightGray;
+ height: 3em;
padding: 10px 0px 5px 0px;
- background: url(../images/playing_bg.png);
+ background: SaddleBrown;
font-weight: bold;
- color: #fff;
+ color: White;
}
#control_buttons {
text-align: center;
- width: 390px;
margin: 10px 5px 10px 5px;
}
#control_buttons table {
margin-left: auto;
- margin-right: auto;
+ margin-right: auto;
}
#control_volume {
text-align: center;
- width: 390px;
margin: 10px 5px 10px 5px;
}
#control_volume table {
margin-left: auto;
- margin-right: auto;
+ margin-right: auto;
}
-#playlist_menu {
- font-wieght: bold;
- height: 24px;
- background: url(../images/control_bg.png) repeat-x;
- border-top: 2px solid #525356;
- margin-top: 5px;
- margin-bottom: 5px;
+.playlist_menu {
+ font-weight: bold;
+ height: 24px;
+ padding: 5px;
+ background: linear-gradient(DarkSlateGray,Black);
+ border-bottom: 1px solid Black;
+ border-top: 1px solid Black;
}
+.home {
+ text-align: left;
+ font-size: 1.0em;
+ font-weight: bold;
+ background: linear-gradient(DarkSlateGray,Black);
+ border-bottom: 2px solid Black;
+ border-top: 2px solid DarkSlateGray;
+}
+
+
#items_heading {
text-align: center;
+ width: 100%;
font-size: 1.0em;
font-weight:bold;
- border-bottom: 1px solid #525356;
- border-top: 1px solid #525356;
- background-color: #333;
-}
-
-#home {
- text-align: left;
- font-size: 1.0em;
- font-weight: bold;
- border-bottom: 3px solid #525356;
- background-color: #251616;
+ border-bottom: 1px solid DimGray;
+ border-top: 1px solid DimGray;
+ background: DarkSlateGray;
}
#items {
font-size: 0.9em;
text-align: center;
- min-height: 400px;
- max-height: 600px;
- background: url(../images/playing_bg.png);
overflow-y: scroll;
}
#items table {
- width: 380px;
- margin: 0px 5px 0px 5px;
- border: 1px solid #525356;
+ border: 1px solid DimGray;
}
-#file {
+.file {
text-align: left;
width: 100%;
-
}
-#itemEven{
- background-color: #251616;
-
-}
-
-#itemOdd{
- background-color: #333;
+.itemEven{
+ background-color: DarkSlateGray;
}
-#itemActive {
- background: url(../images/playing_bg.png);
- color: #fff;
+.itemOdd{
+ background-color: DimGray;
}
-#itemActive a {
- color: #fff;
+.itemActive {
+ background: LightGray;
+ color: DarkSlateGray;
}
-
-#move img {
- margin: 1px 1px 1px 1px;
+.itemActive a {
+ color: DarkSlateGray;
}
-#remove img {
- margin: 1px 1px 1px 1px;
+.track_number {
+ text-align: right;
}
-
#volume_total {
- width: 100px;
- border: 1px solid #525356;
- height: 5px;
+ margin: 10px;
+ width: 200px;
+ border: 1px solid LightGray;
+ height: 0.6em;
}
#volume_actual {
- background-color: #d9600c;
- height:5px;
+ background-color: DarkOrange;
+ height: 0.6em;
}
-
#!/usr/bin/lua
+require "uci"
+require("socket")
+json=require("json")
+
function url_decode(str)
if not str then return nil end
str = string.gsub (str, "+", " ")
return res
end
-require "uci"
-require("socket")
-
function mpd_new(settings)
local client = {}
if settings == nil then settings = {} end
return client
end
-
function mpd_send(mpd,action,raw)
local command = string.format("%s\n", action)
return values
end
-
-json=require("json")
-
x = uci.cursor()
+
settings = {}
settings['host'] = x.get("mpd","server","host") or "localhost"
settings['port'] = x.get("mpd","server","port") or 6600
+settings['timeout'] = x.get("mpd","server","timeout") or 1
+
+volstep = x.get("mpd","control","volume_step") or 3
+
password = x.get("mpd","server","password")
if password then
settings["password"] = password
command = url_decode(os.getenv('QUERY_STRING'))
if not command or command=="" then
- command="status"
+ command="idle"
end
if command=="play" or command=="pause" or command=="stop" or command=="previous" or command=="next" then
+
res=mpd_send(m,command)
+
+elseif command=="idle" then
+
+ m.timeout=30
+ res=mpd_send(m,command)
+
elseif command=="vold" then
+
status=mpd_send(m,"status")
volume=tonumber(status["volume"])
- res=mpd_send(m,"setvol "..(volume-3))
+ res=mpd_send(m,"setvol "..(volume-volstep))
+
elseif command=="volu" then
+
status=mpd_send(m,"status")
volume=tonumber(status["volume"])
- res=mpd_send(m,"setvol "..(volume+3))
+ res=mpd_send(m,"setvol "..(volume+volstep))
+
elseif command=="status" then
+
res=mpd_send(m,"status")
song=res["song"]
playlist=mpd_send(m,"playlist",1)
pl=process_playlist(playlist)
+
if song then
res['current_playing']=pl[song]['name']
else
res['current_playing']="No songs selected"
end
+
elseif command=="playlist" then
+
playlist=mpd_send(m,"playlist",1)
res=process_playlist(playlist)
+
elseif command=="repeat" then
+
status=mpd_send(m,"status")
rep=1-status["repeat"]
res=mpd_send(m,"repeat "..rep)
+
elseif string.starts(command,"cpl") then
+
cmd=split(command,"|")
id=cmd[3]
command=cmd[2]
+
if command=="playitem" then
command="play "..id
res=mpd_send(m,command)
end
+
if command=="clear" then
res=mpd_send(m,"clear")
end
+
if command=="remove" then
command="delete "..id
res=mpd_send(m,command)
end
+
if command=="moveup" then
command="swap "..id.." "..(id-1)
res=mpd_send(m,command)
end
+
if command=="movedown" then
command="swap "..id.." "..(id+1)
res=mpd_send(m,command)
end
+
elseif string.starts(command,"lists") then
+
cmd=split(command,"|")
command=cmd[2]
+
if command=="load" then
if not cmd[3] then
lists=mpd_send(m,"listplaylists",1)
res=mpd_send(m,"load "..cmd[3],1)
end
end
+
if command=="save" and cmd[3] then
res=mpd_send(m,"save "..cmd[3],1)
end
+
if command=="delete" and cmd[3] then
res=mpd_send(m,"rm "..cmd[3],1)
end
+
if command=="edit" then
if cmd[3] then
dir=mpd_send(m,"lsinfo \""..cmd[3].."\"",1)
end
res=process_directory(dir)
end
+
if command=="add" then
res={}
if cmd[3] then
res=mpd_send(m,"add \""..cmd[3].."\"")
end
end
+
end
if not res then