Quellcode durchsuchen

izpl 0.10.0 Jukebox remote mode working

LH vor 6 Jahren
Ursprung
Commit
940a6ab335

+ 1 - 1
iZpl/build.gradle

@@ -10,7 +10,7 @@ apply plugin: 'java'
 apply plugin: 'application'
 apply from: "$rootDir/utils/IO.gradle"
 
-version = '0.10.0.0-snapshot'
+version = '0.10.0.0'
 mainClassName = 'de.nplusc.izc.iZpl.Main'
 //'de.nplusc.izc.iZpl.Main'
 

+ 6 - 0
iZpl/src/main/java/de/nplusc/izc/iZpl/API/PlaybackPlugin.java

@@ -67,6 +67,12 @@ public interface PlaybackPlugin extends Plugin
      */
     public void connectToPlayer();
     
+    /**
+     * Gets the current playing status
+     * @return true if the player is playing.
+     */
+    public boolean playingStatus();
+    
     /**
      * Registers a JPanel for being used as a Playback surface, (optional)
      * @param p Panel used as target for the video

+ 6 - 0
iZpl/src/main/java/de/nplusc/izc/iZpl/Utils/VlcInterface.java

@@ -531,6 +531,12 @@ public class VlcInterface implements PlaybackPlugin , MediaPlayerEventListener
     {
     }
 
+    @Override
+    public boolean playingStatus()
+    {
+        return isPlaying;
+    }
+
 
     
     

+ 112 - 106
iZplPlugins/ITunes/src/main/java/de/nplusc/izpl/plugins/itunes/ITunesAPI.java

@@ -1,106 +1,112 @@
-/*
- * Copyright (C) 2015 iZc
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package de.nplusc.izpl.plugins.itunes;
-
-import de.nplusc.izc.iZpl.API.shared.PlayListItem;
-import de.nplusc.izc.iZpl.API.PlaybackPlugin;
-import java.io.File;
-/**
- *
- * @author iZc <nplusc.de>
- */
-public class ITunesAPI implements PlaybackPlugin
-{
-    
-    
-    
-    
-    
-    @Override
-    public void setTitleToPlay(PlayListItem i)
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public int getLengthInSeconds()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public int getPosition()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void seek(int sekunde)
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void skipTitle()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void play()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void pause()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public PlayListItem getCurrentTitle()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void connectToPlayer()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public String getPluginName()
-    {
-        return "ITunes ActiveX Interface";
-    }
-
-    @Override
-    public void initializePlugin()
-    {
-        //TODO EXTRACT NATIVES
-    }
-
-    @Override
-    public void prepareUpgrade()
-    {
-        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-    
-}
+/*
+ * Copyright (C) 2015 iZc
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.nplusc.izpl.plugins.itunes;
+
+import de.nplusc.izc.iZpl.API.shared.PlayListItem;
+import de.nplusc.izc.iZpl.API.PlaybackPlugin;
+import java.io.File;
+/**
+ *
+ * @author iZc <nplusc.de>
+ */
+public class ITunesAPI implements PlaybackPlugin
+{
+    
+    
+    
+    
+    
+    @Override
+    public void setTitleToPlay(PlayListItem i)
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public int getLengthInSeconds()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public int getPosition()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void seek(int sekunde)
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void skipTitle()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void play()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void pause()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public PlayListItem getCurrentTitle()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void connectToPlayer()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public String getPluginName()
+    {
+        return "ITunes ActiveX Interface";
+    }
+
+    @Override
+    public void initializePlugin()
+    {
+        //TODO EXTRACT NATIVES
+    }
+
+    @Override
+    public void prepareUpgrade()
+    {
+        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public boolean playingStatus()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+    
+}

+ 1 - 1
iZplPlugins/JukeBox/build.gradle

@@ -3,7 +3,7 @@ apply plugin:'java'
 apply plugin: 'application'
 apply from: "$rootDir/utils/IO.gradle"
 
-version = '0.10.0.0-snapshot'
+version = '0.10.0.0'
 mainClassName = 'de.nplusc.izc.izpl.plugins.jukebox.StandaloneMain'
 
 //task distZip(dependsOn: 'jar') {

+ 7 - 1
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/Backend.java

@@ -23,7 +23,7 @@ import java.util.List;
  *
  * @author iZc <nplusc.de>
  */
-public interface Backend
+public interface Backend extends PlaybackStatusUpdater
 {
     void play();
     void pause();
@@ -36,6 +36,12 @@ public interface Backend
     
     void reload();
     
+    String getTitle();
+    
+    int getTrackLength();
+    boolean getPlaybackStatus();
+    
+    default void sync(){};
     String[] getTitles() throws InvalidPlayListFileException;
     List<String> getScheduledTracks();
     

+ 42 - 129
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeBox.java

@@ -36,18 +36,24 @@ import org.apache.logging.log4j.Logger;
  *
  * @author tgoerner
  */
-public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListener,FeaturePlugin,PlaybackStatusUpdater
+public class JukeBox extends javax.swing.JFrame implements MouseListener,PlaybackStatusUpdater
 {
     public static final int JUKEBOX_PORT=0x6767;
-    private Backend jukeboxBackend;
     private static final Logger l = LogManager.getLogger();
+    private Backend backend;
     /**
      * Creates new form JukeBoxGUI
      */
-    public JukeBox(JukeBoxPlugin p)
+    public JukeBox()
     {
     }
 
+    public void setBackend(Backend b)
+    {
+        backend = b;
+    }
+    
+    
     /**
      * This method is called from within the constructor to initialize the form.
      * WARNING: Do NOT modify this code. The content of this method is always
@@ -212,9 +218,10 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
         }
         if((modified&evt.ALT_MASK)!=0)
         {
-            jukeboxBackend.quitWithSave();
+            APIWrapper.quickQuit();
         }
-        jukeboxBackend.skip();
+        backend.skip();
+        
     }//GEN-LAST:event_btnSkipActionPerformed
 
     private void btnPlayPauseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnPlayPauseActionPerformed
@@ -229,50 +236,23 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
         int index = (Integer)((DefaultTableModel)tblPLE.getModel()).getValueAt(viewRow,0);
         if(index>=0)
         {
-            jukeboxBackend.enqueue(index);
+            backend.enqueue(index);
         }
     }//GEN-LAST:event_btnEnqueueActionPerformed
 
     private void btnReloadActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnReloadActionPerformed
     {//GEN-HEADEREND:event_btnReloadActionPerformed
-        jukeboxBackend.reload();
+        backend.reload();
         rebuildTable(false);
     }//GEN-LAST:event_btnReloadActionPerformed
-    
-    @Override
-    public String getPluginName()
-    {
-        return "JukeBox";
-    }
 
-    @Override
-    public void initializePlugin()
-    {
-        if(APIWrapper.getUiPlugin()==this)
-        {
-            l.info("Init UI(JukeBox)");
-            jukeboxBackend= new LocalBackend(this);
-        }
-        else
-        {
-            l.info("Loaded as featurePlugin or standalone, delaying the init");
-        }
-               
-    }
-
-    @Override
-    public void prepareUpgrade()
-    {
-        /*nothing to do for this plugin*/
-    }
-    
     private void rebuildTable(boolean recovery)
     {
         try
         {
             //mdl.setAllColumnsVisible();
             
-            String[] titles = jukeboxBackend.getTitles();
+            String[] titles = backend.getTitles(); //TODO
             for(int i=tblPLE.getRowCount()-1;i>0;i--)
             {
                 ((DefaultTableModel)tblPLE.getModel()).removeRow(i-1);
@@ -302,7 +282,7 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
                 APIWrapper.quickQuit();//this should not happen at all on remote
             }
             //reloading data from disk and flushing internal references when the resume state got corrupted from a encoding change
-            jukeboxBackend.reload();
+            backend.reload();
             rebuildTable(recovery);
         }
         //mdl.setColumnVisible(0, false);
@@ -328,40 +308,25 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
         if(e.getSource()==seekBar)
         {
              
-            jukeboxBackend.seek(seekBar.getValue());
+            backend.seek(seekBar.getValue());
         }
     }
 
     @Override
     public void mousePressed(MouseEvent e)
     {
-        if(e.getSource()==seekBar)
-        {
-            jukeboxBackend.pause();
-        }
     }
     @Override
     public void mouseReleased(MouseEvent e)
     {
         if(e.getSource()==seekBar)
         {
-            jukeboxBackend.seek(seekBar.getValue());
-            if(playing)
-            {
-                jukeboxBackend.play();
-            }
+            backend.seek(seekBar.getValue());
         }
     }
     
     
-    @Override
-    public void setAlbumArt(Image i)
-    {
-        //not used for the JukeBox so far
-    }
-    
     private String trackTime = "--:--";
-    @Override
     public void setTrackLength(int seconds)
     {
         int mins=seconds/60;
@@ -371,7 +336,6 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
         EventQueue.invokeLater(()->seekBar.setMaximum(seconds));
     }
     
-    @Override
     public void setPlaybackPositionInSeconds(int seconds)
     {
         EventQueue.invokeLater(() ->
@@ -379,30 +343,24 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
             int mins=seconds/60;
             int textSeconds=seconds%60;
             String textSeconds2=textSeconds>9?textSeconds+"":"0"+textSeconds;
-            lblStatus.setText(mins+":"+textSeconds2+"/"+trackTime);
-            seekBar.setValue(seconds);
+            if(lblStatus!=null)
+            {
+                lblStatus.setText(mins+":"+textSeconds2+"/"+trackTime);
+                seekBar.setValue(seconds);
+            }
         });
     }
     
-    @Override
     public void setTrackName(String trackName)
     {
         EventQueue.invokeLater(()->lblTrackName.setText(trackName));
-        EventQueue.invokeLater(()->rebuildTable(false));
+        // EventQueue.invokeLater(()->rebuildTable(false)); normal nötig, aber da die JukeBox die Spalte für die Playcounts nicht braucht genullroutet
     }
     
-
-    @Override
-    public void loadPlayListEditScreen()
-    {
-        /*NO-OP*/
-    }
-
     
     private HidableTableColumnModel mdl = null;
     
     
-    @Override
     public void initializeUI()
     {
         boolean onARM = Detectors.getSystemClassification()[1].equals("arm");
@@ -430,7 +388,7 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
             @Override
             public void windowClosing(WindowEvent e)
             {
-                jukeboxBackend.quitWithSave();
+                //TODO
             }
         });
         seekBar.addMouseListener(this);
@@ -456,30 +414,34 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
         // selectedPlaybackPlugin.registerVideoSurface(videoPanel);
         //TODO: HAX für RPi mit ProjectM-SDL/PulseAudio fullscreen. 
         // HW-Incompat, Requires different HW
-        jukeboxBackend.reload();
+        //TODO jukeboxBackend.reload();
+        backend.sync();
         rebuildTable(false);
+        
+    }
+    public void refreshScheduledItemList()
+    {
+        EventQueue.invokeLater(()->{
+            DefaultListModel<String> model = (DefaultListModel<String>) lstScheduled.getModel();
+            model.clear();
+            List<String> items = backend.getScheduledTracks();
+            items.forEach((e)->{model.addElement(e);});
+        });
     }
     
