Persoenliche Mediazentrale
ulrich
2024-11-22 c259d990ad63b38140985ba6e25b5046dd767833
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,28 +46,40 @@
 * 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 
 * 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/"; 
@@ -75,6 +89,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";
@@ -118,6 +133,17 @@
          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);
        }
        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);
        }
@@ -139,9 +165,13 @@
    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)){
    // 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 {
@@ -343,22 +373,7 @@
    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, 
@@ -381,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);
        }
      }
    }
  }
}