Веб-интерфейс к MPD.
authorRoman Bazalevsky <rvb@rvb.name>
Wed, 28 Sep 2016 16:50:21 +0000 (19:50 +0300)
committerRoman Bazalevsky <rvb@rvb.name>
Wed, 28 Sep 2016 16:50:21 +0000 (19:50 +0300)
Серверная часть - PHP + libmpc.

Клиентская часть - AJAX без библиотек.

50 files changed:
ajax/command.php [new file with mode: 0644]
ajax/editplaylist.php [new file with mode: 0644]
ajax/mpd.js [new file with mode: 0644]
ajax/mpd.php [new file with mode: 0644]
ajax/playerstate.php [new file with mode: 0644]
ajax/playlist-command.php [new file with mode: 0644]
ajax/playlist.php [new file with mode: 0644]
ajax/repeatstate.php [new file with mode: 0644]
ajax/trackinfo.php [new file with mode: 0644]
ajax/volume.php [new file with mode: 0644]
config/config.php [new file with mode: 0644]
css/general.css [new file with mode: 0644]
images/addall.png [new file with mode: 0755]
images/addselected.png [new file with mode: 0755]
images/bg.png [new file with mode: 0755]
images/control_bg.png [new file with mode: 0755]
images/down.png [new file with mode: 0755]
images/highlight.png [new file with mode: 0755]
images/left.png [new file with mode: 0755]
images/minus.png [new file with mode: 0755]
images/next.png [new file with mode: 0755]
images/pause.png [new file with mode: 0755]
images/play.png [new file with mode: 0755]
images/playing_bg.png [new file with mode: 0755]
images/playlist.png [new file with mode: 0755]
images/plus.png [new file with mode: 0755]
images/prev.png [new file with mode: 0755]
images/previous.png [new file with mode: 0755]
images/remall.png [new file with mode: 0755]
images/remove.png [new file with mode: 0755]
images/removeall.png [new file with mode: 0755]
images/removeselected.png [new file with mode: 0755]
images/remselected.png [new file with mode: 0755]
images/repeatoff.png [new file with mode: 0755]
images/repeaton.png [new file with mode: 0755]
images/right.png [new file with mode: 0755]
images/songs.png [new file with mode: 0755]
images/stop.png [new file with mode: 0755]
images/up.png [new file with mode: 0755]
images/update.png [new file with mode: 0755]
index.php [new file with mode: 0644]
model/player.php [new file with mode: 0644]
model/tracklist.php [new file with mode: 0644]
system/helper.php [new file with mode: 0644]
system/mpd_class.php [new file with mode: 0644]
view/default/tmpl/default.php [new file with mode: 0644]
view/default/tmpl/playlistmenu.php [new file with mode: 0644]
view/default/view.php [new file with mode: 0644]
view/player/tmpl/default.php [new file with mode: 0644]
view/player/view.php [new file with mode: 0644]