-    
-    private boolean connected=false;
     private boolean playing=false;
     
     private void play()
     {
-        if(!connected)
-        {
-            jukeboxBackend.initBackend();
-            connected=true;
-        }
         if(playing)
         {
-            jukeboxBackend.pause();
+            backend.pause();
             btnPlayPause.setText("Play");
             playing=false;
         }
         else
         {
-            jukeboxBackend.play();
+            backend.play();
             btnPlayPause.setText("Pause");
             playing=true;
         }
@@ -495,53 +457,6 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
     {
     }
 
-    @Override
-    public void refreshScheduledItemList()
-    {
-        EventQueue.invokeLater(()->{
-            DefaultListModel<String> model = (DefaultListModel<String>) lstScheduled.getModel();
-            model.clear();
-            List<String> items = jukeboxBackend.getScheduledTracks();
-            items.forEach((e)->{model.addElement(e);});
-        });
-    }
-
-    @Override
-    public void reloadPlayList()
-    {
-        EventQueue.invokeLater(()->this.rebuildTable(false));
-    }
-
-    @Override
-    public void parseParameter(String param)
-    {
-
-    }
-
-    @Override
-    public boolean hasUserInterface()
-    {
-        return true;
-    }
-
-    @Override
-    public void openUserInterface()
-    {
-        initializeUI();
-        EventQueue.invokeLater(()->this.setVisible(true));
-    }
-
-    @Override
-    public boolean requiresLoadedPlayList()
-    {
-        return false; //not needed since it connects via Network to the Real jukebox
-    }
-
-    
-    
-    
-    
-    //compat stub for the backend
     @Override
     public void updateTrackLength(int length)
     {
@@ -563,7 +478,7 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
     @Override
     public void triggerTableRefresh()
     {
-        EventQueue.invokeLater(()->rebuildTable(false));
+        rebuildTable(false);
     }
 
     @Override
@@ -575,9 +490,7 @@ public class JukeBox extends javax.swing.JFrame implements UIPlugin,MouseListene
     @Override
     public void setPlayStatus(boolean playing)
     {
-        this.playing = playing;
-        btnPlayPause.setText(playing?"Pause":"play");
+        this.playing=playing;
+        btnPlayPause.setText(playing?"Pause":"Play");
     }
-    
-    
 }

+ 28 - 32
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeBoxPlugin.java

@@ -26,14 +26,11 @@ import org.apache.logging.log4j.Logger;
  *
  * @author iZc <nplusc.de>
  */
-public class JukeBoxPlugin implements UIPlugin,FeaturePlugin
+public class JukeBoxPlugin implements UIPlugin, FeaturePlugin
 {
-    
-    private Backend jukeboxBackend;
     private static final Logger l = LogManager.getLogger();
-    private JukeBox jukebox;
-    
-    
+    private Backend backend;
+    private JukeBox frontend = new JukeBox();
     @Override
     public void setAlbumArt(Image image)
     {
@@ -41,51 +38,51 @@ public class JukeBoxPlugin implements UIPlugin,FeaturePlugin
     }
 
     @Override
-    public void setTrackLength(int i)
+    public void setTrackLength(int length)
     {
-        //jukeboxBackend.
+        backend.updateTrackLength(length);
     }
 
     @Override
-    public void setPlaybackPositionInSeconds(int i)
+    public void setPlaybackPositionInSeconds(int position)
     {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        backend.updateCurrentPlaybackPosition(position);
     }
 
     @Override
-    public void setVisible(boolean bln)
+    public void setVisible(boolean visible)
     {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        frontend.setVisible(visible);
     }
 
     @Override
-    public void setTrackName(String string)
+    public void setTrackName(String title)
     {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        backend.updateTrackTitle(title);
     }
 
     @Override
     public void loadPlayListEditScreen()
     {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        // NOP; nicht in diesem fall
     }
 
     @Override
     public void initializeUI()
     {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        frontend.initializeUI();
     }
 
     @Override
     public void refreshScheduledItemList()
     {
-        UIPlugin.super.refreshScheduledItemList(); //To change body of generated methods, choose Tools | Templates.
+        backend.triggerScheduleRefresh();
     }
 
     @Override
     public void reloadPlayList()
     {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        backend.triggerTableRefresh();
     }
 
     @Override
@@ -99,13 +96,12 @@ public class JukeBoxPlugin implements UIPlugin,FeaturePlugin
     {
         if(APIWrapper.getUiPlugin()==this)
         {
-            l.info("Init UI(JukeBox)");
-            jukebox = new JukeBox(this);
-            jukeboxBackend= new LocalBackend(jukebox);
+            backend = new LocalBackend(frontend);
+            frontend.setBackend(backend);
         }
         else
         {
-            l.info("Loaded as featurePlugin or standalone, delaying the init");
+            
         }
     }
 
@@ -118,17 +114,18 @@ public class JukeBoxPlugin implements UIPlugin,FeaturePlugin
     @Override
     public void parseParameter(String param)
     {
-        if(param!=null&&!param.equals(""))
+        l.trace("Load PLugin JukeBox with Param{}:",param);
+        if(param!=null &&! param.equals(""))
         {
-            jukebox = new JukeBox(this);
-            jukeboxBackend = new RemoteBackend(param, jukebox);
-            jukeboxBackend.initBackend();
+            
+            backend = new RemoteBackend(param,frontend);
+            frontend.setBackend(backend);
+            backend.initBackend();
             openUserInterface();
+            setVisible(true);
+            l.trace("Plugin should be open now");
         }
-        else
-        {
-            l.error("Invalid parameter");
-        }
+        
     }
 
     @Override
@@ -140,8 +137,7 @@ public class JukeBoxPlugin implements UIPlugin,FeaturePlugin
     @Override
     public void openUserInterface()
     {
-        //TODO Dialog für IP-abfrage bei GUI-launch
-        jukebox.openUserInterface();
+        frontend.initializeUI();
     }
 
     @Override

+ 57 - 24
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeboxClientHandler.java

@@ -25,7 +25,9 @@ import java.io.PrintStream;
 import java.net.Socket;
 import java.nio.charset.Charset;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Queue;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.yaml.snakeyaml.Yaml;
@@ -39,7 +41,7 @@ public class JukeboxClientHandler
     private Socket sck;
     private JukeboxServer srv;
     private static final Logger l = LogManager.getLogger();
-    private String returnMsg = "";
+    private Queue<String> returnMsgs = new LinkedList<>();
     public JukeboxClientHandler(Socket s,JukeboxServer srv)
     {
         sck=s;
@@ -93,10 +95,13 @@ public class JukeboxClientHandler
                             sck.wait();
                         } catch (InterruptedException ex) {
                         }
-                        out.println(returnMsg);
-                        out.flush();
-                        returnMsg="";
-                        l.info("MSG sent back");
+                        while(!returnMsgs.isEmpty())
+                        {
+                            out.println(returnMsgs.poll());
+                            out.flush();
+                            l.trace("MSG sent back");
+                        }
+                        l.trace("End of Messages package");
                     }
                 }
             });
