App zur Steuerung des mpv Mediaplayers auf einem Raspberry Pi über HTTP
undisclosed
2022-12-31 b16b544a3982da609564491ac207e74c0e121c25
VLC Basiskommandos play, pause, stop eingebaut
9 files modified
2 files added
262 ■■■■ changed files
src/de/uhilger/calypso/App.java 2 ●●● patch | view | raw | blame | history
src/de/uhilger/calypso/Server.java 24 ●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/handler/AbstractHandler.java 9 ●●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/handler/BasePlayer.java 49 ●●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/handler/DBusHandler.java 35 ●●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/handler/OMXPlayer.java 70 ●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/handler/PlayHandler.java 16 ●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/handler/Player.java 6 ●●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/handler/SeekHandler.java 10 ●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/handler/VLCKillHandler.java 25 ●●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/handler/VLCPlayer.java 16 ●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/App.java
@@ -87,7 +87,7 @@
      server.setContextName(DEFAULT_CTX);
    }
    try {
      server.start();
      server.start(playerType);
    } catch (IOException ex) {
      Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
    }
src/de/uhilger/calypso/Server.java
@@ -15,11 +15,12 @@
    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso;
import com.sun.net.httpserver.HttpServer;
import de.uhilger.calypso.handler.BasePlayer;
import de.uhilger.calypso.handler.CmdHandler;
import de.uhilger.calypso.handler.DBusHandler;
import de.uhilger.calypso.handler.FileHandler;
import de.uhilger.calypso.handler.LogHandler;
import de.uhilger.calypso.handler.OMXPlayer;
@@ -28,10 +29,13 @@
import de.uhilger.calypso.handler.PlayOnHandler;
import de.uhilger.calypso.handler.SeekHandler;
import de.uhilger.calypso.handler.StopServerHandler;
import de.uhilger.calypso.handler.VLCKillHandler;
import de.uhilger.calypso.handler.VLCPlayer;
import java.io.IOException;
import java.util.logging.Logger;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.logging.Level;
/**
 *
@@ -61,22 +65,30 @@
    this.contextName = contextName;
  }
  
  public void start() throws IOException {
    logger.info("Server starting on port " + port);
  public void start(String playerType) throws IOException {
    logger.log(Level.INFO, "Server starting on port {0}", port);
    HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
    server.createContext(contextName + "/play", new PlayHandler(OMXPlayer.F_PLAY));
    server.createContext(contextName + "/play", new PlayHandler(BasePlayer.F_PLAY));
    if (playerType.equals(App.OMX_PLAYER)) {
    server.createContext(contextName + "/seek", new SeekHandler(OMXPlayer.F_SEEK));
    server.createContext(contextName + "/stop", new CmdHandler(OMXPlayer.CMD_STOP));
    server.createContext(contextName + "/pause", new CmdHandler(OMXPlayer.CMD_PAUSE_RESUME));
    server.createContext(contextName + "/vol-inc", new CmdHandler(OMXPlayer.CMD_INC_VOL));
    server.createContext(contextName + "/vol-dec", new CmdHandler(OMXPlayer.CMD_DEC_VOL));
    server.createContext(contextName + "/info", new CmdHandler(OMXPlayer.CMD_TOGGLE_INFO));
    server.createContext(contextName + "/ping", new PingHandler(OMXPlayer.F_PING));
    server.createContext(contextName + "/server/stop", new StopServerHandler());
    server.createContext(contextName + "/log", new LogHandler());
    server.createContext(contextName + "/playon", new PlayOnHandler(OMXPlayer.F_PLAY_ON));
    } else if (playerType.equals(App.VLC_PLAYER)) {
      server.createContext(contextName + "/play", new PlayHandler(BasePlayer.F_PLAY));
      //server.createContext(contextName + "/stop", new CmdHandler(VLCPlayer.CMD_STOP));
      server.createContext(contextName + "/pause", new DBusHandler(VLCPlayer.CMD_PAUSE_RESUME));
      server.createContext(contextName + "/stop", new VLCKillHandler());
    }
    server.createContext(contextName + "/ui", new FileHandler(App.getInitParameter(App.IP_WWW_DATA)));
    server.createContext(contextName + "/ping", new PingHandler(BasePlayer.F_PING));
    server.createContext(contextName + "/server/stop", new StopServerHandler());
    //server.setExecutor(null); // creates a default executor
    server.setExecutor(Executors.newFixedThreadPool(20));
    server.start();
src/de/uhilger/calypso/handler/AbstractHandler.java
@@ -73,15 +73,6 @@
  /* --- --- */
  
  protected String getParam(Map map, String key) {
    Object o = map.get(key);
    if(o != null) {
      return o.toString();
    } else {
      return null;
    }
  }
  /*
    Den Query-Teil einer URL in die Parameter zerlegen
  
src/de/uhilger/calypso/handler/BasePlayer.java
@@ -2,9 +2,14 @@
import de.uhilger.calypso.App;
import static de.uhilger.calypso.handler.OMXPlayer.CMD_STOP;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -15,6 +20,9 @@
public abstract class BasePlayer implements Player {
  
  private static final Logger logger = Logger.getLogger(BasePlayer.class.getName());
  public static final String F_PLAY = "play";
  public static final String F_PING = "ping";
  
  
  @Override
@@ -63,4 +71,45 @@
    return antwort;
  }
    
    public String getParam(Map map, String key) {
    Object o = map.get(key);
    if(o != null) {
      return o.toString();
    } else {
      return null;
    }
  }
  /**
   * Dem laufenden Abspielprozess ein Kommando uebermitteln
   * @param k  das Kommando laut
   * <a href="https://github.com/huceke/omxplayer/blob/master/README.md" target="_blank">Liste der Kommandos</a>
   * @return die Antwort des Servers
   */
  @Override
  public String kommando(String k) {
    String antwort; // = null;
    try {
      //Object o = t.getAttribute(App.PI_PLAYER);
      Process o = App.getPlayerProcess();
      if(o == null) {
        //App.setPlayerProcess(null);
        //servletContext.removeAttribute(PI_PLAYER);
        //t.setAttribute(App.PI_PLAYER, null);
        antwort = "Es wird nichts abgespielt dem ein Kommando gesendet werden kann.";
      } else {
        Process player_process = o;
        OutputStream os = player_process.getOutputStream();
        Writer out = new BufferedWriter(new OutputStreamWriter(os));
        out.write(k);
        out.flush();
        antwort = "Kommando '" + k + "' ausgefuehrt.";
      }
    }
    catch(IOException ex) {
      antwort = "Fehler: " + ex.getMessage();
    }
    return antwort;
  }
}
src/de/uhilger/calypso/handler/DBusHandler.java
New file
@@ -0,0 +1,35 @@
/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
 */
