From 4d16fb3576e60a2a5da6f7bfe396a555010dfa79 Mon Sep 17 00:00:00 2001
From: ulrich
Date: Fri, 22 Nov 2024 18:32:35 +0000
Subject: [PATCH] Buildscript und readme angepasst.

---
 src/de/uhilger/tango/api/MediaSteuerung.java |  148 ++++++++++++++++++++++++++++++++++++------------
 1 files changed, 110 insertions(+), 38 deletions(-)

diff --git a/src/de/uhilger/tango/api/MediaSteuerung.java b/src/de/uhilger/tango/api/MediaSteuerung.java
index 37e0d9e..e6ce428 100644
--- a/src/de/uhilger/tango/api/MediaSteuerung.java
+++ b/src/de/uhilger/tango/api/MediaSteuerung.java
@@ -19,12 +19,11 @@
 
 import com.google.gson.Gson;
 import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.tango.App;
+import de.uhilger.tango.PlaylistListener;
 import de.uhilger.tango.Server;
 import de.uhilger.tango.entity.Abspielvorgang;
 import de.uhilger.tango.entity.Abspieler;
 import de.uhilger.tango.entity.Abspielliste;
-import de.uhilger.tango.entity.Einstellung;
 import de.uhilger.tango.entity.Entity;
 import de.uhilger.tango.entity.Livestream;
 import de.uhilger.tango.entity.Titel;
@@ -33,8 +32,11 @@
 import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -44,47 +46,74 @@
  * Abspielgeraet.
  *
  * HTTP GET /mz/api/strg/abspieler/play/liste/[name] 
+ * HTTP GET /mz/api/strg/abspieler/next
  * HTTP GET /mz/api/strg/abspieler/ende
  *
  * HTTP POST /mz/api/strg/abspieler/play/titel mit dem Titel im Body
  * HTTP POST /mz/api/strg/abspieler/play/stream mit dem Livestream im Body (nur Name gefuellt)
+ * 
+ * DEPRECATED: HTTP POST /mz/api/strg/abspieler/weiter/titel mit dem Titel im Body
  *
  * HTTP GET /mz/api/strg/abspieler/pause 
  * HTTP GET /mz/api/strg/abspieler/stop 
- * HTTP GET /mz/api/strg/abspieler/weiter
+ * HTTP GET /mz/api/strg/abspieler/seek/[sekunden]
  * 
  * Faustregel: Anzahl Elemente eines URL plus 1 ist die Anzahl der Elemente des 
  * Ergebnisses von String.split.
  *
+ * Mit der Funktion ende liefert die MediaSteuerung die Moeglichkeit, Titel aus 
+ * einer Abspielliste gesteuert von Tango abzuspielen. Die Nutzung der Funktion wird 
+ * ausgeloest vom Aufruf an abspieler/play/liste/[name]. Tango erwartet dann von einem 
+ * Abspieler die Rueckmeldung, dass dieser den zuletzt von Tango an den 
+ * Abspieler zum Abspielen uebermittelten Titel zuende abgespielt hat. Tango 
+ * uebergibt dem Abspieler dann den naechsten Titel, bis die Abspielliste zuende ist.
+ * 
+ * Diese Form unterscheidet sich vom Abspielen einer Abspielliste als einzelner 
+ * Stream, wie es vom StreamHandler realisiert wird.
  *
  * @author Ulrich Hilger
  * @version 1, 9.4.2021
  */