@@ -109,8 +114,10 @@ public class JukeboxClientHandler
     public void respondToLinkedClient(Packet response) {
         synchronized(sck)
         {
-            l.info("Response");
-            returnMsg=new Yaml().dump(response)+"\n---\n";
+            l.trace("Response");
+            String returnMsg = new Yaml().dump(response)+"\n---\n";
+            returnMsgs.add(returnMsg);
+            l.trace(returnMsg);
             sck.notify();
         }
     }
@@ -127,6 +134,9 @@ public class JukeboxClientHandler
             case "play":
                 srv.play();
                 break;
+            case "sync":
+                sync();
+                break;
             case "pause":
                 srv.pause();
                 break;
@@ -143,6 +153,7 @@ public class JukeboxClientHandler
                 {
                     //TODO error
                 }
+                break;
             case "enqueue":
                 try
                 {
@@ -153,28 +164,30 @@ public class JukeboxClientHandler
                 {
                     //TODO error
                 }
+                break;
             case "reload":
                 srv.reload();
+                break;
             case "getTitles":
-            {
-                try
                 {
-                    String[] titles = srv.getTitles();
-                    HashMap<String,Object> data = new HashMap<>();
-                    Packet response = new Packet();
-                    data.put("RESPONSE", "TITLES");
-                    data.put("DATA", titles);
-                    response.setData(data);
-                    respondToLinkedClient(response);
-                    
-                    
-                }
-                catch (InvalidPlayListFileException ex)
-                {
-                    ex.printStackTrace();
+                    try
+                    {
+                        String[] titles = srv.getTitles();
+                        HashMap<String,Object> data = new HashMap<>();
+                        Packet response = new Packet();
+                        data.put("RESPONSE", "TITLES");
+                        data.put("DATA", titles);
+                        response.setData(data);
+                        respondToLinkedClient(response);
+
+
+                    }
+                    catch (InvalidPlayListFileException ex)
+                    {
+                        ex.printStackTrace();
+                    }
                 }
-            }
-            break;
+                break;
             case "getScheduled":
                 List<String> titles = srv.getScheduledTracks();
                 HashMap<String,Object> data = new HashMap<>();
@@ -183,8 +196,28 @@ public class JukeboxClientHandler
                 data.put("DATA", titles);
                 response.setData(data);
                 respondToLinkedClient(response);
+                break;
             default:
                 break;
         }
     }