diff --git a/ajax/command.php b/ajax/command.php
new file mode 100644 (file)
index 0000000..25567a4
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$task=$_REQUEST['task'];
+
+include('mpd.php');
+include('../model/player.php')
+
+?>
diff --git a/ajax/editplaylist.php b/ajax/editplaylist.php
new file mode 100644 (file)
index 0000000..b7e8bf4
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+function escapePhpString($target) {
+    $replacements = array(
+            "'" => '\\\'',
+            "\\" => '\\\\',
+            "\r\n" => "\\r\\n",
+            "\n" => "\\n"
+    );
+    return strtr($target, $replacements);
+}
+
+include('mpd.php');
+$dir = $_REQUEST['dir'];
+
+?>
+  <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="PlaylistEditCommand('addall','<?php echo escapePhpString($dir);?>')" ><img width="20" src="images/addall.png"></span><td>
+                       <td><span class="button" onclick="PlaylistEditItemsCommand('addselected','<?php echo escapePhpString($dir);?>')"><img width="20" src="images/addselected.png"></span><td>
+               </tr>
+       </table>
+  </div>
+  <div id="items">
+    <table>
+    <tr id="items_heading">
+       <td></td><td>Title</td><th colspan="2">Control</th>
+    </tr>
+    <?php
+      $dirs=$mpd->GetDir($dir);
+    ?>
+      <tr id="home"><td></td><td><span class="button" onclick="EditPlayList('<?php echo escapePhpString(cut_upperDir($dir));?>')"><img width="20" src="images/left.png"></span></td><td></td><td></td>
+
+     <?php for($i=0;$i<count($dirs);$i++) {?>
+      <tr id="item<?php if($i%2==0) { echo "Even";}else{echo "Odd";}?>">
+         <td id="track_number"> <a name="<?php echo $i;?>"></a></td>
+         <?php if($dirs[$i]['type']=="directory") {?>
+               <td id="file"><span class="button" onclick="EditPlayList('<?php echo escapePhpString($dirs[$i]['name']);?>')"><?php
+                       if ($dirs[$i]['name']==$dirs[$i]['title']) {
+                               echo htmlentities(cut_lastDir($dirs[$i]['name']));
+                       } else {
+                               echo htmlentities($dirs[$i]['title']);
+                       }
+               ?></span></td><td><span class="button" onclick="PlaylistEditCommand('adddir','<?php echo escapePhpString($dirs[$i]['name']);?>')"><img width="15" src="images/plus.png"></span></td>
+         <?php } else {?>
+               <td id="file"><?php
+                       if ($dirs[$i]['name']==$dirs[$i]['title']) { 
+                               echo htmlentities(cut_file($dirs[$i]['name']));
+                       } else {
+                               echo htmlentities($dirs[$i]['title']);
+                       }
+               ?></td><td><span class="button" onclick="PlaylistEditCommand('addfile','<?php echo escapePhpString($dirs[$i]['name']);?>')"><img width="15" src="images/plus.png"></span></td>
+         <?php } ?>
+         <td id="checkbox"><input type="checkbox" name="itemlist[]" value="<?php echo $i;?>"></td>
+      </tr>
+    <?php
+      }
+    ?>
+    </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="PlaylistEditCommand('addall','<?php echo escapePhpString($dir);?>')" ><img width="20" src="images/addall.png"></span><td>
+                       <td><span class="button" onclick="PlaylistEditItemsCommand('addselected','<?php echo escapePhpString($dir);?>')"><img width="20" src="images/addselected.png"></span><td>
+               </tr>
+        </table>
+  </div>
diff --git a/ajax/mpd.js b/ajax/mpd.js
new file mode 100644 (file)
index 0000000..5d64a92
--- /dev/null
@@ -0,0 +1,198 @@
+
+function RefreshNowPlaying() {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+  if (this.readyState != 4 || this.status != 200) return;
+  document.getElementById('nowplaying_content').innerHTML=this.responseText;
+  document.title='MPD Player: '+this.responseText;
+};
+
+req.open("GET", "ajax/trackinfo.php", true);
+req.send();
+
+}
+
+function RefreshPlayerState() {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+  if (this.readyState != 4 || this.status != 200) return;
+  if (this.responseText=="play") {
+    document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('pause')\"><img class=\"button\" src=\"images/pause.png\"></span>";
+  } else {
+    document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('play')\"><img class=\"button\" src=\"images/play.png\"></span>";
+  }
+};
+
+req.open("GET", "ajax/playerstate.php", true);
+req.send();
+
+}
+
+function RefreshRepeatState() {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+  if (this.readyState != 4 || this.status != 200) return;
+  if (this.responseText=="1") {
+    document.getElementById('repeatstate').innerHTML="<img src=\"images/repeaton.png\"></a>";
+  } else {
+    document.getElementById('repeatstate').innerHTML="<img src=\"images/repeatoff.png\"></a>";
+  }
+};
+
+req.open("GET", "ajax/repeatstate.php", true);
+req.send();
+
+}
+
+function RefreshVolume() {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+  if (this.readyState != 4 || this.status != 200) return;
+  document.getElementById('volume_total').innerHTML="<div id=\"volume_actual\" style=\"width:"+this.responseText+"%\">";
+};
+
+req.open("GET", "ajax/volume.php", true);
+req.send();
+
+}
+
+function RefreshPageStatus() {
+
+  RefreshNowPlaying();
+  RefreshPlayerState();
+  RefreshRepeatState();
+  RefreshVolume();
+
+}
+
+function RefreshPlaylist() {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+  if (this.readyState != 4 || this.status != 200) return;
+  document.getElementById('playlist').innerHTML=this.responseText;
+};
+
+req.open("GET", "ajax/playlist.php", true);
+req.send();
+
+}
+
+function EditPlayList(dir) {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+  if (this.readyState != 4 || this.status != 200) return;
+  document.getElementById('playlist').innerHTML=this.responseText;
+};
+
+if (!dir) { dir = ''; };
+
+req.open("GET", "ajax/editplaylist.php?dir="+dir, true);
+req.send();
+
+}
+
+function RefreshPageContent() {
+
+  RefreshPageStatus();
+  RefreshPlaylist();
+
+}
+
+function Command(cmd) {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+  if (this.readyState != 4 || this.status != 200) return;
+  RefreshPageStatus();
+};
+
+req.open("GET", "ajax/command.php?task="+cmd, true);
+req.send();
+
+}
+
+function PlaylistCommand(cmd,item) {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+  if (this.readyState != 4 || this.status != 200) return;
+  RefreshPageContent();
+};
+
+req.open("GET", "ajax/playlist-command.php?item="+item+"&task="+cmd, true);
+req.send();
+
+}
+
+function PlaylistEditCommand(cmd,item) {
+
+var req = new XMLHttpRequest();
+
+req.open("GET", "ajax/playlist-command.php?item="+item+"&task="+cmd, true);
+req.send();
+
+}
+
+
+function PlaylistItemsCommand(cmd) {
+
+var req = new XMLHttpRequest();
+
+var selected = [].filter.call(document.getElementsByName('itemlist[]'), function(c) {
+  return c.checked;
+}).map(function(c) {
+  return c.value;
+});
+  
+req.onreadystatechange = function () {
+  if (this.readyState != 4 || this.status != 200) return;
+  RefreshPageContent();
+};
+
+params=selected.map(function(el) {
+        //Map each field into a name=value string, make sure to properly escape!
+        return 'itemlist[]=' + encodeURIComponent(el);
+    }).join('&');
+
+req.open("POST", "ajax/playlist-command.php?task="+cmd, true);
+req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+req.send(params);
+
+}
+
+function PlaylistEditItemsCommand(cmd,dir) {
+
+var req = new XMLHttpRequest();
+
+var selected = [].filter.call(document.getElementsByName('itemlist[]'), function(c) {
+  return c.checked;
+}).map(function(c) {
+  return c.value;
+});
+  
+params=selected.map(function(el) {
+        //Map each field into a name=value string, make sure to properly escape!
+        return 'itemlist[]=' + encodeURIComponent(el);
+    }).join('&');
+
+req.open("POST", "ajax/playlist-command.php?dir="+dir+"&task="+cmd, true);
+req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+req.send(params);
+
+}
+
+// setInterval(RefreshPageStatus, 5000);
diff --git a/ajax/mpd.php b/ajax/mpd.php
new file mode 100644 (file)
index 0000000..9f435e2
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+
+include('../config/config.php');
+include('../system/mpd_class.php');
+include('../system/helper.php');
+
+$mpd = new mpd($mpd_host,$mpd_port,$mpd_password);
+
+if($mpd->connected != 1){
+        echo "Not Connected to Server";
+        exit(1);
+}
+
+?>
diff --git a/ajax/playerstate.php b/ajax/playerstate.php
new file mode 100644 (file)
index 0000000..c4735a3
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+include('mpd.php');
+
+echo $mpd->state;
+
+?>
diff --git a/ajax/playlist-command.php b/ajax/playlist-command.php
new file mode 100644 (file)
index 0000000..19344da
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+$task=$_REQUEST['task'];
+$item=$_REQUEST['item'];
+
+include('mpd.php');
+include('../model/tracklist.php')
+
+?>
diff --git a/ajax/playlist.php b/ajax/playlist.php
new file mode 100644 (file)
index 0000000..78fe8ad
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+include('mpd.php');
+
+$cur_track= $mpd->current_track_id;
+$playlist= $mpd->playlist;
+?>
+<div id="playlist">
+<?php include("../view/default/tmpl/playlistmenu.php"); ?>
+<div id="items">
+    <table>
+    <tr id="items_heading">
+       <td></td><td>Title</td><th colspan="4">Controls</th>
+    </tr>
+    <?php
+      for($i=0;$i<count($playlist);$i++) {
+    ?>
+      <tr id="item<?php if($cur_track == $i){echo "Active";} elseif($i%2==0) { echo "Even";}else{echo "Odd";}?>">
+         <td id="track_number">
+               <a name="<?php echo $i;?>"></a></td>
+          </td>
+         <td id="file">
+                 <span class="button" onclick="PlaylistCommand('playitem',<?php echo $i;?>)"><?php
+                       if ($playlist[$i]['name']==$playlist[$i]['title']) { 
+                               echo htmlentities(cut_file($playlist[$i]['name']));
+                       } else {
+                               echo htmlentities($playlist[$i]['title']);
+                       }
+               ?></span>
+         </td>
+         <td id="move">
+                <span class="button" onclick="PlaylistCommand('moveup',<?php echo $i;?>)"><img width="15" src="images/up.png"></span>
+          </td>
+         <td id="move">
+                <span class="button" onclick="PlaylistCommand('movedown',<?php echo $i;?>)"><img width="15" src="images/down.png"></span>
+          </td>
+         <td id="remove">
+                <span class="button" onclick="PlaylistCommand('remove',<?php echo $i;?>)"><img width="15" src="images/remove.png"></span>
+         </td>
+         <td id="check">
+                 <input type="checkbox" name="itemlist[]" value="<?php echo $i;?>">
+         </td>
+      </tr>
+    <?php
+      }
+    ?>
+    </table>
+</div>
+<?php include("../view/default/tmpl/playlistmenu.php"); ?>
+</div>
diff --git a/ajax/repeatstate.php b/ajax/repeatstate.php
new file mode 100644 (file)
index 0000000..c983152
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+include('mpd.php');
+
+echo $mpd->repeat;
+
+?>
diff --git a/ajax/trackinfo.php b/ajax/trackinfo.php
new file mode 100644 (file)
index 0000000..e5cc464
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+include('mpd.php');
+
+$cur_track= $mpd->current_track_id;
+$playlist= $mpd->playlist;
+if($cur_track !=-1)
+
+    if ($playlist[$cur_track]['name']==$playlist[$cur_track]['title']) {
+        echo htmlentities(cut_file($playlist[$cur_track]['name']));
+    } else {
+        echo htmlentities($playlist[$cur_track]['title']);
+    }
+else 
+    echo "No Track selected";
+
+?>
diff --git a/ajax/volume.php b/ajax/volume.php
new file mode 100644 (file)
index 0000000..bd3caf0
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+include('mpd.php');
+
+echo $mpd->volume;
+
+?>
diff --git a/config/config.php b/config/config.php
new file mode 100644 (file)
index 0000000..fecc1f6
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$mpd_host ="localhost";
+$mpd_port = "6600";
+$mpd_password = "mypassword"
+
+?>
diff --git a/css/general.css b/css/general.css
new file mode 100644 (file)
index 0000000..19078d4
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+#525356
+*/
+
+
+
+* {
+       margin:0;
+}
+
+body {
+       text-align: center;
+       font-family:arial,sans-serif;
+       margin-top: 15px;
+       margin-bottom: 15px;
+       color:#AEAEAE;
+}
+
+a {
+       text-decoration:none;
+       color: #AEAEAE;
+}
+
+table
+{
+    border-style:none;
+    padding:0px;
+    border-collapse: collapse;
+    border-spacing: 0;
+
+}
+
+img{
+       border:0px;
+       margin: 2px 2px 2px 2px;
+}
+
+button
+{
+background  : none;
+cursor  : pointer;
+border: 0px;
+margin      : 0px;
+padding     : 0px;
+}
+
+.button
+{
+cursor  : pointer;
+}
+
+#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;
+}
+
+
+#nowplaying_heading {
+       font-size: 1.3em;
+       font-wieght: bold;
+       height: 30px;   
+       background: url(../images/control_bg.png) repeat-x;
+       border-bottom: 1px solid #525356;
+}
+
+#nowplaying_content {
+       margin: 10px 5px 10px 5px;
+       text-align: center;
+       border: 1px solid #525356;
+       width: 380px;
+       padding: 30px 0px 30px 0px;
+       background:url(../images/playing_bg.png);
+       font-weight: bold;
+       color: #fff;    
+}
+
+#control_buttons {
+       text-align:center;
+       width: 390px;
+       margin: 10px 5px 10px 5px;
+}
+
+#control_buttons table {
+       margin-left: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;
+}
+
+#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;
+}
+
+#items_heading {
+       text-align: center;
+       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;
+}
+
+#items {
+       font-size: 0.9em;
+       text-align: center;
+       min-height: 400px;
+       background:url(../images/playing_bg.png);
+}
+
+#items table {
+       width: 390px;
+       margin: 0px 5px 0px 5px;
+       border: 1px solid  #525356;
+}
+
+#file {
+       text-align: left;
+       width: 100%;
+
+}
+
+
+#itemEven{
+       background-color: #251616;
+
+}
+
+#itemOdd{
+        background-color: #333;
+}
+
+#itemActive {
+       background: url(../images/playing_bg.png);
+       color: #fff;
+}
+
+#itemActive a {
+       color: #fff;
+}
+
+
+#move img {
+       margin: 1px 1px 1px 1px;
+}
+
+#remove img {
+        margin: 1px 1px 1px 1px;
+}
+
+
+#volume_total {
+       width: 100px;
+       border: 1px solid #525356;
+       height: 5px;
+}
+
+
+#volume_actual {
+       background-color: #d9600c;
+       height:5px;
+}
+
diff --git a/images/addall.png b/images/addall.png
new file mode 100755 (executable)
index 0000000..fa3983e
Binary files /dev/null and b/images/addall.png differ
diff --git a/images/addselected.png b/images/addselected.png
new file mode 100755 (executable)
index 0000000..52fbb78
Binary files /dev/null and b/images/addselected.png differ
diff --git a/images/bg.png b/images/bg.png
new file mode 100755 (executable)
index 0000000..5bd1ec8
Binary files /dev/null and b/images/bg.png differ
diff --git a/images/control_bg.png b/images/control_bg.png
new file mode 100755 (executable)
index 0000000..685abbb
Binary files /dev/null and b/images/control_bg.png differ
diff --git a/images/down.png b/images/down.png
new file mode 100755 (executable)
index 0000000..e8f3d6e
Binary files /dev/null and b/images/down.png differ
diff --git a/images/highlight.png b/images/highlight.png
new file mode 100755 (executable)
index 0000000..3710d71
Binary files /dev/null and b/images/highlight.png differ
diff --git a/images/left.png b/images/left.png
new file mode 100755 (executable)
index 0000000..00714b7
Binary files /dev/null and b/images/left.png differ
diff --git a/images/minus.png b/images/minus.png
new file mode 100755 (executable)
index 0000000..dff37f6
Binary files /dev/null and b/images/minus.png differ
diff --git a/images/next.png b/images/next.png
new file mode 100755 (executable)
index 0000000..fc2c791
Binary files /dev/null and b/images/next.png differ
diff --git a/images/pause.png b/images/pause.png
new file mode 100755 (executable)
index 0000000..9508f98
Binary files /dev/null and b/images/pause.png differ
diff --git a/images/play.png b/images/play.png
new file mode 100755 (executable)
index 0000000..3591973
Binary files /dev/null and b/images/play.png differ
diff --git a/images/playing_bg.png b/images/playing_bg.png
new file mode 100755 (executable)
index 0000000..f2e2337
Binary files /dev/null and b/images/playing_bg.png differ
diff --git a/images/playlist.png b/images/playlist.png
new file mode 100755 (executable)
index 0000000..ae4af14
Binary files /dev/null and b/images/playlist.png differ
diff --git a/images/plus.png b/images/plus.png
new file mode 100755 (executable)
index 0000000..b72d579
Binary files /dev/null and b/images/plus.png differ
diff --git a/images/prev.png b/images/prev.png
new file mode 100755 (executable)
index 0000000..aedbbdf
Binary files /dev/null and b/images/prev.png differ
diff --git a/images/previous.png b/images/previous.png
new file mode 100755 (executable)
index 0000000..9c49139
Binary files /dev/null and b/images/previous.png differ
diff --git a/images/remall.png b/images/remall.png
new file mode 100755 (executable)
index 0000000..ffb546a
Binary files /dev/null and b/images/remall.png differ
diff --git a/images/remove.png b/images/remove.png
new file mode 100755 (executable)
index 0000000..bf94562
Binary files /dev/null and b/images/remove.png differ
diff --git a/images/removeall.png b/images/removeall.png
new file mode 100755 (executable)
index 0000000..4fe02d1
Binary files /dev/null and b/images/removeall.png differ
diff --git a/images/removeselected.png b/images/removeselected.png
new file mode 100755 (executable)
index 0000000..35294aa
Binary files /dev/null and b/images/removeselected.png differ
diff --git a/images/remselected.png b/images/remselected.png
new file mode 100755 (executable)
index 0000000..6466dce
Binary files /dev/null and b/images/remselected.png differ
diff --git a/images/repeatoff.png b/images/repeatoff.png
new file mode 100755 (executable)
index 0000000..0a17659
Binary files /dev/null and b/images/repeatoff.png differ
diff --git a/images/repeaton.png b/images/repeaton.png
new file mode 100755 (executable)
index 0000000..aaef8ce
Binary files /dev/null and b/images/repeaton.png differ
diff --git a/images/right.png b/images/right.png
new file mode 100755 (executable)
index 0000000..2ce6d36
Binary files /dev/null and b/images/right.png differ
diff --git a/images/songs.png b/images/songs.png
new file mode 100755 (executable)
index 0000000..f24c1ef
Binary files /dev/null and b/images/songs.png differ
diff --git a/images/stop.png b/images/stop.png
new file mode 100755 (executable)
index 0000000..1e1dd0f
Binary files /dev/null and b/images/stop.png differ
diff --git a/images/up.png b/images/up.png
new file mode 100755 (executable)
index 0000000..0ada34a
Binary files /dev/null and b/images/up.png differ
diff --git a/images/update.png b/images/update.png
new file mode 100755 (executable)
index 0000000..fa2242b
Binary files /dev/null and b/images/update.png differ
diff --git a/index.php b/index.php
new file mode 100644 (file)
index 0000000..40c64d8
--- /dev/null
+++ b/index.php
@@ -0,0 +1,17 @@
+<?php
+include('config/config.php');
+include('system/mpd_class.php');
+include('system/helper.php');
+
+$mpd = new mpd($mpd_host,$mpd_port,$mpd_password);
+
+if($mpd->connected != 1){
+       echo "Not Connected to Server";
+       exit(1);
+}
+
+$task=$_REQUEST['task'];
+
+include('view/default/view.php');
+
+?>
diff --git a/model/player.php b/model/player.php
new file mode 100644 (file)
index 0000000..ff3fc0d
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+switch($task) {
+
+       case("play"):
+               $mpd->Play();
+               break;
+
+       case("prev"):
+               $mpd->Previous();
+               break;
+
+       case("pause"):
+               $mpd->Pause();
+               break;
+
+       case("stop"):
+               $mpd->Stop();
+               break;
+
+       case("next"):
+                $mpd->Next();
+                break;
+
+       case("vold"):
+                $mpd->AdjustVolume(-3);
+                break;
+       case("volu"):
+                $mpd->AdjustVolume(+3);
+                break;
+
+       case("update"):
+                $mpd->DBRefresh();
+                break;
+
+       case("repeat"):
+               $repeat = $mpd->repeat;
+               if($repeat==1)
+                       $mpd->SetRepeat(0);
+               else
+                       $mpd->SetRepeat(1);
+               break;
+}
+?>
diff --git a/model/tracklist.php b/model/tracklist.php
new file mode 100644 (file)
index 0000000..798ca01
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+
+function addDir($item,$mpd) {
+       $opendirs[] = $item;
+       $count=0;
+       while($count != count($opendirs)){
+               $current = $opendirs[$count];
+               $count++;
+
+               $files = $mpd->GetDir($current);
+               for($i=0;$i<count($files);$i++) {
+                       if($files[$i]['type']=="directory") {
+                               $opendirs[]=$files[$i]['name'];
+                       } else {
+                               $mpd->PLAdd($files[$i]['name']);
+                       }
+
+               }
+       }       
+}
+
+switch($task) {
+
+  case("remove"):
+    if($item != null)
+      $mpd->PLRemove($item);
+    break;
+
+
+   case("clear"):
+     $mpd->PLClear();
+     break;
+
+   case("playitem"):
+     if($item != null){
+       $mpd->SkipTo($item);
+      }
+      break;
+
+   case("addfile"):
+      $mpd->PLAdd($item);
+      break;
+
+   case("adddir"):
+      addDir($item,$mpd);
+      break;
+      
+
+    case("moveup"):
+       if($item !=0) {
+           $mpd->Move($item,$item-1);
+       }
+       break;
+
+    case("movedown"):
+       if($item !=count($mpd->playlist)-1) {
+           $mpd->Move($item,$item+1);
+       }
+       break;
+
+
+     case("removeselected"):
+       $items=$_POST['itemlist'];
+       for($i=0;$i<count($items);$i++){
+         $mpd->PLRemove($items[$i]-$i);
+       }
+       break;
+
+
+       case("addselected"):
+               $items=$_POST['itemlist'];
+               $dir=$_REQUEST['dir'];
+               $files = $mpd->GetDir($dir);
+                for($i=0;$i<count($items);$i++) {
+                        if($files[$items[$i]]['type']=="directory") {
+                                addDir($files[$items[$i]]['name'],$mpd);
+                        } else {
+                                $mpd->PLAdd($files[$items[$i]]['name']);
+                        }
+                }
+               break;
+
+       case("addall"):
+                $dir=$_REQUEST['item'];
+                $files = $mpd->GetDir($dir);
+                for($i=0;$i<count($files);$i++) {
+                        if($files[$i]['type']=="directory") {
+                                addDir($files[$i]['name'],$mpd);
+                        } else {
+                                $mpd->PLAdd($files[$i]['name']);
+                        }
+                }
+                break;
+
+
+
+}
+
+
+?>
diff --git a/system/helper.php b/system/helper.php
new file mode 100644 (file)
index 0000000..10009e4
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+function cut_file($str) {
+       $result=array();
+       $result=preg_split("/\//",$str);
+        //print_r($result);
+       return $result[count($result)-1];
+}
+
+
+function cut_lastDir($str) {
+        $result=array();
+        $result=preg_split("/\//",$str);
+       //print_r($result);
+        return $result[count($result)-1];
+}
+
+
+function cut_firstDir($str) {
+        $result=array();
+        preg_match("/([^\/]+)\//",$str,$result);
+
+       //print_r($result);
+        return $result[1];
+}
+
+function cut_upperDir($str) {
+        $result=array();
+        preg_match("/(.*)\/([^\/]*)/",$str,$result);
+
+       //print_r($result);
+        return $result[1];
+}
+
+?>
diff --git a/system/mpd_class.php b/system/mpd_class.php
new file mode 100644 (file)
index 0000000..8ffddcd
--- /dev/null
@@ -0,0 +1,976 @@
+<?php\r
+/*\r
+ *  mpd.class.php - PHP Object Interface to the MPD Music Player Daemon\r
+ *  Version 1.2, Released 05/05/2004\r
+ *  Copyright (C) 2003-2004  Benjamin Carlisle (bcarlisle@24oz.com)\r
+ *  http://mpd.24oz.com/ | http://www.musicpd.org/\r
+ *\r
+ *  This program is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU General Public License as published by\r
+ *  the Free Software Foundation; either version 2 of the License, or\r
+ *  (at your option) any later version.\r
+ *\r
+ *  This program is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU General Public License\r
+ *  along with this program; if not, write to the Free Software\r
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */ \r
+\r
+// Create common command definitions for MPD to use\r
+define("MPD_CMD_STATUS",      "status");\r
+define("MPD_CMD_STATISTICS",  "stats");\r
+define("MPD_CMD_VOLUME",      "volume");\r
+define("MPD_CMD_SETVOL",      "setvol");\r
+define("MPD_CMD_PLAY",        "play");\r
+define("MPD_CMD_STOP",        "stop");\r
+define("MPD_CMD_PAUSE",       "pause");\r
+define("MPD_CMD_NEXT",        "next");\r
+define("MPD_CMD_PREV",        "previous");\r
+define("MPD_CMD_PLLIST",      "playlistinfo");\r
+define("MPD_CMD_PLADD",       "add");\r
+define("MPD_CMD_PLREMOVE",    "delete");\r
+define("MPD_CMD_PLCLEAR",     "clear");\r
+define("MPD_CMD_PLSHUFFLE",   "shuffle");\r
+define("MPD_CMD_PLLOAD",      "load");\r
+define("MPD_CMD_PLSAVE",      "save");\r
+define("MPD_CMD_KILL",        "kill");\r
+define("MPD_CMD_REFRESH",     "update");\r
+define("MPD_CMD_REPEAT",      "repeat");\r
+define("MPD_CMD_LSDIR",       "lsinfo");\r
+define("MPD_CMD_SEARCH",      "search");\r
+define("MPD_CMD_START_BULK",  "command_list_begin");\r
+define("MPD_CMD_END_BULK",    "command_list_end");\r
+define("MPD_CMD_FIND",        "find");\r
+define("MPD_CMD_RANDOM",      "random");\r
+define("MPD_CMD_SEEK",        "seek");\r
+define("MPD_CMD_PLSWAPTRACK", "swap");\r
+define("MPD_CMD_PLMOVETRACK", "move");\r
+define("MPD_CMD_PASSWORD",    "password");\r
+define("MPD_CMD_TABLE",       "list");\r
+\r
+// Predefined MPD Response messages\r
+define("MPD_RESPONSE_ERR", "ACK");\r
+define("MPD_RESPONSE_OK",  "OK");\r
+\r
+// MPD State Constants\r
+define("MPD_STATE_PLAYING", "play");\r
+define("MPD_STATE_STOPPED", "stop");\r
+define("MPD_STATE_PAUSED",  "pause");\r
+\r
+// MPD Searching Constants\r
+define("MPD_SEARCH_ARTIST", "artist");\r
+define("MPD_SEARCH_TITLE",  "title");\r
+define("MPD_SEARCH_ALBUM",  "album");\r
+\r
+// MPD Cache Tables\r
+define("MPD_TBL_ARTIST","artist");\r
+define("MPD_TBL_ALBUM","album");\r
+\r
+class mpd {\r
+       // TCP/Connection variables\r
+       var $host;\r
+       var $port;\r
+    var $password;\r
+\r
+       var $mpd_sock   = NULL;\r
+       var $connected  = FALSE;\r
+\r
+       // MPD Status variables\r
+       var $mpd_version    = "(unknown)";\r
+\r
+       var $state;\r
+       var $current_track_position;\r
+       var $current_track_length;\r
+       var $current_track_id;\r
+       var $volume;\r
+       var $repeat;\r
+       var $random;\r
+\r
+       var $uptime;\r
+       var $playtime;\r
+       var $db_last_refreshed;\r
+       var $num_songs_played;\r
+       var $playlist_count;\r
+       \r
+       var $num_artists;\r
+       var $num_albums;\r
+       var $num_songs;\r
+       \r
+       var $playlist           = array();\r
+\r
+       // Misc Other Vars      \r
+       var $mpd_class_version = "1.2";\r
+\r
+       var $debugging   = FALSE;    // Set to TRUE to turn extended debugging on.\r
+       var $errStr      = "";       // Used for maintaining information about the last error message\r
+\r
+       var $command_queue;          // The list of commands for bulk command sending\r
+\r
+    // =================== BEGIN OBJECT METHODS ================\r
+\r
+       /* mpd() : Constructor\r
+        * \r
+        * Builds the MPD object, connects to the server, and refreshes all local object properties.\r
+        */\r
+       function mpd($srv,$port,$pwd = NULL) {\r
+               $this->host = $srv;\r
+               $this->port = $port;\r
+        $this->password = $pwd;\r
+\r
+               $resp = $this->Connect();\r
+               if ( is_null($resp) ) {\r
+            $this->errStr = "Could not connect";\r
+                       return;\r
+               } else {\r
+                       list ( $this->mpd_version ) = sscanf($resp, MPD_RESPONSE_OK . " MPD %s\n");\r
+            if ( ! is_null($pwd) ) {\r
+                if ( is_null($this->SendCommand(MPD_CMD_PASSWORD,$pwd)) ) {\r
+                    $this->connected = FALSE;\r
+                    return;  // bad password or command\r
+                }\r
+                       if ( is_null($this->RefreshInfo()) ) { // no read access -- might as well be disconnected!\r
+                    $this->connected = FALSE;\r
+                    $this->errStr = "Password supplied does not have read access";\r
+                    return;\r
+                }\r
+            } else {\r
+                       if ( is_null($this->RefreshInfo()) ) { // no read access -- might as well be disconnected!\r
+                    $this->connected = FALSE;\r
+                    $this->errStr = "Password required to access server";\r
+                    return; \r
+                }\r
+            }\r
+               }\r
+       }\r
+\r
+       /* Connect()\r
+        * \r
+        * Connects to the MPD server. \r
+     * \r
+        * NOTE: This is called automatically upon object instantiation; you should not need to call this directly.\r
+        */\r
+       function Connect() {\r
+               if ( $this->debugging ) echo "mpd->Connect() / host: ".$this->host.", port: ".$this->port."\n";\r
+               $this->mpd_sock = fsockopen($this->host,$this->port,$errNo,$errStr,10);\r
+               if (!$this->mpd_sock) {\r
+                       $this->errStr = "Socket Error: $errStr ($errNo)";\r
+                       return NULL;\r
+               } else {\r
+                       while(!feof($this->mpd_sock)) {\r
+                               $response =  fgets($this->mpd_sock,1024);\r
+                               if (strncmp(MPD_RESPONSE_OK,$response,strlen(MPD_RESPONSE_OK)) == 0) {\r
+                                       $this->connected = TRUE;\r
+                                       return $response;\r
+                                       break;\r
+                               }\r
+                               if (strncmp(MPD_RESPONSE_ERR,$response,strlen(MPD_RESPONSE_ERR)) == 0) {\r
+                                       $this->errStr = "Server responded with: $response";\r
+                                       return NULL;\r
+                               }\r
+                       }\r
+                       // Generic response\r
+                       $this->errStr = "Connection not available";\r
+                       return NULL;\r
+               }\r
+       }\r
+\r
+       /* SendCommand()\r
+        * \r
+        * Sends a generic command to the MPD server. Several command constants are pre-defined for \r
+        * use (see MPD_CMD_* constant definitions above). \r
+        */\r
+       function SendCommand($cmdStr,$arg1 = "",$arg2 = "") {\r
+               if ( $this->debugging ) echo "mpd->SendCommand() / cmd: ".$cmdStr.", args: ".$arg1." ".$arg2."\n";\r
+               \r
+               if ( ! $this->connected ) {\r
+                       echo "mpd->SendCommand() / Error: Not connected\n";\r
+               } else {\r
+                       // Clear out the error String\r
+                       $this->errStr = "";\r
+                       $respStr = "";\r
+\r
+                       // Check the command compatibility:\r
+                       if ( ! $this->_checkCompatibility($cmdStr) ) {\r
+                               echo "Not compatible command!";\r
+                               return NULL;\r
+                       }\r
+\r
+                       if (strlen($arg1) > 0) $cmdStr .= " \"$arg1\"";\r
+\r
+                       if (strlen($arg2) > 0) $cmdStr .= " \"$arg2\"";\r
+                       if ( $this->debugging ) echo "mpd-> ".$cmdStr."\n";\r
+                       fputs($this->mpd_sock,"$cmdStr\n");\r
+                       while(!feof($this->mpd_sock)) {\r
+                               $response = fgets($this->mpd_sock,1024);\r
+                               if ( $this->debugging ) echo "mpd.response-> ".$response."\n";\r
+\r
+                               // An OK signals the end of transmission -- we'll ignore it\r
+                               if (strncmp(MPD_RESPONSE_OK,$response,strlen(MPD_RESPONSE_OK)) == 0) {\r
+                                       break;\r
+                               }\r
+\r
+                               // An ERR signals the end of transmission with an error! Let's grab the single-line message.\r
+                               if (strncmp(MPD_RESPONSE_ERR,$response,strlen(MPD_RESPONSE_ERR)) == 0) {\r
+                                       list ( $junk, $errTmp ) = explode(MPD_RESPONSE_ERR . " ",$response );\r
+                                       $this->errStr = strtok($errTmp,"\n");\r
+                               }\r
+\r
+                               if ( strlen($this->errStr) > 0 ) {\r
+                                       return NULL;\r
+                               }\r
+\r
+                               // Build the response string\r
+                               $respStr .= $response;\r
+                       }\r
+                       if ( $this->debugging ) echo "mpd->SendCommand() / response: '".$respStr."'\n";\r
+               }\r
+               return $respStr;\r
+       }\r
+\r
+       /* QueueCommand() \r
+        *\r
+        * Queues a generic command for later sending to the MPD server. The CommandQueue can hold \r
+        * as many commands as needed, and are sent all at once, in the order they are queued, using \r
+        * the SendCommandQueue() method. The syntax for queueing commands is identical to SendCommand(). \r
+     */\r
+       function QueueCommand($cmdStr,$arg1 = "",$arg2 = "") {\r
+               if ( $this->debugging ) echo "mpd->QueueCommand() / cmd: ".$cmdStr.", args: ".$arg1." ".$arg2."\n";\r
+               if ( ! $this->connected ) {\r
+                       echo "mpd->QueueCommand() / Error: Not connected\n";\r
+                       return NULL;\r
+               } else {\r
+                       if ( strlen($this->command_queue) == 0 ) {\r
+                               $this->command_queue = MPD_CMD_START_BULK . "\n";\r
+                       }\r
+                       if (strlen($arg1) > 0) $cmdStr .= " \"$arg1\"";\r
+                       if (strlen($arg2) > 0) $cmdStr .= " \"$arg2\"";\r
+\r
+                       $this->command_queue .= $cmdStr ."\n";\r
+\r
+                       if ( $this->debugging ) echo "mpd->QueueCommand() / return\n";\r
+               }\r
+               return TRUE;\r
+       }\r
+\r
+       /* SendCommandQueue() \r
+        *\r
+        * Sends all commands in the Command Queue to the MPD server. See also QueueCommand().\r
+     */\r
+       function SendCommandQueue() {\r
+               if ( $this->debugging ) echo "mpd->SendCommandQueue()\n";\r
+               if ( ! $this->connected ) {\r
+                       echo "mpd->SendCommandQueue() / Error: Not connected\n";\r
+                       return NULL;\r
+               } else {\r
+                       $this->command_queue .= MPD_CMD_END_BULK . "\n";\r
+                       if ( is_null($respStr = $this->SendCommand($this->command_queue)) ) {\r
+                               return NULL;\r
+                       } else {\r
+                               $this->command_queue = NULL;\r
+                               if ( $this->debugging ) echo "mpd->SendCommandQueue() / response: '".$respStr."'\n";\r
+                       }\r
+               }\r
+               return $respStr;\r
+       }\r
+\r
+       /* AdjustVolume() \r
+        *\r
+        * Adjusts the mixer volume on the MPD by <modifier>, which can be a positive (volume increase),\r
+        * or negative (volume decrease) value. \r
+     */\r
+       function AdjustVolume($modifier) {\r
+               if ( $this->debugging ) echo "mpd->AdjustVolume()\n";\r
+               if ( ! is_numeric($modifier) ) {\r
+                       $this->errStr = "AdjustVolume() : argument 1 must be a numeric value";\r
+                       return NULL;\r
+               }\r
+\r
+        $this->RefreshInfo();\r
+        $newVol = $this->volume + $modifier;\r
+        $ret = $this->SetVolume($newVol);\r
+\r
+               if ( $this->debugging ) echo "mpd->AdjustVolume() / return\n";\r
+               return $ret;\r
+       }\r
+\r
+       /* SetVolume() \r
+        *\r
+        * Sets the mixer volume to <newVol>, which should be between 1 - 100.\r
+     */\r
+       function SetVolume($newVol) {\r
+               if ( $this->debugging ) echo "mpd->SetVolume()\n";\r
+               if ( ! is_numeric($newVol) ) {\r
+                       $this->errStr = "SetVolume() : argument 1 must be a numeric value";\r
+                       return NULL;\r
+               }\r
+\r
+        // Forcibly prevent out of range errors\r
+               if ( $newVol < 0 )   $newVol = 0;\r
+               if ( $newVol > 100 ) $newVol = 100;\r
+\r
+        // If we're not compatible with SETVOL, we'll try adjusting using VOLUME\r
+        if ( $this->_checkCompatibility(MPD_CMD_SETVOL) ) {\r
+            if ( ! is_null($ret = $this->SendCommand(MPD_CMD_SETVOL,$newVol))) $this->volume = $newVol;\r
+        } else {\r
+               $this->RefreshInfo();     // Get the latest volume\r
+               if ( is_null($this->volume) ) {\r
+                       return NULL;\r
+               } else {\r
+                       $modifier = ( $newVol - $this->volume );\r
+                if ( ! is_null($ret = $this->SendCommand(MPD_CMD_VOLUME,$modifier))) $this->volume = $newVol;\r
+               }\r
+        }\r
+\r
+               if ( $this->debugging ) echo "mpd->SetVolume() / return\n";\r
+               return $ret;\r
+       }\r
+\r
+       /* GetDir() \r
+        * \r
+     * Retrieves a database directory listing of the <dir> directory and places the results into\r
+        * a multidimensional array. If no directory is specified, the directory listing is at the \r
+        * base of the MPD music path. \r
+        */\r
+       function GetDir($dir = "") {\r
+               if ( $this->debugging ) echo "mpd->GetDir()\n";\r
+               $resp = $this->SendCommand(MPD_CMD_LSDIR,$dir);\r
+               $dirlist = $this->_parseFileListResponse($resp);\r
+               if ( $this->debugging ) echo "mpd->GetDir() / return ".print_r($dirlist)."\n";\r
+               return $dirlist;\r
+       }\r
+\r
+       /* PLAdd() \r
+        * \r
+     * Adds each track listed in a single-dimensional <trackArray>, which contains filenames \r
+        * of tracks to add, to the end of the playlist. This is used to add many, many tracks to \r
+        * the playlist in one swoop.\r
+        */\r
+       function PLAddBulk($trackArray) {\r
+               if ( $this->debugging ) echo "mpd->PLAddBulk()\n";\r
+               $num_files = count($trackArray);\r
+               for ( $i = 0; $i < $num_files; $i++ ) {\r
+                       $this->QueueCommand(MPD_CMD_PLADD,$trackArray[$i]);\r
+               }\r
+               $resp = $this->SendCommandQueue();\r
+               $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->PLAddBulk() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+       /* PLAdd() \r
+        * \r
+        * Adds the file <file> to the end of the playlist. <file> must be a track in the MPD database. \r
+        */\r
+       function PLAdd($fileName) {\r
+               if ( $this->debugging ) echo "mpd->PLAdd()\n";\r
+               if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLADD,$fileName))) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->PLAdd() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+       /* PLMoveTrack() \r
+        * \r
+        * Moves track number <origPos> to position <newPos> in the playlist. This is used to reorder \r
+        * the songs in the playlist.\r
+        */\r
+       function PLMoveTrack($origPos, $newPos) {\r
+               if ( $this->debugging ) echo "mpd->PLMoveTrack()\n";\r
+               if ( ! is_numeric($origPos) ) {\r
+                       $this->errStr = "PLMoveTrack(): argument 1 must be numeric";\r
+                       return NULL;\r
+               } \r
+               if ( $origPos < 0 or $origPos > $this->playlist_count ) {\r
+                       $this->errStr = "PLMoveTrack(): argument 1 out of range";\r
+                       return NULL;\r
+               }\r
+               if ( $newPos < 0 ) $newPos = 0;\r
+               if ( $newPos > $this->playlist_count ) $newPos = $this->playlist_count;\r
+               \r
+               if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLMOVETRACK,$origPos,$newPos))) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->PLMoveTrack() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+       /* PLShuffle() \r
+        * \r
+        * Randomly reorders the songs in the playlist.\r
+        */\r
+       function PLShuffle() {\r
+               if ( $this->debugging ) echo "mpd->PLShuffle()\n";\r
+               if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLSHUFFLE))) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->PLShuffle() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+       /* PLLoad() \r
+        * \r
+        * Retrieves the playlist from <file>.m3u and loads it into the current playlist. \r
+        */\r
+       function PLLoad($file) {\r
+               if ( $this->debugging ) echo "mpd->PLLoad()\n";\r
+               if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLLOAD,$file))) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->PLLoad() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+       /* PLSave() \r
+        * \r
+        * Saves the playlist to <file>.m3u for later retrieval. The file is saved in the MPD playlist\r
+        * directory.\r
+        */\r
+       function PLSave($file) {\r
+               if ( $this->debugging ) echo "mpd->PLSave()\n";\r
+               $resp = $this->SendCommand(MPD_CMD_PLSAVE,$file);\r
+               if ( $this->debugging ) echo "mpd->PLSave() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+       /* PLClear() \r
+        * \r
+        * Empties the playlist.\r
+        */\r
+       function PLClear() {\r
+               if ( $this->debugging ) echo "mpd->PLClear()\n";\r
+               if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLCLEAR))) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->PLClear() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+\r
+       /* PLMove()\r
+       *\r
+       * Move song from pos to the other\r
+       */\r
+       function Move ($from,$to) {\r
+               if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLMOVETRACK,$from,$to))) $this->RefreshInfo();\r
+               //die(print_r($resp));\r
+\r
+       }\r
+\r
+\r
+       /* PLRemove() \r
+        * \r
+        * Removes track <id> from the playlist.\r
+        */\r
+       function PLRemove($id) {\r
+               if ( $this->debugging ) echo "mpd->PLRemove()\n";\r
+               if ( ! is_numeric($id) ) {\r
+                       $this->errStr = "PLRemove() : argument 1 must be a numeric value";\r
+                       return NULL;\r
+               }\r
+               if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLREMOVE,$id))) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->PLRemove() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+       /* SetRepeat() \r
+        * \r
+        * Enables 'loop' mode -- tells MPD continually loop the playlist. The <repVal> parameter \r
+        * is either 1 (on) or 0 (off).\r
+        */\r
+       function SetRepeat($repVal) {\r
+               if ( $this->debugging ) echo "mpd->SetRepeat()\n";\r
+               $rpt = $this->SendCommand(MPD_CMD_REPEAT,$repVal);\r
+               $this->repeat = $repVal;\r
+               if ( $this->debugging ) echo "mpd->SetRepeat() / return\n";\r
+               return $rpt;\r
+       }\r
+\r
+       /* SetRandom() \r
+        * \r
+        * Enables 'randomize' mode -- tells MPD to play songs in the playlist in random order. The\r
+        * <rndVal> parameter is either 1 (on) or 0 (off).\r
+        */\r
+       function SetRandom($rndVal) {\r
+               if ( $this->debugging ) echo "mpd->SetRandom()\n";\r
+               $resp = $this->SendCommand(MPD_CMD_RANDOM,$rndVal);\r
+               $this->random = $rndVal;\r
+               if ( $this->debugging ) echo "mpd->SetRandom() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+       /* Shutdown() \r
+        * \r
+        * Shuts down the MPD server (aka sends the KILL command). This closes the current connection, \r
+        * and prevents future communication with the server. \r
+        */\r
+       function Shutdown() {\r
+               if ( $this->debugging ) echo "mpd->Shutdown()\n";\r
+               $resp = $this->SendCommand(MPD_CMD_SHUTDOWN);\r
+\r
+               $this->connected = FALSE;\r
+               unset($this->mpd_version);\r
+               unset($this->errStr);\r
+               unset($this->mpd_sock);\r
+\r
+               if ( $this->debugging ) echo "mpd->Shutdown() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+       /* DBRefresh() \r
+        * \r
+        * Tells MPD to rescan the music directory for new tracks, and to refresh the Database. Tracks \r
+        * cannot be played unless they are in the MPD database.\r
+        */\r
+       function DBRefresh() {\r
+               if ( $this->debugging ) echo "mpd->DBRefresh()\n";\r
+               $resp = $this->SendCommand(MPD_CMD_REFRESH);\r
+               \r
+               // Update local variables\r
+               $this->RefreshInfo();\r
+\r
+               if ( $this->debugging ) echo "mpd->DBRefresh() / return\n";\r
+               return $resp;\r
+       }\r
+\r
+       /* Play() \r
+        * \r
+        * Begins playing the songs in the MPD playlist. \r
+        */\r
+       function Play() {\r
+               if ( $this->debugging ) echo "mpd->Play()\n";\r
+               if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PLAY) )) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->Play() / return\n";\r
+               return $rpt;\r
+       }\r
+\r
+       /* Stop() \r
+        * \r
+        * Stops playing the MPD. \r
+        */\r
+       function Stop() {\r
+               if ( $this->debugging ) echo "mpd->Stop()\n";\r
+               if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_STOP) )) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->Stop() / return\n";\r
+               return $rpt;\r
+       }\r
+\r
+       /* Pause() \r
+        * \r
+        * Toggles pausing on the MPD. Calling it once will pause the player, calling it again\r
+        * will unpause. \r
+        */\r
+       function Pause() {\r
+               if ( $this->debugging ) echo "mpd->Pause()\n";\r
+               if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PAUSE) )) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->Pause() / return\n";\r
+               return $rpt;\r
+       }\r
+       \r
+       /* SeekTo() \r
+        * \r
+        * Skips directly to the <idx> song in the MPD playlist. \r
+        */\r
+       function SkipTo($idx) { \r
+               if ( $this->debugging ) echo "mpd->SkipTo()\n";\r
+               if ( ! is_numeric($idx) ) {\r
+                       $this->errStr = "SkipTo() : argument 1 must be a numeric value";\r
+                       return NULL;\r
+               }\r
+               if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PLAY,$idx))) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->SkipTo() / return\n";\r
+               return $idx;\r
+       }\r
+\r
+       /* SeekTo() \r
+        * \r
+        * Skips directly to a given position within a track in the MPD playlist. The <pos> argument,\r
+        * given in seconds, is the track position to locate. The <track> argument, if supplied is\r
+        * the track number in the playlist. If <track> is not specified, the current track is assumed.\r
+        */\r
+       function SeekTo($pos, $track = -1) { \r
+               if ( $this->debugging ) echo "mpd->SeekTo()\n";\r
+               if ( ! is_numeric($pos) ) {\r
+                       $this->errStr = "SeekTo() : argument 1 must be a numeric value";\r
+                       return NULL;\r
+               }\r
+               if ( ! is_numeric($track) ) {\r
+                       $this->errStr = "SeekTo() : argument 2 must be a numeric value";\r
+                       return NULL;\r
+               }\r
+               if ( $track == -1 ) { \r
+                       $track = $this->current_track_id;\r
+               } \r
+               \r
+               if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_SEEK,$track,$pos))) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->SeekTo() / return\n";\r
+               return $pos;\r
+       }\r
+\r
+       /* Next() \r
+        * \r
+        * Skips to the next song in the MPD playlist. If not playing, returns an error. \r
+        */\r
+       function Next() {\r
+               if ( $this->debugging ) echo "mpd->Next()\n";\r
+               if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_NEXT))) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->Next() / return\n";\r
+               return $rpt;\r
+       }\r
+\r
+       /* Previous() \r
+        * \r
+        * Skips to the previous song in the MPD playlist. If not playing, returns an error. \r
+        */\r
+       function Previous() {\r
+               if ( $this->debugging ) echo "mpd->Previous()\n";\r
+               if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PREV))) $this->RefreshInfo();\r
+               if ( $this->debugging ) echo "mpd->Previous() / return\n";\r
+               return $rpt;\r
+       }\r
+       \r
+       /* Search() \r
+        * \r
+     * Searches the MPD database. The search <type> should be one of the following: \r
+     *        MPD_SEARCH_ARTIST, MPD_SEARCH_TITLE, MPD_SEARCH_ALBUM\r
+     * The search <string> is a case-insensitive locator string. Anything that contains \r
+        * <string> will be returned in the results. \r
+        */\r
+       function Search($type,$string) {\r
+               if ( $this->debugging ) echo "mpd->Search()\n";\r
+               if ( $type != MPD_SEARCH_ARTIST and\r
+                $type != MPD_SEARCH_ALBUM and\r
+                        $type != MPD_SEARCH_TITLE ) {\r
+                       $this->errStr = "mpd->Search(): invalid search type";\r
+                       return NULL;\r
+               } else {\r
+                       if ( is_null($resp = $this->SendCommand(MPD_CMD_SEARCH,$type,$string))) return NULL;\r
+                       $searchlist = $this->_parseFileListResponse($resp);\r
+               }\r
+               if ( $this->debugging ) echo "mpd->Search() / return ".print_r($searchlist)."\n";\r
+               return $searchlist;\r
+       }\r
+\r
+       /* Find() \r
+        * \r
+        * Find() looks for exact matches in the MPD database. The find <type> should be one of \r
+        * the following: \r
+     *         MPD_SEARCH_ARTIST, MPD_SEARCH_TITLE, MPD_SEARCH_ALBUM\r
+     * The find <string> is a case-insensitive locator string. Anything that exactly matches \r
+        * <string> will be returned in the results. \r
+        */\r
+       function Find($type,$string) {\r
+               if ( $this->debugging ) echo "mpd->Find()\n";\r
+               if ( $type != MPD_SEARCH_ARTIST and\r
+                $type != MPD_SEARCH_ALBUM and\r
+                        $type != MPD_SEARCH_TITLE ) {\r
+                       $this->errStr = "mpd->Find(): invalid find type";\r
+                       return NULL;\r
+               } else {\r
+                       if ( is_null($resp = $this->SendCommand(MPD_CMD_FIND,$type,$string)))   return NULL;\r
+                       $searchlist = $this->_parseFileListResponse($resp);\r
+               }\r
+               if ( $this->debugging ) echo "mpd->Find() / return ".print_r($searchlist)."\n";\r
+               return $searchlist;\r
+       }\r
+\r
+       /* Disconnect() \r
+        * \r
+        * Closes the connection to the MPD server.\r
+        */\r
+       function Disconnect() {\r
+               if ( $this->debugging ) echo "mpd->Disconnect()\n";\r
+               fclose($this->mpd_sock);\r
+\r
+               $this->connected = FALSE;\r
+               unset($this->mpd_version);\r
+               unset($this->errStr);\r
+               unset($this->mpd_sock);\r
+       }\r
+\r
+       /* GetArtists() \r
+        * \r
+        * Returns the list of artists in the database in an associative array.\r
+       */\r
+       function GetArtists() {\r
+               if ( $this->debugging ) echo "mpd->GetArtists()\n";\r
+               if ( is_null($resp = $this->SendCommand(MPD_CMD_TABLE, MPD_TBL_ARTIST)))        return NULL;\r
+        $arArray = array();\r
+        \r
+        $arLine = strtok($resp,"\n");\r
+        $arName = "";\r
+        $arCounter = -1;\r
+        while ( $arLine ) {\r
+            list ( $element, $value ) = explode(": ",$arLine);\r
+            if ( $element == "Artist" ) {\r
+               $arCounter++;\r
+               $arName = $value;\r
+               $arArray[$arCounter] = $arName;\r
+            }\r
+\r
+            $arLine = strtok("\n");\r
+        }\r
+               if ( $this->debugging ) echo "mpd->GetArtists()\n";\r
+        return $arArray;\r
+    }\r
+\r
+    /* GetAlbums() \r
+        * \r
+        * Returns the list of albums in the database in an associative array. Optional parameter\r
+     * is an artist Name which will list all albums by a particular artist.\r
+       */\r
+       function GetAlbums( $ar = NULL) {\r
+               if ( $this->debugging ) echo "mpd->GetAlbums()\n";\r
+               if ( is_null($resp = $this->SendCommand(MPD_CMD_TABLE, MPD_TBL_ALBUM, $ar )))   return NULL;\r
+        $alArray = array();\r
+\r
+        $alLine = strtok($resp,"\n");\r
+        $alName = "";\r
+        $alCounter = -1;\r
+        while ( $alLine ) {\r
+            list ( $element, $value ) = explode(": ",$alLine);\r
+            if ( $element == "Album" ) {\r
+               $alCounter++;\r
+               $alName = $value;\r
+               $alArray[$alCounter] = $alName;\r
+            }\r
+\r
+            $alLine = strtok("\n");\r
+        }\r
+               if ( $this->debugging ) echo "mpd->GetAlbums()\n";\r
+        return $alArray;\r
+    }\r
+\r
+       //*******************************************************************************//\r
+       //***************************** INTERNAL FUNCTIONS ******************************//\r
+       //*******************************************************************************//\r
+\r
+    /* _computeVersionValue()\r
+     *\r
+     * Computes a compatibility value from a version string\r
+     *\r
+     */\r
+    function _computeVersionValue($verStr) {\r
+               list ($ver_maj, $ver_min, $ver_rel ) = explode("\.",$verStr);\r
+               return ( 100 * $ver_maj ) + ( 10 * $ver_min ) + ( $ver_rel );\r
+    }\r
+\r
+       /* _checkCompatibility() \r
+        * \r
+        * Check MPD command compatibility against our internal table. If there is no version \r
+        * listed in the table, allow it by default.\r
+       */\r
+       function _checkCompatibility($cmd) {\r
+        // Check minimum compatibility\r
+               $req_ver_low = $this->COMPATIBILITY_MIN_TBL[$cmd];\r
+               $req_ver_hi = $this->COMPATIBILITY_MAX_TBL[$cmd];\r
+\r
+               $mpd_ver = $this->_computeVersionValue($this->mpd_version);\r
+\r
+               if ( $req_ver_low ) {\r
+                       $req_ver = $this->_computeVersionValue($req_ver_low);\r
+\r
+                       if ( $mpd_ver < $req_ver ) {\r
+                               $this->errStr = "Command '$cmd' is not compatible with this version of MPD, version ".$req_ver_low." required";\r
+                               return FALSE;\r
+                       }\r
+               }\r
+\r
+        // Check maxmum compatibility -- this will check for deprecations\r
+               if ( $req_ver_hi ) {\r
+            $req_ver = $this->_computeVersionValue($req_ver_hi);\r
+\r
+                       if ( $mpd_ver > $req_ver ) {\r
+                               $this->errStr = "Command '$cmd' has been deprecated in this version of MPD.";\r
+                               return FALSE;\r
+                       }\r
+               }\r
+\r
+               return TRUE;\r
+       }\r
+\r
+       /* _parseFileListResponse() \r
+        * \r
+        * Builds a multidimensional array with MPD response lists.\r
+     *\r
+        * NOTE: This function is used internally within the class. It should not be used.\r
+        */\r
+       function _parseFileListResponse($resp) {\r
+               if ( is_null($resp) ) {\r
+                       return NULL;\r
+               } else {\r
+                       $plistArray = array();\r
+                       $plistLine = strtok($resp,"\n");\r
+                       $plistFile = "";\r
+                       $plCounter = -1;\r
+                       while ( $plistLine ) {\r
+                               list ( $element, $value ) = explode(": ",$plistLine);\r
+                               if($element == "file" || $element=="directory") {\r
+                                 $plCounter++;\r
+                                 $plistArray[$plCounter]['name']=$value;\r
+                                 $plistArray[$plCounter]['type']=$element; \r
+                                 $plistArray[$plCounter]['title']=$value;\r
+                               }\r
+                               if($element == "Name") {\r
+                                 $plistArray[$plCounter]['title']=$value;\r
+                               }\r
+                               $plistLine = strtok("\n");\r
+                       } \r
+               }\r
+               return $plistArray;\r
+       }\r
+\r
+       /* RefreshInfo() \r
+        * \r
+        * Updates all class properties with the values from the MPD server.\r
+     *\r
+        * NOTE: This function is automatically called upon Connect() as of v1.1.\r
+        */\r
+       function RefreshInfo() {\r
+        // Get the Server Statistics\r
+               $statStr = $this->SendCommand(MPD_CMD_STATISTICS);\r
+               if ( !$statStr ) {\r
+                       return NULL;\r
+               } else {\r
+                       $stats = array();\r
+                       $statLine = strtok($statStr,"\n");\r
+                       while ( $statLine ) {\r
+                               list ( $element, $value ) = explode(": ",$statLine);\r
+                               $stats[$element] = $value;\r
+                               $statLine = strtok("\n");\r
+                       } \r
+               }\r
+\r
+        // Get the Server Status\r
+               $statusStr = $this->SendCommand(MPD_CMD_STATUS);\r
+               if ( ! $statusStr ) {\r
+                       return NULL;\r
+               } else {\r
+                       $status = array();\r
+                       $statusLine = strtok($statusStr,"\n");\r
+                       while ( $statusLine ) {\r
+                               list ( $element, $value ) = explode(": ",$statusLine);\r
+                               $status[$element] = $value;\r
+                               $statusLine = strtok("\n");\r
+                       }\r
+               }\r
+\r
+        // Get the Playlist\r
+               $plStr = $this->SendCommand(MPD_CMD_PLLIST);\r
+               $this->playlist = $this->_parseFileListResponse($plStr);\r
+       $this->playlist_count = count($this->playlist);\r
+\r
+        // Set Misc Other Variables\r
+               $this->state = $status['state'];\r
+               if ( ($this->state == MPD_STATE_PLAYING) || ($this->state == MPD_STATE_PAUSED) ) {\r
+                       $this->current_track_id = $status['song'];\r
+                       list ($this->current_track_position, $this->current_track_length ) = explode(":",$status['time']);\r
+               } else {\r
+                       $this->current_track_id = -1;\r
+                       $this->current_track_position = -1;\r
+                       $this->current_track_length = -1;\r
+               }\r
+\r
+               $this->repeat = $status['repeat'];\r
+               $this->random = $status['random'];\r
+\r
+               $this->db_last_refreshed = $stats['db_update'];\r
+\r
+               $this->volume = $status['volume'];\r
+               $this->uptime = $stats['uptime'];\r
+               $this->playtime = $stats['playtime'];\r
+               $this->num_songs_played = $stats['songs_played'];\r
+               $this->num_artists = $stats['num_artists'];\r
+               $this->num_songs = $stats['num_songs'];\r
+               $this->num_albums = $stats['num_albums'];\r
+               return TRUE;\r
+       }\r
+\r
+    /* ------------------ DEPRECATED METHODS -------------------*/\r
+       /* GetStatistics() \r
+        * \r
+        * Retrieves the 'statistics' variables from the server and tosses them into an array.\r
+     *\r
+        * NOTE: This function really should not be used. Instead, use $this->[variable]. The function\r
+        *   will most likely be deprecated in future releases.\r
+        */\r
+       function GetStatistics() {\r
+               if ( $this->debugging ) echo "mpd->GetStatistics()\n";\r
+               $stats = $this->SendCommand(MPD_CMD_STATISTICS);\r
+               if ( !$stats ) {\r
+                       return NULL;\r
+               } else {\r
+                       $statsArray = array();\r
+                       $statsLine = strtok($stats,"\n");\r
+                       while ( $statsLine ) {\r
+                               list ( $element, $value ) = explode(": ",$statsLine);\r
+                               $statsArray[$element] = $value;\r
+                               $statsLine = strtok("\n");\r
+                       } \r
+               }\r
+               if ( $this->debugging ) echo "mpd->GetStatistics() / return: " . print_r($statsArray) ."\n";\r
+               return $statsArray;\r
+       }\r
+\r
+       /* GetStatus() \r
+        * \r
+        * Retrieves the 'status' variables from the server and tosses them into an array.\r
+     *\r
+        * NOTE: This function really should not be used. Instead, use $this->[variable]. The function\r
+        *   will most likely be deprecated in future releases.\r
+        */\r
+       function GetStatus() {\r
+               if ( $this->debugging ) echo "mpd->GetStatus()\n";\r
+               $status = $this->SendCommand(MPD_CMD_STATUS);\r
+               if ( ! $status ) {\r
+                       return NULL;\r
+               } else {\r
+                       $statusArray = array();\r
+                       $statusLine = strtok($status,"\n");\r
+                       while ( $statusLine ) {\r
+                               list ( $element, $value ) = explode(": ",$statusLine);\r
+                               $statusArray[$element] = $value;\r
+                               $statusLine = strtok("\n");\r
+                       }\r
+               }\r
+               if ( $this->debugging ) echo "mpd->GetStatus() / return: " . print_r($statusArray) ."\n";\r
+               return $statusArray;\r
+       }\r
+\r
+       /* GetVolume() \r
+        * \r
+        * Retrieves the mixer volume from the server.\r
+     *\r
+        * NOTE: This function really should not be used. Instead, use $this->volume. The function\r
+        *   will most likely be deprecated in future releases.\r
+        */\r
+       function GetVolume() {\r
+               if ( $this->debugging ) echo "mpd->GetVolume()\n";\r
+               $volLine = $this->SendCommand(MPD_CMD_STATUS);\r
+               if ( ! $volLine ) {\r
+                       return NULL;\r
+               } else {\r
+                       list ($vol) = sscanf($volLine,"volume: %d");\r
+               }\r
+               if ( $this->debugging ) echo "mpd->GetVolume() / return: $vol\n";\r
+               return $vol;\r
+       }\r
+\r
+       /* GetPlaylist() \r
+        * \r
+        * Retrieves the playlist from the server and tosses it into a multidimensional array.\r
+     *\r
+        * NOTE: This function really should not be used. Instead, use $this->playlist. The function\r
+        *   will most likely be deprecated in future releases.\r
+        */\r
+       function GetPlaylist() {\r
+               if ( $this->debugging ) echo "mpd->GetPlaylist()\n";\r
+               $resp = $this->SendCommand(MPD_CMD_PLLIST);\r
+               $playlist = $this->_parseFileListResponse($resp);\r
+               if ( $this->debugging ) echo "mpd->GetPlaylist() / return ".print_r($playlist)."\n";\r
+               return $playlist;\r
+       }\r
+\r
+    /* ----------------- Command compatibility tables --------------------- */\r
+       var $COMPATIBILITY_MIN_TBL = array(\r
+       );\r
+\r
+    var $COMPATIBILITY_MAX_TBL = array(\r
+    );\r
+\r
+}   // ---------------------------- end of class ------------------------------\r
+?>\r
diff --git a/view/default/tmpl/default.php b/view/default/tmpl/default.php
new file mode 100644 (file)
index 0000000..269b508
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de-de" lang="de-de" >
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+  <title>MPD Player</title>
+  <link rel="stylesheet" href="css/general.css" type="text/css" />
+  <script type="text/javascript" src="ajax/mpd.js"></script>
+</head>
+<body onload="RefreshPageContent()">
+
+<div id="frame">
+
+       <?php include('view/player/view.php');?>
+
+<div id="playlist">
+  <?php include('view/default/tmpl/playlistmenu.php');?>
+  <div id="items">
+  </div>
+  <?php include('view/default/tmpl/playlistmenu.php');?>
+</div>
+
+</div>
+
+<?php
+//print_r($mpd);
+?>
+
+
+</body>
diff --git a/view/default/tmpl/playlistmenu.php b/view/default/tmpl/playlistmenu.php
new file mode 100644 (file)
index 0000000..bc0f8f0
--- /dev/null
@@ -0,0 +1,9 @@
+<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="PlaylistCommand('clear')" ><img width="20" src="images/removeall.png"></span><td>
+                       <td><span class="button" onclick="PlaylistItemsCommand('removeselected')"><img width="20" src="images/removeselected.png"></span><td>
+               </tr>
+        </table>
+</div>
diff --git a/view/default/view.php b/view/default/view.php
new file mode 100644 (file)
index 0000000..12276a0
--- /dev/null
@@ -0,0 +1,4 @@
+<?php
+include('model/tracklist.php');
+include('tmpl/default.php');
+?>
diff --git a/view/player/tmpl/default.php b/view/player/tmpl/default.php
new file mode 100644 (file)
index 0000000..e3c5315
--- /dev/null
@@ -0,0 +1,38 @@
+<div id="playerframe">
+  <div id="nowplaying_heading">
+       <table id="heading_tbl">
+       <tr>
+            <td id="left">Now Playing</td><td id="right"><span onclick="RefreshPageContent()"><img class="button" align="right" width="20" src="images/update.png"></span></td>
+       </tr>
+       </table>
+  </div>
+  <div id="nowplaying_content">
+  </div>
+  <div id="control_buttons">
+    <table>
+      <tr>
+        <td><span onclick="Command('prev')"><img class="button" src="images/previous.png"></span></td>
+        <td>
+          <div id="playpausebutton">
+           <span onclick="Command('pause')"><img class="button" src="images/pause.png"></span>
+          </div>
+       </td>
+        <td><span onclick="Command('stop')"><img class="button" src="images/stop.png"></span></td>
+        <td><span onclick="Command('next')"><img class="button" src="images/next.png"></span></td>
+        <td><span onclick="Command('repeat')"><div id="repeatstate"><img class="button" src="images/repeaton.png"></div></span></td>
+  </tr>
+
+  </table>
+
+  </div>
+
+  <div id="control_volume">
+    <table>
+      <tr>
+        <td><span onclick="Command('vold')"><img class="button" src="images/minus.png"></span></td>
+       <td id="volume_content">Volume:</td><td><div id="volume_total"></div></div></td>
+        <td><span onclick="Command('volu')"><img class="button" src="images/plus.png"></span></td>
+      </tr>
+    </table>
+  </div>
+</div>
diff --git a/view/player/view.php b/view/player/view.php
new file mode 100644 (file)
index 0000000..6cf1b29
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+include('model/player.php');
+include('tmpl/default.php');
+
+?>