-public class MediaSteuerung extends AbstractHandler {
+public class MediaSteuerung extends AbstractHandler implements PlaylistListener {
 
   private static final Logger logger = Logger.getLogger(MediaSteuerung.class.getName());
 
   public static final String PL_CMD_PLAY = "play";
+  public static final String PL_CMD_SEEK = "seek";
   public static final String PL_DEFAULT_PARAMS = "?titel=";
   public static final String PL_PARAM_RUECK = "&r=";
-  public static final String PL_API_STRG = "/api/strg/"; 
+  public static final String PL_API_STRG = "api/strg/"; 
   public static final String PL_CMD_ENDE = "ende";
   public static final String PL_CMD_STOP = "stop";
+  public static final String PL_CMD_VOLDN = "voldn";
+  public static final String PL_CMD_VOLUP = "volup";
   public static final String PL_CMD_PAUSE = "pause";
-  public static final String PL_CMD_PLAYON = "playon";
+  public static final String PL_CMD_PLAYON = "weiter";
+  public static final String PL_CMD_NEXT = "next";
   public static final String PL_CMD_CALYPSO_STOP = "stop";
+  public static final String PL_CMD_CALYPSO_VOL_INC = "vol-inc";
+  public static final String PL_CMD_CALYPSO_VOL_DEC = "vol-dec";
   public static final String PL_CMD_CALYPSO_PAUSE = "pause";
   public static final String PL_CMD_CALYPSO_PLAYON = "playon";
   public static final String DEFAULT_HOST = "http://localhost:9090";
 
+  public static final String RB_HOST = "host";
+  public static final String RB_PLAYERPARAMS = "playerparams";
+  
   private final Map spielt = new HashMap();
+  
+  private String conf;
+  
+  public MediaSteuerung(String conf) {
+    this.conf = conf;
+  }
 
   @Override
   protected String get(HttpExchange e) {
     String response;
     String path = e.getRequestURI().toString();
     String[] elems = path.split(Server.SLASH);
-    FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
+    FileStorage fs = new FileStorage(conf);
     logger.fine(path);
     
     // Faustregel: Anzahl Elemente eines URL plus 1 ist die Anzahl der Elemente des 
@@ -96,10 +125,25 @@
         } else if(elems[5].equalsIgnoreCase(PL_CMD_STOP)) {
           spielt.remove(elems[4]);
           response = kommandoSenden(fs, elems[4], PL_CMD_CALYPSO_STOP);
+        } else if(elems[5].equalsIgnoreCase(PL_CMD_VOLDN)) {
+          response = kommandoSenden(fs, elems[4], PL_CMD_CALYPSO_VOL_DEC);
+        } else if(elems[5].equalsIgnoreCase(PL_CMD_VOLUP)) {
+          response = kommandoSenden(fs, elems[4], PL_CMD_CALYPSO_VOL_INC);
         } else if(elems[5].equalsIgnoreCase(PL_CMD_PAUSE)) {
           response = kommandoSenden(fs, elems[4], PL_CMD_CALYPSO_PAUSE);
-        } else if(elems[5].equalsIgnoreCase(PL_CMD_PLAYON)) {
-          response = kommandoSenden(fs, elems[4], PL_CMD_CALYPSO_PLAYON);
+        //} else if(elems[5].equalsIgnoreCase(PL_CMD_PLAYON)) {
+        //  response = kommandoSenden(fs, elems[4], PL_CMD_CALYPSO_PLAYON);
+        } else if(elems[5].equalsIgnoreCase(PL_CMD_NEXT)) {
+          response = kommandoSenden(fs, elems[4], PL_CMD_CALYPSO_STOP);
+          //response = naechsterTitel(fs, elems[4]);
+        } else {
+          response = meldung("Ungueltiges Kommando: " + elems[5], AbstractHandler.RTC_NOT_FOUND);
+        }
+        break;
+      case 7:
+        if (elems[5].equalsIgnoreCase(PL_CMD_SEEK)) {
+          // /calypso/seek?pos=[sekunden]
+          response = kommandoSenden(fs, elems[4], "seek?pos=" + elems[6]);
         } else {
           response = meldung("Ungueltiges Kommando: " + elems[5], AbstractHandler.RTC_NOT_FOUND);
         }
@@ -117,8 +161,21 @@
   @Override
   protected String post(HttpExchange e) {
     String response;
+    String abspielerKmd = PL_CMD_PLAY;
+    String path = e.getRequestURI().toString();
+    String[] elems = path.split(Server.SLASH);
+    logger.info(elems[5]);
+    // PLAYON ist deprecated
+    //if(elems[5].equalsIgnoreCase(PL_CMD_PLAYON)) {
+    //  abspielerKmd = PL_CMD_CALYPSO_PLAYON;
+    //} else if(elems[5].equalsIgnoreCase(PL_CMD_PLAY)){
+    //  abspielerKmd = PL_CMD_PLAY;
+    //}
+    if(elems[5].equalsIgnoreCase(PL_CMD_PLAY)){
+      abspielerKmd = PL_CMD_PLAY;
+    }
     try {
-      return urlAbspielen(e);
+      return urlAbspielen(e, abspielerKmd);
     } catch (IOException ex) {
       logger.log(Level.SEVERE, null, ex);
       return meldung(ex.getLocalizedMessage(), 404);
@@ -126,11 +183,11 @@
   }
   
   // titel.katalogUrl + titel.pfad + titel.name
-  private String urlAbspielen(HttpExchange e) throws IOException {
+  private String urlAbspielen(HttpExchange e, String abspielerKmd) throws IOException {
     String path = e.getRequestURI().toString();
     String[] elems = path.split(Server.SLASH);
-    FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
-    if(elems[5].equalsIgnoreCase("titel")) {
+    FileStorage fs = new FileStorage(conf);
+    if(elems[6].equalsIgnoreCase("titel")) {
       String titelJson = bodyLesen(e);
       Gson gson = new Gson();
       Object o = gson.fromJson(titelJson, fs.typeFromName(Titel.class.getSimpleName()).getType());
@@ -140,8 +197,8 @@
         Entity entity = fs.read(FileStorage.ST_ABSPIELER, elems[4]);
         if (entity instanceof Abspieler) {
           Abspieler abspieler = (Abspieler) entity;
-          String server = getEinstellung(fs, App.getRs(App.RB_HOST), DEFAULT_HOST);
-          String signal = abspielKommando(fs, abspieler, server, titelUrl).toString();
+          String server = getEinstellung(fs, getResString(RB_HOST), DEFAULT_HOST);
+          String signal = abspielKommando(fs, abspieler, server, titelUrl, abspielerKmd).toString();
           abspielerKommandoSenden(signal);
           return signal + "gesendet.";
         } else {
@@ -150,7 +207,7 @@
       } else {
         return meldung("Ungueltiger Titel.", 404);
       }
-    } else if(elems[5].equalsIgnoreCase("stream")) {
+    } else if(elems[6].equalsIgnoreCase("stream")) {
       String streamJson = bodyLesen(e);
       Gson gson = new Gson();
       Object o = gson.fromJson(streamJson, fs.typeFromName(Livestream.class.getSimpleName()).getType());
@@ -162,7 +219,7 @@
           if (entity instanceof Abspieler) {
             Abspieler abspieler = (Abspieler) entity;
             String server = "";
-            String signal = abspielKommando(fs, abspieler, server, stream.getUrl()).toString();
+            String signal = abspielKommando(fs, abspieler, server, stream.getUrl(), PL_CMD_PLAY).toString();
             abspielerKommandoSenden(signal);
             return signal + "gesendet.";
           } else {
@@ -179,6 +236,7 @@
     }
   }
   
+  
   private String kommandoSenden(Storage s, String aName, String kommando) {
     Entity entity = s.read(FileStorage.ST_ABSPIELER, aName);
     if (entity instanceof Abspieler) {
@@ -187,12 +245,15 @@
       kmd.append(abspieler.getUrl());
       kmd.append(kommando);
       String signal = kmd.toString();
+      //String server = getEinstellung(s, App.getRs(App.RB_HOST), DEFAULT_HOST);
+      //String signal = abspielKommando(s, abspieler, server, stream.getUrl(), PL_CMD_PLAY).toString();
       abspielerKommandoSenden(signal);
       return signal + " gesendet.";
     } else {
       return meldung("Abspielliste nicht gefunden.", AbstractHandler.RTC_NOT_FOUND);
     }
   }
+  
   
   private String ersterTitel(Storage s, String aName, String lName) {
     String response;
@@ -272,7 +333,7 @@
     vorgang.setTitelNr(titelNr);
     spielt.put(abspieler.getName(), vorgang);
     
-    String server = getEinstellung(s, App.getRs(App.RB_HOST), DEFAULT_HOST);
+    String server = getEinstellung(s, getResString(RB_HOST), DEFAULT_HOST);
 
     /*
 
@@ -285,9 +346,12 @@
     kmd.append(server);
     kmd.append(titelUrl);
     */
-    StringBuilder kmd = abspielKommando(s, abspieler, server, titelUrl);
+    StringBuilder kmd = abspielKommando(s, abspieler, server, titelUrl, PL_CMD_PLAY);
     kmd.append(PL_PARAM_RUECK);
     kmd.append(server);
+    if(!server.endsWith(Server.SLASH)) {
+      kmd.append(Server.SLASH);
+    }
     kmd.append(PL_API_STRG);
     kmd.append(abspieler.getName());
     kmd.append("/ende");
@@ -295,35 +359,21 @@
     return kmd.toString();
   }
 
-  private StringBuilder abspielKommando(Storage s, Abspieler abspieler, String server, String titelUrl) {
+  private StringBuilder abspielKommando(Storage s, Abspieler abspieler, String server, String titelUrl, String abspielKmd) {
     
     // Kommando an den Abspieler zusammenbauen
     StringBuilder kmd = new StringBuilder();
     kmd.append(abspieler.getUrl());
-    kmd.append(PL_CMD_PLAY);
+    //kmd.append(PL_CMD_PLAY);
+    kmd.append(abspielKmd);
     // Parameter fuer den Abspieler holen
-    kmd.append(getEinstellung(s, App.getRs(App.RB_PLAYERPARAMS), PL_DEFAULT_PARAMS));
+    kmd.append(getEinstellung(s, getResString(RB_PLAYERPARAMS), PL_DEFAULT_PARAMS));
     kmd.append(server);
     kmd.append(titelUrl);
 
     return kmd;    
   }
-  
-  private String getEinstellung(Storage s, String key, String standardWert) {
-    Entity entity = s.read(Einstellung.class.getSimpleName(), key);
-    if (entity instanceof Einstellung) {
-      Einstellung einstellung = (Einstellung) entity;
-      Object o = einstellung.getValue();
-      if(o instanceof String) {
-        return o.toString();
-      } else {
-        return standardWert;
-      }
-    } else {
-      return standardWert;
-    }
-  }
-  
+    
   private void abspielerKommandoSenden(String kommando) {
     /*
       TODO hier evtl. mit mehreren Versuchen ausgleichen, 
@@ -346,4 +396,26 @@
     setReturnCode(code);
     return text;
   }
+
+  /* ------- PlaylistListener implementation ------ */
+  
+  @Override
+  public void titleRemoved(String listName, int titleIndex) {
+    Set keys = spielt.keySet();
+    Iterator<String> keyIterator = keys.iterator();
+    boolean found = false;
+    while(keyIterator.hasNext() && !found) {
+      String abspielerName = keyIterator.next();
+      Abspielvorgang av = (Abspielvorgang) spielt.get(abspielerName);
+      if(av.getListe().equals(listName)) {
+        found = true;
+        int tnr = av.getTitelNr();
+        if(tnr > titleIndex) {
+          av.setTitelNr(--tnr);
+          logger.info("Abspieler " + abspielerName + " Liste " + av.getListe() + " titelnr jetzt " + tnr);
+          spielt.put(abspielerName, av);
+        }
+      }
+    }
+  }
 }

--
Gitblit v1.9.3