+    private void sync()
+    {
+        l.info("SYNC");
+        Packet titles = srv.createUpdatePackage("TRACKS","");
+        respondToLinkedClient(titles);
+        l.trace("SNYC Tracks");
+        Packet queue = srv.createUpdatePackage("QUEUE","");
+        respondToLinkedClient(queue);
+        l.trace("SNYC QUEUE");
+        Packet title = srv.createUpdatePackage("TITLE",srv.getTitle());
+        respondToLinkedClient(title);
+        l.trace("SNYC LENGTH");
+        Packet length = srv.createUpdatePackage("LENGTH",srv.getTrackLength()+"");
+        respondToLinkedClient(length);
+        l.trace("SNYC PLAYING");
+        Packet playbackStatus = srv.createUpdatePackage("PLAYING",srv.getPlaybackStatus()+"");
+        respondToLinkedClient(playbackStatus);
+        l.info("SYNC finished");
+    }
 }

+ 31 - 4
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeboxServer.java

@@ -58,11 +58,15 @@ public class JukeboxServer implements PlaybackStatusUpdater,Backend
             while(true)
             {
                 Socket socket = serverSocket.accept();
+                
+                
                 Thread t = new Thread(()->{
                    JukeboxClientHandler c =  new JukeboxClientHandler(socket,this);
                    c.start();
                    currentClients.add(c);
                 });
+                
+                
                 t.setName("protocolParser-"+socket.getRemoteSocketAddress());
                 t.start();
             }
