From 89e41699fee6789130e20837831509bcacc9b1ff Mon Sep 17 00:00:00 2001
From: ulrich
Date: Mon, 24 Mar 2025 19:13:08 +0000
Subject: [PATCH] Beruecksichtigung eines gleichnamigen Untertitel-Files

---
 src/de/uhilger/tango/api/MediaSteuerung.java |  152 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 138 insertions(+), 14 deletions(-)

diff --git a/src/de/uhilger/tango/api/MediaSteuerung.java b/src/de/uhilger/tango/api/MediaSteuerung.java
index b499372..09fa750 100644
--- a/src/de/uhilger/tango/api/MediaSteuerung.java
+++ b/src/de/uhilger/tango/api/MediaSteuerung.java
@@ -19,20 +19,29 @@
 
 import com.google.gson.Gson;
 import com.sun.net.httpserver.HttpExchange;
+import de.uhilger.tango.PlaylistListener;
 import de.uhilger.tango.Server;
+import static de.uhilger.tango.api.ListFileHandler.RB_VIDEOEXTS;
+import de.uhilger.tango.entity.Ablageort;
 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;
 import de.uhilger.tango.store.FileStorage;
 import de.uhilger.tango.store.Storage;
+import java.io.File;
 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.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -42,12 +51,13 @@
  * 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)
  * 
- * HTTP POST /mz/api/strg/abspieler/weiter/titel mit dem Titel im Body
+ * 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 
@@ -69,7 +79,7 @@
  * @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());
 
@@ -84,6 +94,7 @@
   public static final String PL_CMD_VOLUP = "volup";
   public static final String PL_CMD_PAUSE = "pause";
   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";
@@ -96,7 +107,7 @@
   
   private final Map spielt = new HashMap();
   
-  private String conf;
+  private final String conf;
   
   public MediaSteuerung(String conf) {
     this.conf = conf;
@@ -127,6 +138,9 @@
           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_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);
         }
@@ -155,10 +169,19 @@
     String abspielerKmd = PL_CMD_PLAY;
     String path = e.getRequestURI().toString();
     String[] elems = path.split(Server.SLASH);