package de.uhilger.calypso.handler;
import com.sun.net.httpserver.HttpExchange;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 *
 * @author ulli
 */
public class DBusHandler extends CmdHandler {
  public DBusHandler(String cmd) {
    super(cmd);
  }
  @Override
  protected String process(HttpExchange t, String params) {
      String antwort;// = null;
    try {
      StringBuilder kommando = new StringBuilder(cmd);
      Process player_process = Runtime.getRuntime().exec(kommando.toString());
      antwort = "Kommando ausgefuehrt: " + kommando;
    } catch (IOException ex) {
      antwort = "Fehler: " + ex.getMessage();
    }
    return antwort;
  }
}
src/de/uhilger/calypso/handler/OMXPlayer.java
@@ -18,6 +18,7 @@
package de.uhilger.calypso.handler;
import com.sun.net.httpserver.HttpExchange;
import de.uhilger.calypso.App;
import de.uhilger.calypso.MeldeThread;
import de.uhilger.calypso.ProzessLauscher;
@@ -30,6 +31,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -64,8 +66,6 @@
  public static final String CMD_PREV_SUB = "n";
  public static final String CMD_STOP = "q";
  public static final String CMD_TOGGLE_SUB = "s";
  public static final String F_PING = "ping";
  public static final String F_PLAY = "play";
  public static final String F_PLAY_ON = "playon";
  public static final String F_SEEK = "seek";
  public static final String OPT_HDMI_AUDIO = "-o%20hdmi";