@@ -77,6 +81,12 @@ public class JukeboxServer implements PlaybackStatusUpdater,Backend
     
     
     private void sendUpdate(String action,String value)
+    {
+        final Packet response = createUpdatePackage(action, value);
+        currentClients.forEach((c->c.respondToLinkedClient(response)));
+    }
+    
+    Packet createUpdatePackage(String action,String value)
     {
         HashMap<String,Object> data = new HashMap<>();
         final Packet response = new Packet();
@@ -84,11 +94,9 @@ public class JukeboxServer implements PlaybackStatusUpdater,Backend
         data.put("TOPIC", action);
         data.put("VALUE", value);
         response.setData(data);
-        currentClients.forEach((c->c.respondToLinkedClient(response)));
+        return response;
     }
     
-    
-    
     @Override
     public void setPlayStatus(boolean playing)
     {
@@ -110,7 +118,7 @@ public class JukeboxServer implements PlaybackStatusUpdater,Backend
     @Override
     public void updateCurrentPlaybackPosition(int position)
     {
-        sendUpdate("POSTITION",position+"");
+        sendUpdate("POSITION",position+"");
     }
 
     @Override
@@ -187,5 +195,24 @@ public class JukeboxServer implements PlaybackStatusUpdater,Backend
     {
         //stubbed, not a real backend
     }
+
+    @Override
+    public String getTitle()
+    {
+        return backend.getTitle();
+    }
+
+    @Override
+    public boolean getPlaybackStatus()
+    {
+        return backend.getPlaybackStatus();
+    }
+
+    @Override
+    public int getTrackLength()
+    {
+        return backend.getTrackLength();
+    }
+    
     
 }