-    logger.info(elems[5]);
-    if(elems[5].equalsIgnoreCase(PL_CMD_PLAYON)) {
-      abspielerKmd = PL_CMD_CALYPSO_PLAYON;
-    } else if(elems[5].equalsIgnoreCase(PL_CMD_PLAY)){
+    logger.info("POST elem 0: " + elems[0]);
+    logger.info("POST elem 1: " + elems[1]);
+    logger.info("POST elem 2: " + elems[2]);
+    logger.info("POST elem 3: " + elems[3]);
+    logger.info("POST elem 4: " + elems[4]);
+    logger.info("POST cmd: " + 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 {
@@ -176,18 +199,23 @@
     FileStorage fs = new FileStorage(conf);
     if(elems[6].equalsIgnoreCase("titel")) {
       String titelJson = bodyLesen(e);
+      logger.finest("Titel aus Body: " + titelJson);
       Gson gson = new Gson();
       Object o = gson.fromJson(titelJson, fs.typeFromName(Titel.class.getSimpleName()).getType());
       if(o instanceof Titel) {
         Titel titel = (Titel) o;
+        logger.finest("Katalog-URL: " + titel.getKatalogUrl());
+        logger.finest("Titel-Pfad: " + titel.getPfad());
         String titelUrl = titel.getKatalogUrl() + titel.getPfad() + titel.getName();
+        logger.finest("Titel-URL: " + titelUrl);
+        
         Entity entity = fs.read(FileStorage.ST_ABSPIELER, elems[4]);
         if (entity instanceof Abspieler) {
           Abspieler abspieler = (Abspieler) entity;
           String server = getEinstellung(fs, getResString(RB_HOST), DEFAULT_HOST);
-          String signal = abspielKommando(fs, abspieler, server, titelUrl, abspielerKmd).toString();
+          String signal = abspielKommando(fs, abspieler, server, e.getHttpContext().getPath(), titel.getKatalogUrl(), titelUrl, abspielerKmd).toString();
           abspielerKommandoSenden(signal);
-          return signal + "gesendet.";
+          return signal + " gesendet.";
         } else {
           return meldung("Ungueltiger Abspieler.", 404);
         }
@@ -206,9 +234,9 @@
           if (entity instanceof Abspieler) {
             Abspieler abspieler = (Abspieler) entity;
             String server = "";
-            String signal = abspielKommando(fs, abspieler, server, stream.getUrl(), PL_CMD_PLAY).toString();
+            String signal = abspielKommando(fs, abspieler, server, "", "", stream.getUrl(), PL_CMD_PLAY).toString();
             abspielerKommandoSenden(signal);
-            return signal + "gesendet.";
+            return signal + " gesendet.";
           } else {
             return meldung("Ungueltiger Abspieler.", 404);
           }
@@ -333,7 +361,7 @@
     kmd.append(server);
     kmd.append(titelUrl);
     */
-    StringBuilder kmd = abspielKommando(s, abspieler, server, titelUrl, PL_CMD_PLAY);
+    StringBuilder kmd = abspielKommando(s, abspieler, server, "", "", titelUrl, PL_CMD_PLAY);
     kmd.append(PL_PARAM_RUECK);
     kmd.append(server);
     if(!server.endsWith(Server.SLASH)) {
@@ -346,8 +374,8 @@
     return kmd.toString();
   }
 
-  private StringBuilder abspielKommando(Storage s, Abspieler abspieler, String server, String titelUrl, String abspielKmd) {
-    
+  private StringBuilder abspielKommando(Storage s, Abspieler abspieler, String server, String ctx, String katalogUrl, String titelUrl, String abspielKmd) {
+    logger.finest("Server: " + server);
     // Kommando an den Abspieler zusammenbauen
     StringBuilder kmd = new StringBuilder();
     kmd.append(abspieler.getUrl());
@@ -357,8 +385,82 @@
     kmd.append(getEinstellung(s, getResString(RB_PLAYERPARAMS), PL_DEFAULT_PARAMS));
     kmd.append(server);
     kmd.append(titelUrl);
+    
+    /*
+      Wenn eine Untertiteldatei gleichen Names vorliegt, wird 
+      diese beim Abspielen aktiviert. Soll also kein Untertitel 
+      erscheinen, darf keine Untertiteldatei beigelegt werden, 
+      deren Name so lautet wie der abzuspielende Titel.
+    
+      Beispiel: Titel mein-video.mp4 und eine Datei mein-video.srt aktiviert 
+                die Unteritel-Datei. Lautet der Name der Untertiteldatei 
+                stattdessen mein-video.de-de.forced.srt werden Untertitel 
+                nicht aktiviert
+     
+    */
+    if(isVideo(s, titelUrl)) {
+      if(hasSub((FileStorage) s, ctx, katalogUrl, titelUrl)) {
+        logger.info(titelUrl + " has subFile");
+        kmd.append("&sub=on");
+      }
+    }
+    
 
     return kmd;    
+  }
+  
+  private boolean hasSub(FileStorage s, String ctx, String katalogUrl, String titelUrl) {
+    //String titel = titelUrl.substring(0, titelUrl.lastIndexOf("."));
+    String titel = titelUrl.substring(katalogUrl.length());
+    logger.finest(titel);
+    String pfad = ablageortFromKatalog(s, ctx, katalogUrl);
+    File titelFile = new File(pfad, titel);
+    File parentFile = titelFile.getParentFile();
+    File subFile = new File(parentFile, titelFile.getName().substring(0, titelFile.getName().lastIndexOf(".")) + ".srt");
+    logger.finest("subFile abs path: " + subFile.getAbsolutePath());
+    boolean doesExist = subFile.exists();
+    logger.finest("subFile exist? " + doesExist);
+    return doesExist;
+  }
+  
+  private boolean isVideo(Storage s, String titelUrl) {
+    String werte = getEinstellung(s, getResString(RB_VIDEOEXTS), "mp4");
+    String[] exts = werte.split(",");
+    for(String ext : exts) {
+      //extMap.put(ext, typ);
+      if(titelUrl.toLowerCase().endsWith(ext.toLowerCase())) {
+        return true;
+      }
+    }
+    return false;
+  }
+  
+  private String ablageortFromKatalog(Storage s, String ctx, String katalogUrl) {
+    String ort = "";
+    logger.finest("start");
+    String typ = Ablageort.class.getSimpleName();
+    logger.finest("typ: " + typ);
+    //FileStorage store = new FileStorage(conf);
+    FileStorage store = (FileStorage) s;
+    List<String> orte = store.list(typ);
+    Iterator<String> i = orte.iterator();
+    while(i.hasNext()) {
+      String ortName = i.next();
+      logger.finest("ortname: " + ortName);
+      Entity e = store.read(typ, ortName);
+      if(e instanceof Ablageort) {
+        Ablageort ablageort = (Ablageort) e;
+        logger.log(Level.FINE, "Ablageort {0}{1}", new Object[]{ctx, ablageort.getUrl()});
+        logger.fine(ablageort.getOrt());
+        if(ablageort.getUrl().endsWith(katalogUrl)) {
+          logger.finest("MATCH for " + katalogUrl + " Pfad " + ablageort.getOrt());
+          ort = ablageort.getOrt();
+        }
+        //server.createContext(ctx + ablageort.getUrl(),  
+          //new ListFileHandler(new File(ablageort.getOrt()).getAbsolutePath(), conf));
+      }
+    }
+    return ort;
   }
     
   private void abspielerKommandoSenden(String kommando) {
@@ -383,4 +485,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