@@ -116,6 +116,23 @@
    return antwort;
  }
    
  @Override
  public StringBuilder buildParams(HttpExchange t, Map map) {
    StringBuilder params = new StringBuilder();
    params.append("-o ");
    params.append(getParam(map, "o"));
    params.append(" --threshold ");
    params.append(getParam(map, "th"));
    params.append(" --timeout ");
    params.append(getParam(map, "ti"));
    String log = getParam(map, "log");
    if (log != null && log.equalsIgnoreCase("true")) {
      params.append(" --genlog");
    }
    return params;
  }
  /**
   * Einen eventuell laufenden Abspielprozess beenden und den 
   * Servlet-Kontext bereinigen.Diese Methode kann auch verwendet werden, wenn es beim normalen
@@ -149,55 +166,6 @@
    return antwort;
  }
  */
  /**
   * Dem laufenden Abspielprozess ein Kommando uebermitteln
   * @param k  das Kommando laut
   * <a href="https://github.com/huceke/omxplayer/blob/master/README.md" target="_blank">Liste der Kommandos</a>
   * @return die Antwort des Servers
   */
  @Override
  public String kommando(String k) {
    String antwort; // = null;
    try {
      //Object o = t.getAttribute(App.PI_PLAYER);
      Process o = App.getPlayerProcess();
      if(o == null) {
        //App.setPlayerProcess(null);
        //servletContext.removeAttribute(PI_PLAYER);
        //t.setAttribute(App.PI_PLAYER, null);
        antwort = "Es wird nichts abgespielt dem ein Kommando gesendet werden kann.";
      } else {
        Process player_process = o;
        OutputStream os = player_process.getOutputStream();
        Writer out = new BufferedWriter(new OutputStreamWriter(os));
        out.write(k);
        out.flush();
        if(k.equals(CMD_STOP)) {
          out.close();
          /*
            fuer den Fall, dass ein Stopp-Signal den Player nicht erreicht
            oder dort nicht funktioniert, gibt es keine Moeglichkeit festzustellen,
            dass der Player noch spielt. Damit in einem solchen Fall der Zeiger
            auf den Abspielprozess nicht verloren geht, wird  der Zeiger nicht
            auf null gesetzt.
          */
          //App.setPlayerProcess(null);
          //player_process.destroy();
          //player_process = null;
          //t.setAttribute(App.PI_PLAYER, null);
          //servletContext.removeAttribute(PI_PLAYER);
        }
        antwort = "Kommando '" + k + "' ausgefuehrt.";
      }
    }
    catch(IOException ex) {
      antwort = "Fehler: " + ex.getMessage();
    }
    return antwort;
  }
  
  /* ------ Implementierung ProzessLauscher ----------------- */
  
src/de/uhilger/calypso/handler/PlayHandler.java
@@ -55,6 +55,16 @@
    super(cmd);
  }
  @Override
  protected StringBuilder buildParams(HttpExchange t) {
    StringBuilder params = super.buildParams(t);
    params.append(App.getPlayer().buildParams(t, map));
    return params;
  }
  /*
  protected StringBuilder buildParams(HttpExchange t) {
    StringBuilder params = super.buildParams(t);
    params.append("-o ");
@@ -69,6 +79,7 @@
    }
    return params;
  }
  */
  @Override
  protected String process(HttpExchange t, String params) {
@@ -85,8 +96,9 @@
        logger.log(Level.SEVERE, null, ex);
      }
    }
    String antwort = App.getPlayer().abspielen(
            getParam(map, "titel"), params, getParam(map, "r"), "1");
    Player player = App.getPlayer();
    String antwort = player.abspielen(
            player.getParam(map, "titel"), params, player.getParam(map, "r"), "1");
    logger.log(Level.FINE, antwort);
    return antwort;
  }