+ 92 - 1
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/LocalBackend.java

@@ -21,6 +21,7 @@ import de.nplusc.izc.iZpl.API.PlayListEditAPI;
 import de.nplusc.izc.iZpl.API.PlaybackPlugin;
 import de.nplusc.izc.iZpl.API.shared.InvalidPlayListFileException;
 import de.nplusc.izc.iZpl.API.shared.PlayListItem;
+import de.nplusc.izc.iZpl.API.shared.SinglePlayListItem;
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
@@ -33,6 +34,8 @@ import org.apache.logging.log4j.Logger;
  */
 public class LocalBackend implements Backend
 {
+    private boolean connected = false;
+    private int trackLength = 0;
     private PlaybackPlugin selectedPlaybackPlugin;
     private static final Logger l = LogManager.getLogger();
     private PlaybackStatusUpdater u;
@@ -47,6 +50,7 @@ public class LocalBackend implements Backend
         t.setName("serverMain");
         t.start();
         l.info("Loaded Server");
+        server = s;
     }
     
     @Override
@@ -85,11 +89,17 @@ public class LocalBackend implements Backend
     @Override
     public void play()
     {
+        if(!connected)
+        {
+            l.info("Initializing the PlaybackBackend");
+            initBackend();
+            connected=true;
+        }
+        
         selectedPlaybackPlugin.play();
         u.setPlayStatus(true);
         server.setPlayStatus(true);
     }
-
     @Override
     public void pause()
     {
@@ -120,5 +130,86 @@ public class LocalBackend implements Backend
         items.forEach((e)->{results.add(PlayListEditAPI.getTitle(e));});
         return results;
     }
+
+    @Override
+    public void updateTrackLength(int length)
+    {
+        trackLength = length;
+        u.updateTrackLength(length);
+        server.updateTrackLength(length);
+    }
+
+    @Override
+    public void updateTrackTitle(String title)
+    {
+        u.updateTrackTitle(title);
+        server.updateTrackTitle(title);
+    }
+
+    @Override
+    public void updateCurrentPlaybackPosition(int position)
+    {
+        u.updateCurrentPlaybackPosition(position);
+        server.updateCurrentPlaybackPosition(position);
+    }
+
+    @Override
+    public void triggerTableRefresh()
+    {
+        u.triggerTableRefresh();
+        server.triggerTableRefresh();
+    }
+
+    @Override
+    public void triggerScheduleRefresh()
+    {
+        u.triggerScheduleRefresh();
+        server.triggerScheduleRefresh();
+    }
+
+    @Override
+    public void setPlayStatus(boolean playing)
+    {
+        u.setPlayStatus(playing);
+        server.setPlayStatus(playing);
+    }
+
+    @Override
+    public String getTitle()
+    {
+        PlayListItem next = selectedPlaybackPlugin.getCurrentTitle();
+        if(next == null)
+        {
+            return "-- No Track --";
+        }
+        if(next instanceof SinglePlayListItem)
+            {
+                String t = ((SinglePlayListItem) next).getTitle();
+                if (t != null && !t.equals(""))
+                {
+                     return t.split(",")[1];
+                }
+                else
+                {
+                    return((SinglePlayListItem) next).getPath();
+                }
+            }
+            else
+            {
+                return "MultiItem";
+            }
+    }
+            
+    @Override
+    public boolean getPlaybackStatus()
+    {
+        return selectedPlaybackPlugin.playingStatus();
+    }
+
+    @Override
+    public int getTrackLength()
+    {
+        return trackLength;
+    }
     
 }

