1 urlbase="/cgi-bin/mpd.cgi?"
6 function GetFilename(url)
9 return url.split('/').pop().split('#')[0].split('?')[0];
12 function EscapeStr(str) {
13 res = str.replace(/'/g,"\\'");
20 e = d.documentElement,
21 g = d.getElementsByTagName('body')[0],
22 body_h = g.clientHeight,
23 window_h = w.innerHeight|| e.clientHeight|| g.clientHeight,
24 items = d.getElementById('items'),
25 current_h = items.clientHeight,
26 new_h=(window_h-body_h)+current_h;
27 if (new_h>minScrollHeight) {
28 items.style.height=new_h+"px";
32 function toHHMMSS(seconds) {
33 var hours = Math.floor(seconds / 3600);
34 seconds -= hours*3600;
35 var minutes = Math.floor(seconds / 60);
36 seconds -= minutes*60;
38 if (hours < 10) {hours = "0"+hours;}
39 if (minutes < 10) {minutes = "0"+minutes;}
40 if (seconds < 10) {seconds = "0"+seconds;}
42 return minutes+':'+seconds;
44 return hours+':'+minutes+':'+seconds;
48 function RefreshTime() {
50 currentTime = toHHMMSS(currentSeconds)
52 trackTime = toHHMMSS(trackSeconds)
53 nowPlayingTime = currentTime+"/"+trackTime
55 nowPlayingTime = currentTime
58 nowPlayingTime = "-:--/-:--"
60 document.getElementById('nowplaying_tracklen').innerHTML=nowPlayingTime;
63 function PeriodicRefreshTime() {
64 if (currentState == "play") {
66 delta = (nowTime - updateTime)/1000
67 currentSeconds = updateSeconds + Math.round(delta)
68 if (trackSeconds && (currentSeconds > trackSeconds)) {
69 currentSeconds = trackSeconds
75 function RefreshPageStatus() {
77 var req = new XMLHttpRequest();
79 req.onreadystatechange = function () {
80 if (this.readyState != 4 || this.status != 200) return;
81 var returnedData = JSON.parse(this.responseText);
82 trackName = GetFilename(returnedData['current_playing']);
84 var trackName=decodeURI(trackName).replace(/%2C/g,",")
87 console.log(trackName)
89 trackNo = returnedData['song'];
90 trackId = returnedData['songid']
91 currentState = returnedData['state'];
92 document.title='MPD Player: '+trackName;
94 var nowPlayingTrackNo=String(1+Number(trackNo))
96 var nowPlayingTrackNo="--"
98 nowPlayingTrack = nowPlayingTrackNo + '/' + returnedData['playlistlength'];
99 nowPlayingName = trackName;
100 playingTime = returnedData['time']
102 var splits = playingTime.split(":")
103 updateTime = Date.now()
104 currentSeconds = Number(splits[0])
105 updateSeconds = currentSeconds
106 trackSeconds = Number(splits[1])
108 currentSeconds = null
110 if (currentState=='stop') {
111 nowPlayingName = '<font color="gray">' + nowPlayingName+ '</font>'
113 document.getElementById('nowplaying_trackno').innerHTML=nowPlayingTrack;
114 document.getElementById('nowplaying_trackname').innerHTML=nowPlayingName;
116 if (currentState=="play") {
117 document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('pause')\"><img class=\"button\" title=\"Pause\" src=\"images/pause.svg\"></span>";
119 document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('play')\"><img class=\"button\" title=\"Play\" src=\"images/play-button.svg\"></span>";
121 if (currentState=="stop") {
122 document.getElementById('stopbutton').innerHTML="<span><img class=\"button\" src=\"images/stopoff.svg\"></span>";
124 document.getElementById('stopbutton').innerHTML="<span onclick=\"Command('stop')\"><img class=\"button\" title=\"Stop\" src=\"images/stop.svg\"></span>";
126 if (returnedData["repeat"]=="1") {
127 document.getElementById('repeatstate').innerHTML="<img class=\"button\" title=\"Replay is on\" src=\"images/replay.svg\"></a>";
129 document.getElementById('repeatstate').innerHTML="<img class=\"button\" title=\"Replay is off\" src=\"images/replayoff.svg\"></a>";
131 document.getElementById('volume_total').innerHTML="<div id=\"volume_actual\" style=\"width:"+returnedData["volume"]+"%\">";
133 var items = document.getElementById('items');
134 var table = items.getElementsByClassName('track');
135 var current_track="track_"+trackId;
136 for (var i = 0; i < table.length; i++) {
137 if (table[i].id==current_track) {
138 table[i].classList.add("itemActive");
140 table[i].classList.remove("itemActive")
146 req.open("GET", urlbase+"status", true);
151 function RefreshPlaylist() {
153 var req = new XMLHttpRequest();
155 req.onreadystatechange = function () {
156 if (this.readyState != 4 || this.status != 200) return;
157 var returnedData = JSON.parse(this.responseText);
159 var playlistMenuText = "<table>\
161 <td><span onclick=\"EditPlayList()\"><img class=\"medium-button\" title=\"Files\" src=\"images/folder.svg\"></span><td>\
162 <td><span onclick=\"LoadPlayList()\"><img class=\"medium-button\" title=\"Lists\" src=\"images/list.svg\"></span><td>\
163 <td><span onclick=\"SavePlayList()\"><img class=\"medium-button\" title=\"Save current list\" src=\"images/download.svg\"></span><td>\
164 <td><span onclick=\"return confirm('Clear current playlist, are you sure?') ? PlaylistCommand('clear') : false;\" ><img class=\"medium-button\" title=\"Clear current list\" src=\"images/cancel.svg\"></span><td>\
168 var itemsText="<table>\
169 <tr id=\"items_heading\">\
170 <td></td class=\"track_number\"><td class=\"file\">Title</td><td class=\"medium-button\" colspan=\"3\">Controls</td>\
174 for (var key in returnedData) {
175 var rec=returnedData[key];
176 var name=GetFilename(rec["title"]);
178 var name=decodeURI(name).replace(/%2C/g,",")
193 itemsText = itemsText + "<tr id=\"track_"+id+"\" class=\"track "+evText+"\">\
194 <td class=\"track_number\">\
195 <a name=\""+id+"\">"+(Number(key)+1)+"</a></td>\
198 <span class=\"link\" onclick=\"PlaylistCommand('playitem',"+id+")\">"+name+"</span>\
201 <span onclick=\"PlaylistCommand('moveup',"+id+")\"><img class=\"small-button\" title=\"Move up\" src=\"images/up-arrow.svg\"></span>\
204 <span onclick=\"PlaylistCommand('movedown',"+id+")\"><img class=\"small-button\" title=\"Move down\" src=\"images/down-arrow.svg\"></span>\
206 <td class=\"remove\">\
207 <span onclick=\"PlaylistCommand('remove',"+id+")\"><img class=\"small-button\" title=\"Remove\" src=\"images/cancel.svg\"></span>\
212 itemsText = itemsText + "</table>";
214 document.getElementById('items').innerHTML=itemsText;
215 document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
216 document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
219 req.open("GET", urlbase+"playlist", true);
224 function EditPlayList(dir) {
226 var req = new XMLHttpRequest();
228 req.onreadystatechange = function () {
229 if (this.readyState != 4 || this.status != 200) return;
230 var returnedData = JSON.parse(this.responseText);
232 var playlistMenuText = "<table>\
234 <td><span onclick=\"RefreshPageContent()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\
235 <td><span onclick=\"return confirm('Add all to the list, are you sure?') ? PlaylistEditCommand('add','"+EscapeStr(dir)+"') : false;\" ><img class=\"medium-button\" title=\"Add all\" src=\"images/plus.svg\"></span><td>\
239 var itemsText= "<table>\
240 <tr id=\"items_heading\">\
241 <td></td class=\"track_number\"><td class=\"file\">Title</td><td colspan=\"2\">Controls</td>\
246 var lastSlash=dir.lastIndexOf("/");
248 var upperLevel=dir.slice(0,lastSlash);
253 var itemsText = itemsText + "<tr class=\"itemOdd\">\
254 <td class=\"track_number\"></td>\
255 <td class=\"file\"><span class=\"link\" onclick=\"EditPlayList('"+upperLevel+"')\">..</span></td>\
260 for (var key in returnedData) {
261 var rec=returnedData[key];
262 var type=rec["type"];
263 var name=rec["name"];
264 var lastSlash=name.lastIndexOf("/");
266 var tailName=name.slice(lastSlash+1);
271 var tailName=decodeURI(tailName).replace(/%2C/g,",")
274 console.log(tailName)
277 if (type == "directory" || type == "file") {
287 itemsText = itemsText + "<tr class=\""+evText+"\">\
288 <td class=\"track_number\">\
289 <a name=\""+i+"\"></a></td>\
292 if (type == "directory") {
293 itemsText = itemsText + "<td class=\"file\">\
294 <span class=\"link\" onclick=\"EditPlayList('"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\
295 <span onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img class=\"small-button\" title=\"Add\" src=\"images/plus.svg\"></span></td>";
298 if (type == "file") {
299 itemsText = itemsText + "<td class=\"file\">\
300 <span class=\"link\" onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\
301 <span onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img class=\"small-button\" title=\"Add\" src=\"images/plus.svg\"></span></td>";
304 itemsText = itemsText + "</tr>";
310 var itemsText = itemsText+"</table>";
311 document.getElementById('items').innerHTML=itemsText;
312 document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
313 document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
316 if (!dir) { dir = ''; };
318 req.open("GET", urlbase+"lists|edit|"+dir, true);
323 function LoadPlayList() {
325 var req = new XMLHttpRequest();
327 req.onreadystatechange = function () {
328 if (this.readyState != 4 || this.status != 200) return;
329 var returnedData = JSON.parse(this.responseText);
330 playlistMenuText="<table>\
332 <td><span onclick=\"RefreshPageContent()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\
333 <td><span onclick=\"confirm('Clear current playlist, are you sure?') ? PlaylistCommandRefStatus('clear') : false;\" ><img class=\"medium-button\" title=\"Clear all\" src=\"images/cancel.svg\"></span><td>\
337 <tr id=\"items_heading\">\
338 <td class=\"track_number\"></td><td class=\"file\">Name</td><td>Controls</td>\
342 for (var key in returnedData) {
343 var name=returnedData[key];
353 itemsText = itemsText + "<tr class=\""+evText+"\">\
354 <td class=\"track_number\"><a name=\"0\"></a></td>\
355 <td class=\"file\"><span class=\"link\" onclick=\"PlaylistEditCommandRefFull('load','"+EscapeStr(name)+"')\">"+name+"</td>\
356 <td class=\"controls\"><span onclick=\"confirm('Delete playlist "+name+", are you sure?') ? DelPlayList('"+EscapeStr(name)+"') : false;\"><img class=\"small-button\" title=\"Delete\" src=\"images/minus.svg\"></span></td>\
360 itemsText=itemsText+"</table>";
361 document.getElementById('items').innerHTML=itemsText;
362 document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
363 document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
366 req.open("GET", urlbase+"lists|load", true);
371 function SavePlayList() {
373 var name=window.prompt('List name','');
375 var req = new XMLHttpRequest();
377 req.onreadystatechange = function () {
378 if (this.readyState != 4 || this.status != 200) return;
379 if (this.responseText != 'OK') {
380 window.alert(this.responseText);
384 req.open("GET", urlbase+"lists|save|"+name, true);
389 function DelPlayList(item) {
391 var req = new XMLHttpRequest();
393 req.onreadystatechange = function () {
394 if (this.readyState != 4 || this.status != 200) return;
399 req.open("GET", urlbase+"lists|delete|"+item, true);
404 function RefreshPageContent() {
409 function Command(cmd) {
411 var req = new XMLHttpRequest();
413 req.onreadystatechange = function () {
414 if (this.readyState != 4 || this.status != 200) return;
418 req.open("GET", urlbase+cmd, true);
423 function PlaylistCommand(cmd,item) {
425 var req = new XMLHttpRequest();
427 req.onreadystatechange = function () {
428 if (this.readyState != 4 || this.status != 200) return;
429 RefreshPageContent();
432 req.open("GET", urlbase+"cpl|"+cmd+"|"+item, true);
437 function PlaylistCommandRefStatus(cmd,item) {
439 var req = new XMLHttpRequest();
441 req.onreadystatechange = function () {
442 if (this.readyState != 4 || this.status != 200) return;
446 req.open("GET", urlbase+"cpl|"+cmd+"|"+item, true);
451 function PlaylistEditCommand(cmd,item) {
453 var req = new XMLHttpRequest();
455 req.onreadystatechange = function () {
456 if (this.readyState != 4 || this.status != 200) return;
460 req.open("GET", urlbase+"lists|"+cmd+"|"+item, true);
465 function PlaylistEditCommandRefFull(cmd,item) {
467 var req = new XMLHttpRequest();
469 req.onreadystatechange = function () {
470 if (this.readyState != 4 || this.status != 200) return;
471 RefreshPageContent();
474 req.open("GET", urlbase+"lists|"+cmd+"|"+item, true);
479 function subscribe_status() {
480 var xhr = new XMLHttpRequest();
482 xhr.onreadystatechange = function() {
483 if (this.readyState != 4) return;
484 if (this.status == 200) {
486 setTimeout(subscribe_status,1000)
488 setTimeout(subscribe_status,15000)
491 xhr.open("GET", urlbase+"idle", true);
495 setTimeout(subscribe_status,5000)
496 setInterval(PeriodicRefreshTime, 1000);