src/de/uhilger/calypso/handler/Player.java
@@ -5,7 +5,9 @@
 */
package de.uhilger.calypso.handler;
import com.sun.net.httpserver.HttpExchange;
import de.uhilger.calypso.ProzessLauscher;
import java.util.Map;
/**
 *
@@ -56,6 +58,10 @@
   */
  String kommando(String k);
  StringBuilder buildParams(HttpExchange t, Map m);
  String getParam(Map map, String key);
  /* ------ Implementierung ProzessLauscher ----------------- */
  void prozessBeendet(String meldeUrlStr);
src/de/uhilger/calypso/handler/SeekHandler.java
@@ -37,8 +37,9 @@
  @Override
  protected String process(HttpExchange t, String params) {
    String antwort = App.getPlayer().abspielen(
            getParam(map, "titel"), params, getParam(map, "r"), "1");
    Player player = App.getPlayer();
    String antwort = player.abspielen(
            player.getParam(map, "titel"), params, player.getParam(map, "r"), "1");
    logger.log(Level.FINE, antwort);
    return antwort;
  }
@@ -55,9 +56,12 @@
          Select the hotkey to use to swap paused state.  
  */
  protected StringBuilder buildParams(HttpExchange t) {
    Player player = App.getPlayer();
    StringBuilder params = super.buildParams(t);
    if(player instanceof OMXPlayer) {
    params.append(" --pos ");
    params.append(getParam(map, "pos"));
      params.append(player.getParam(map, "pos"));
    }
    return params;
  }  
  
src/de/uhilger/calypso/handler/VLCKillHandler.java
New file
@@ -0,0 +1,25 @@
/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
 */
package de.uhilger.calypso.handler;
import com.sun.net.httpserver.HttpExchange;
import de.uhilger.calypso.App;
/**
 *
 * @author ulli
 */
public class VLCKillHandler extends AbstractHandler {
  @Override
  protected String process(HttpExchange t, String params) {
      Process p = App.getPlayerProcess();
      p.destroy();
      App.setPlayerProcess(null);
    String antwort = "Player-Prozess beendet.";
    return antwort;
  }
}
src/de/uhilger/calypso/handler/VLCPlayer.java
@@ -5,9 +5,11 @@
 */
package de.uhilger.calypso.handler;
import com.sun.net.httpserver.HttpExchange;
import de.uhilger.calypso.App;
import de.uhilger.calypso.MeldeThread;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -18,6 +20,9 @@
public class VLCPlayer extends BasePlayer implements Player {
  
  private static final Logger logger = Logger.getLogger(VLCPlayer.class.getName());
  public static final String CMD_STOP = "s";
  public static final String CMD_PAUSE_RESUME = "dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2   org.mpris.MediaPlayer2.Player.PlayPause";
  @Override
  public String abspielen(String urlStr, String parameter, String meldeUrlStr, String token) {
@@ -79,9 +84,10 @@
    return antwort;
  }
  @Override
  /*
  public String kommando(String k) {
    if(k.equalsIgnoreCase(OMXPlayer.CMD_STOP)) {
    if(k.equalsIgnoreCase(VLCPlayer.CMD_STOP)) {
      Process p = App.getPlayerProcess();
      p.destroy();
      App.setPlayerProcess(null);
@@ -89,6 +95,12 @@
    String antwort = "Kommando '" + k + "' ausgefuehrt.";
    return antwort;
  }
*/
  @Override
  public StringBuilder buildParams(HttpExchange t, Map m) {
    return new StringBuilder();
  }
}