+ 79 - 11
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/RemoteBackend.java

@@ -26,7 +26,9 @@ import java.net.Socket;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Queue;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.yaml.snakeyaml.Yaml;
@@ -40,10 +42,13 @@ public class RemoteBackend implements Backend
     Socket sck;
     private static final Logger l = LogManager.getLogger();
     private final String targetIP;
-    private String returnMsg = "";
+    private Queue<String> returnMsgs = new LinkedList<>();
     private PlaybackStatusUpdater frontend;
     private String[] titles = {};
     private List<String> schedule = new ArrayList<>();
+    private String currentTrack = "-- Not synced --";
+    private int trackLength = 0;
+    private boolean playing = false;
     public RemoteBackend(String target, PlaybackStatusUpdater frontend)
     {
         targetIP = target;
@@ -127,10 +132,14 @@ public class RemoteBackend implements Backend
                             } catch (InterruptedException ex) {
                             }
                             l.trace("MSG sent");
-                            l.trace("PKT="+returnMsg);
-                            out.println(returnMsg);
-                            out.flush();
-                            returnMsg="";
+                            while(!returnMsgs.isEmpty())
+                            {
+                                String returnMsg = returnMsgs.poll();
+                                l.trace("PKT="+returnMsg);
+                                out.println(returnMsg);
+                                out.flush();
+                            }
+                            l.trace("end of MessageStream");
                         }
                     }
                     //System.out.println("Flucht ist zwecklos");
@@ -146,7 +155,6 @@ public class RemoteBackend implements Backend
         {   
             ex.printStackTrace();
         }
-       
     }
 
     @Override
@@ -164,7 +172,7 @@ public class RemoteBackend implements Backend
     @Override
     public void reload()
     {
-        sendCommand("reload", null);
+        //sendCommand("reload", null);
         sendCommand("getTitles", null); //TODO
         sendCommand("getScheduled", null); //TODO
     }
@@ -198,7 +206,7 @@ public class RemoteBackend implements Backend
         request.setData(data);
         synchronized(targetIP)
          {
-             returnMsg=new Yaml().dump(request)+"\n---\n";
+             returnMsgs.add(new Yaml().dump(request)+"\n---\n");
              targetIP.notify();
          }
     }
@@ -223,7 +231,7 @@ public class RemoteBackend implements Backend
                                 frontend.updateTrackLength(Integer.valueOf(param));
                                 break;
                             case "TITLE":
-                                frontend.updateTrackTitle(topic);
+                                frontend.updateTrackTitle(param);
                                 break;
                             case "POSITION":
                                 frontend.updateCurrentPlaybackPosition(Integer.valueOf(param));
@@ -252,7 +260,67 @@ public class RemoteBackend implements Backend
             }
             
         }
-        
-        
+    }
+    
+    @Override
+    public void updateTrackLength(int length)
+    {
+        frontend.updateTrackLength(length);
+    }
+
+    @Override
+    public void updateTrackTitle(String title)
+    {
+        frontend.updateTrackTitle(title);
+        currentTrack = title;
+    }
+
+    @Override
+    public void updateCurrentPlaybackPosition(int position)
+    {
+        frontend.updateCurrentPlaybackPosition(position);
+    }
+
+    @Override
+    public void triggerTableRefresh()
+    {
+        frontend.triggerTableRefresh();
+    }
+
+    @Override
+    public void triggerScheduleRefresh()
+    {
+        frontend.triggerScheduleRefresh();
+    }
+
+    @Override
+    public void setPlayStatus(boolean playing)
+    {
+        frontend.setPlayStatus(playing);
+        this.playing = playing;
+    }
+
+    @Override
+    public String getTitle()
+    {
+        return currentTrack;
+    }
+
+    @Override
+    public boolean getPlaybackStatus()
+    {
+        return playing;
+    }
+    
+    @Override
+    public void sync()
+    {
+        sendCommand("sync", null);
+    }
+
+    @Override
+    public int getTrackLength()
+    {
+        return trackLength;
     }
 }

+ 26 - 2
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/StandaloneMain.java

@@ -24,7 +24,31 @@ public class StandaloneMain
 {
     public static void main(String[] args)
     {
-        JukeBoxPlugin jbx = new JukeBoxPlugin();
-        jbx.parseParameter(args[0]);
+        /* Set the Nimbus look and feel */
+        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
+        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
+         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
+         */
+        try
+        {
+            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
+            {
+                if ("Nimbus".equals(info.getName()))
+                {
+                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
+                    break;
+                }
+            }
+        }
+        catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex)
+        {
+
+        }
+
+        //</editor-fold>
+        
+        JukeBoxPlugin p = new JukeBoxPlugin();
+        p.parseParameter(args[0]); //TODO verboseLogging etc
+        
     }
 }

+ 1 - 1
iZplPlugins/JukeBox/src/main/resources/plugin.yml

@@ -1,4 +1,4 @@
-pluginbaseclass: de.nplusc.izc.izpl.plugins.jukebox.JukeBox
+pluginbaseclass: de.nplusc.izc.izpl.plugins.jukebox.JukeBoxPlugin
 supportedoses:
   - 'windows'
   - 'mac'

+ 6 - 0
iZplPlugins/WMP/src/main/java/de/nplusc/izc/izpl/plugins/wmp/WMPNAtive.java

@@ -175,5 +175,11 @@ public class WMPNAtive implements PlaybackPlugin
     {
         //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
     }
+
+    @Override
+    public boolean playingStatus()
+    {
+       return isPlaying;
+    }
     
 }

+ 111 - 105
iZplPlugins/foobar2000_others/src/main/java/de/nplusc/izpl/plugins/FooBar2k/WMPNAtive.java → iZplPlugins/foobar2000_others/src/main/java/de/nplusc/izpl/plugins/FooBar2k/Foobar2000.java

@@ -1,105 +1,111 @@
-/*
- * Copyright (C) 2015 iZc
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package de.nplusc.izpl.plugins.FooBar2k;
-
-import de.nplusc.izc.iZpl.API.shared.PlayListItem;
-import de.nplusc.izc.iZpl.API.PlaybackPlugin;
-/**
- *
- * @author iZc <nplusc.de>
- */
-public class WMPNAtive implements PlaybackPlugin
-{
-    
-    
-    
-    
-    
-    @Override
-    public void setTitleToPlay(PlayListItem i)
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public int getLengthInSeconds()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public int getPosition()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void seek(int sekunde)
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void skipTitle()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void play()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void pause()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public PlayListItem getCurrentTitle()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void connectToPlayer()
-    {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public String getPluginName()
-    {
-        return "WMP ActiveX Interface";
-    }
-
-    @Override
-    public void initializePlugin()
-    {
-        //TODO EXTRACT NATIVES
-    }
-
-    @Override
-    public void prepareUpgrade()
-    {
-        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-    
-}
+/*
+ * Copyright (C) 2015 iZc
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.nplusc.izpl.plugins.FooBar2k;
+
+import de.nplusc.izc.iZpl.API.shared.PlayListItem;
+import de.nplusc.izc.iZpl.API.PlaybackPlugin;
+/**
+ *
+ * @author iZc <nplusc.de>
+ */
+public class Foobar2000 implements PlaybackPlugin
+{
+    
+    
+    
+    
+    
+    @Override
+    public void setTitleToPlay(PlayListItem i)
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public int getLengthInSeconds()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public int getPosition()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void seek(int sekunde)
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void skipTitle()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void play()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void pause()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public PlayListItem getCurrentTitle()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void connectToPlayer()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public String getPluginName()
+    {
+        return "WMP ActiveX Interface";
+    }
+
+    @Override
+    public void initializePlugin()
+    {
+        //TODO EXTRACT NATIVES
+    }
+
+    @Override
+    public void prepareUpgrade()
+    {
+        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public boolean playingStatus()
+    {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+    
+}