From 929228226e08e352769810f729f0e9644a781bec Mon Sep 17 00:00:00 2001
From: undisclosed
Date: Sun, 08 Jan 2023 13:35:06 +0000
Subject: [PATCH] Calypso neu gebaut auf Nutzung von mpv, alte Fassung entfernt
---
src/de/uhilger/calypso/neu/MeldeThread.java | 10
/dev/null | 72 ------
src/de/uhilger/calypso/neu/ProzessLauscher.java | 3
src/de/uhilger/calypso/neu/actor/PlayActor.java | 87 +++++++
src/de/uhilger/calypso/neu/http/Server.java | 69 +++++
src/de/uhilger/calypso/neu/http/ApiHandler.java | 146 ++++++++++++
src/de/uhilger/calypso/neu/AppProperties.java | 15 -
src/de/uhilger/calypso/neu/Rueckmelder.java | 46 +++
src/de/uhilger/calypso/neu/App.java | 19 +
src/de/uhilger/calypso/neu/http/HttpApi.java | 97 ++++++++
src/de/uhilger/calypso/neu/actor/StopServerActor.java | 53 ++++
src/de/uhilger/calypso/neu/actor/ShellActor.java | 73 ++++++
12 files changed, 599 insertions(+), 91 deletions(-)
diff --git a/src/de/uhilger/calypso/App.java b/src/de/uhilger/calypso/App.java
deleted file mode 100644
index 3b17088..0000000
--- a/src/de/uhilger/calypso/App.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- Calypso - Media Player Remote Control via HTTP for Raspberry Pi
- Copyright (C) 2021-2023 Ulrich Hilger
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero 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 Affero General Public License for more details.
-
- 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 de.uhilger.calypso.handler.MPVPlayer;
-import de.uhilger.calypso.handler.MPlayer;
-import de.uhilger.calypso.handler.OMXPlayer;
-import de.uhilger.calypso.handler.Player;
-import de.uhilger.calypso.handler.VLCPlayer;
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Hauptklasse von Calypso
- *
- * Aufruf mit<br>
- * java -jar calypso.jar port=9000 ctx="/calypso"<br>
- * java -jar calypso.jar nfs-prefix="/media/mc" port=9000<br>
- * java -Djava.util.logging.config.file=logging.properties -jar ..<br>
- *
- * Der Parameter nfs-prefix bewirkt, dass beim Abspielen relative Pfade
- * mit diesem Praefix verbunden werden und setzt voraus, dass auf der
- * Maschine ein NFS-Mount ueber /etc/fstab eingerichtet ist.<br>
- * <br>
- * Anmerkung anlaesslich der Aenderung auf VLC (2.1.2023):<br>
- * Mit Calypso wurde erstmals jdk.httpserver anstelle von Tomcat
- * einsetzt. Es war in diesem Punkt noch ein Laborversuch und sollte
- * unter Wiederverwendung der wesentlichen Teile bei Gelegenheit
- * neu gebaut werden.
- *
- * @author Ulrich Hilger
- * @version 0.2 vom 2.1.2023, 0.1 vom 20.03.2021 als Nachfolger von Pirc (02.2013-03.2021)
- */
-public class App {
-
- private static final Logger logger = Logger.getLogger(App.class.getName());
-
- public static final String IP_PORT = "port";
- public static final String IP_WWW_DATA = "www-data";
- public static final String IP_NFS_PREFIX = "nfs-prefix";
- public static final String IP_PLAYER = "player";
- public static final String VLC_PLAYER = "vlc";
- public static final String OMX_PLAYER = "omx";
- public static final String M_PLAYER = "mpl";
- public static final String MPV_PLAYER = "mpv";
- public static final String OMX_WD = "omx.wd";
- public static final String CTX = "ctx";
- public static final String CONF_PATH = "conf";
-
- public static final String DEFAULT_CTX = "/calypso";
-
- private static HashMap initParams;
- private static Process playerproc;
- private static Player player;
-
- /**
- * @param args the command line arguments
- */
- public static void main(String[] args) {
- Logger.getLogger(App.class.getName()).log(Level.INFO, new File(".").getAbsolutePath());
- initParams = new HashMap();
- for(String arg: args) {
- String[] argParts = arg.split("=");
- initParams.put(argParts[0], argParts[1]);
- }
-
- String playerType = getInitParameter(IP_PLAYER);
- switch(playerType) {
- case MPV_PLAYER:
- player = new MPVPlayer();
- break;
- case M_PLAYER:
- player = new MPlayer();
- break;
- case VLC_PLAYER:
- player = new VLCPlayer();
- break;
- case OMX_PLAYER:
- player = new OMXPlayer();
- break;
- }
- Server server = new Server(Integer.parseInt(getInitParameter(IP_PORT)));
- server.setPath(getInitParameter(CONF_PATH));
- String ctx = getInitParameter(CTX);
- if(ctx != null && ctx.length() > 0) {
- server.setContextName(ctx);
- } else {
- server.setContextName(DEFAULT_CTX);
- }
- try {
- server.start(playerType);
- } catch (IOException ex) {
- Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- public static void stop() {
- System.exit(0);
- }
-
- public static String getInitParameter(String pname) {
- String param = null;
- Object o = initParams.get(pname);
- if(o != null) {
- param = o.toString();
- }
- return param;
- }
-
- public static Process getPlayerProcess() {
- return playerproc;
- }
-
- public static void setPlayerProcess(Process p) {
- playerproc = p;
- }
-
- public static Player getPlayer() {
- return player;
- }
-
- public static void setPlayer(Player pl) {
- player = pl;
- }
-
-
-
-}
diff --git a/src/de/uhilger/calypso/Betrachter.java b/src/de/uhilger/calypso/Betrachter.java
deleted file mode 100644
index 3890072..0000000
--- a/src/de/uhilger/calypso/Betrachter.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package de.uhilger.calypso;
-
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.net.URL;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.imageio.ImageIO;
-import org.tw.pi.framebuffer.FrameBuffer;
-
-/**
- * Klasse zum Betrachten von Fotografien auf dem Fernseher
- * mit dem Raspberry Pi
- *
- * Diese Klasse verwendet die Klasse JavaFrameBuffer
- * von Thomas Welsch, die die Ausgabe direkt in den
- * FrameBuffer des Raspberry Pi erlaubt.
- *
- * Der JavaFrameBuffer ist mit Calypso
- * enthalten und erfordert, dass beim Start die native
- * Programmbibliothek namens 'libFrameBuffer.so' eingebunden wird, die im Verteilpaket
- * von Calypso enthalten ist. Zum Einbinden der nativen Biliothek genuegt die
- * Angabe von -Djava.library.path=/pfad/zum/lib-ordner im Startskript von
- * Calypso.
- *
- * Durch die Verwendung des Framebuffer kann das Betrachten von
- * Bildern auf dem Fernseher erfolgen ohne, dass auf dem Raspberry Pi
- * eine grafische Bedienoberflaeche wie z.B. das X Windowing System,
- * XBMC oder OpenELEC, usw. laufen muss. Es genuegt Java
- * im 'headless mode', was zudem die Bedienbarkeit aus der Ferne via
- * HTTP hinzufuegt.
- *
- * @author Ulrich Hilger, https://uhilger.de
- * @author Published under the terms and conditions of
- * the <a href="http://www.gnu.org/licenses/agpl-3.0" target="_blank">GNU Affero General Public License</a>
- *
- * @version 2 vom 11. Februar 2022, Version 1 war vom 15.1.2014
- */
-public class Betrachter {
-
- public static final long serialVersionUID = 42L;
-
- private static final Logger logger = Logger.getLogger(Betrachter.class.getName());
-
- public static final String P_FBDEV = "fbdev";
- public static final String STANDARD_FBDEV = "/dev/fb0";
-
- public static final String P_URL = "u";
- public static final String P_X = "x";
- public static final String P_Y = "y";
- public static final String P_WIDTH = "w";
- public static final String P_HEIGHT = "h";
-
- //public static final String PATH_ZEIGEN = "/zeigen";
- //public static final String PATH_LOESCHEN = "/loeschen";
-
- private FrameBuffer jfb;
- private BufferedImage img;
- private Graphics2D g;
-
- public void init(String devName) {
- String device = devName;
- if(device == null) {
- device = STANDARD_FBDEV;
- }
- jfb = new FrameBuffer(device, false);
- img = jfb.getScreen();
- g = img.createGraphics();
- }
-
- public void close() {
- jfb.close();
- }
-
- public void jfbHelloWorld() {
- g.setColor(Color.RED);
- g.drawString("Hello World !", 50, 50);
- jfb.updateScreen();
- }
-
- /**
- * Anzeigen eines Bildes mit Hilfe des JavaFrameBuffers
- *
- * Diese Methode laedt ein Bild via HTTP oder HTTPS und
- * schreibt es in den Framebuffer zur Anzeige
- *
- * @param urlStr Adresse des Bildes, das angezeigt werden soll
- * @param x waagerechte Koordinate der gewuenschten Position der linken oberen Ecke des Bildes
- * @param y senkrechte Koordinate der gewuenschten Position der linken oberen Ecke des Bildes
- * @param w Breite in Bildpunkten, in der das Bild angezeigt werden soll
- * @param h Hoehe in Bildpunkten, in der das Bild angezeigt werden soll
- */
- public String jfbBildZeigen(String urlStr, int x, int y, int w, int h) {
- String antwort = "jfbBildZeigen hat nicht geklappt";
- BufferedImage webimg = null;
- try {
- /*
- vgl. http://java.kompf.de/java2d.html
- */
- //System.setProperty("sun.java2d.opengl","true");
- URL url = new URL(urlStr);
- webimg = ImageIO.read(url);
- g.drawImage(webimg, x, y, w, h, null);
- jfb.updateScreen();
- antwort = urlStr + " geladen";
- } catch (Exception e) {
- antwort = e.getMessage();
- }
- return antwort;
- }
-
- /**
- * Leeren des FrameBuffers
- *
- * Hier wird einfach ein Linux-Prozess eroeffnet, der das
- * Kommando dd if=/dev/zero of=/dev/fb0 ausfuehrt und
- * den Framebuffer mit Nullwerten fuellt
- */
- public String fbLeeren(String deviceName) {
- String antwort = "fbLeeren hat nicht geklappt";
- try {
- String cmd = "dd if=/dev/zero of=" + deviceName;
- Process leeren = Runtime.getRuntime().exec(cmd);
- /*MeldeThread t = new MeldeThread();
- t.setProcess(leeren);
- t.lauscherHinzufuegen(new ProzessLauscherImpl() {
- @Override
- public void prozessBeendet() {
- // etwas tun, wenn fertig...
- }
- });
- t.start();*/
- antwort = "Prozess gestartet";
- } catch(Exception ex) {
- logger.log(Level.FINE, ex.getMessage(), ex);
- }
- return antwort;
- }
-
-
-
-}
diff --git a/src/de/uhilger/calypso/OMXLogLeser.java b/src/de/uhilger/calypso/OMXLogLeser.java
deleted file mode 100644
index 8450481..0000000
--- a/src/de/uhilger/calypso/OMXLogLeser.java
+++ /dev/null
@@ -1,165 +0,0 @@
-package de.uhilger.calypso;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author ulrich
- */
-public class OMXLogLeser {
-
- private static final Logger logger = Logger.getLogger(OMXLogLeser.class.getName());
-
- public static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
-
- private static final long MILLIS = (long) 1000;
-
- private static final long MINSEC = (long) 60;
-
-
- public String logDirLesen(File logDir) throws IOException, FileNotFoundException, ParseException {
- Blocks blocks = new Blocks();
- File[] files = logDir.listFiles();
- for(File file : files) {
- lesen(file, blocks);
- }
- return blocks.getTimeString();
- }
-
- /**
- *
- * <p>Die Spieldauer laut OMX-Log ergibt sich aus dem Zeitstempel des
- * letzten Eintrags abzueglich des Zeitstempels des
- * ersten Eintrags abzueglich der Pausen</p>
- *
- * <p>Eine Pause ist der Zeitraum vom Zeitstempel eines Eintrags mit
- * <code>Keyboard: character p (0x70)</code> bis zum Zeitstempel des
- * nächsten Eintrags mit <code>Keyboard: character p</code></p>
- *
- *
- * @param logfile
- * @param blocks
- * @return die Spieldauer als String im Format H:MM:SS
- * @throws FileNotFoundException
- * @throws IOException
- * @throws ParseException
- */
- public void lesen(File logfile, Blocks blocks) throws FileNotFoundException, IOException, ParseException {
- boolean inPause = false;
- logger.info("Starting to parse log..");
- Date parseStart = new Date();
- long lineCount = 0;
- InputStream is = new FileInputStream(logfile);
- BufferedReader r = new BufferedReader(new InputStreamReader(is));
- String firstLine = r.readLine();
- ++lineCount;
- String lastLine = "";
- String line = r.readLine();
- //Blocks blocks = new Blocks();
- Block currentBlock = new Block();
- while(line != null) {
- ++lineCount;
- if(currentBlock.getStart() == null) {
- currentBlock.setStart(line.substring(0, 8));
- }
- if(line.contains("Keyboard: character p")) {
- if(inPause) {
- currentBlock.setStart(line.substring(0, 8));
- } else {
- currentBlock.setEnd(line.substring(0, 8));
- blocks.add(currentBlock);
- currentBlock = new Block();
- }
- inPause = !inPause;
- }
- lastLine = line;
- line = r.readLine();
- }
- currentBlock.setEnd(lastLine.substring(0, 8));
- blocks.add(currentBlock);
- Date parseEnd = new Date();
- long timeMillis = parseEnd.getTime() - parseStart.getTime();
- long timeSeconds = timeMillis / MILLIS;
- long secMillis = timeSeconds * MILLIS;
- long restMillis = timeMillis - secMillis;
- logger.log(Level.INFO,
- "{0} lines parsed in {1} seconds and {2} milliseconds.",
- new Object[]{lineCount, timeSeconds, restMillis});
- //return blocks.getTimeString();
- }
-
- class Block {
- private String start = null;
- private String end = null;
-
- public long getDuration() throws ParseException {
- Date startDate = sdf.parse(start);
- Date endDate = sdf.parse(end);
- return endDate.getTime() - startDate.getTime();
- }
-
- public String getStart() {
- return start;
- }
-
- public void setStart(String start) {
- //logger.log(Level.FINER, "Start: ''{0}''", start);
- this.start = start;
- }
-
- public String getEnd() {
- return end;
- }
-
- public void setEnd(String end) {
- //logger.log(Level.FINER, "End: ''{0}''", end);
- this.end = end;
- }
-
-
- }
-
- class Blocks {
-
- private final List<Block> blocks = new ArrayList();
-
- public void add(Block block) {
- blocks.add(block);
- }
-
- public long getDuration() throws ParseException {
- long duration = (long) 0;
- Iterator<Block> i = blocks.iterator();
- while(i.hasNext()) {
- Block b = i.next();
- duration += b.getDuration();
- }
- return duration;
- }
-
- public String getTimeString() throws ParseException {
- long diff = getDuration();
- long h = diff / MILLIS / MINSEC / MINSEC;
- long hmillis = h * MINSEC * MINSEC * MILLIS;
- long m = (diff - hmillis) / MILLIS / MINSEC;
- long mmillis = m * MINSEC * MILLIS;
- long s = (diff - hmillis - mmillis) / MILLIS;
- //logger.log(Level.FINER, "{0}:{1}:{2}", new Object[]{h, m, s});
- return h + ":" + m + ":" + s;
- }
- }
-}
diff --git a/src/de/uhilger/calypso/Server.java b/src/de/uhilger/calypso/Server.java
deleted file mode 100644
index 9948ece..0000000
--- a/src/de/uhilger/calypso/Server.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- Calypso - Media Player Remote Control via HTTP for Raspberry Pi
- Copyright (C) 2021-2023 Ulrich Hilger
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero 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 Affero General Public License for more details.
-
- 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.MPVKillHandler;
-import de.uhilger.calypso.handler.MPVPlayHandler;
-import de.uhilger.calypso.handler.MPVPlayer;
-import de.uhilger.calypso.handler.MPVSeekHandler;
-import de.uhilger.calypso.handler.MPlayHandler;
-import de.uhilger.calypso.handler.MPlayer;
-import de.uhilger.calypso.handler.OMXPlayer;
-import de.uhilger.calypso.handler.PingHandler;
-import de.uhilger.calypso.handler.PlayHandler;
-import de.uhilger.calypso.handler.PlayOnHandler;
-import de.uhilger.calypso.handler.SeekHandler;
-import de.uhilger.calypso.handler.SocketHandler;
-import de.uhilger.calypso.handler.StopServerHandler;
-import de.uhilger.calypso.handler.VLCKillHandler;
-import de.uhilger.calypso.handler.VLCPlayer;
-import de.uhilger.calypso.handler.VLCSeekHandler;
-import java.io.File;
-import java.io.IOException;
-import java.util.logging.Logger;
-import java.net.InetSocketAddress;
-import java.util.concurrent.Executors;
-import java.util.logging.Level;
-
-/**
- * Die Klasse Server implementiert die HTTP-Schnittstelle zum
- * Mediaplayer. Es wird ein Player-Prozesss fuer das Abspielen
- * eines Titels gestartet. Mit Stopp oder Ende des Titels endet
- * auch der Abspielprozess.<br>
- * <br>
- * zum Abspielen:<br>
- * /calypso/play?title=http://ein.titel.mp3&r=http://rueckmelde.url<br>
- * <br>
- * waehrend des Abspielens:<br>
- * /calypso/pause<br>
- * /calypso/seek?pos=[sekunden]<br>
- * /calypso/stop<br>
- * <br>
- * sonstige Funktionen:<br>
- * /calypso/ping<br>
- * /calypso/server/stop<br>
- * <br>
- * verworfene Funktionen<br>
- * /calypso/vol-inc<br>
- * /calypso/vol-dec<br>
- * Die Lautstaerke wird in aller Regel am Geraet geregelt, an das der
- * Zuspieler (der Raspi) angeschlossen ist. Eine Regelung ueber den
- * Zuspieler ist daher eher selten erforderlich.
- *
- * @author Ulrich Hilger
- */
-public class Server {
-
- private static final Logger logger = Logger.getLogger(Server.class.getName());
-
- private int port;
-
- private String contextName;
-
- private String path;
-
- public Server(int port) {
- this.port = port;
- }
-
- public void setPort(int port) {
- this.port = port;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- /**
- *
- * @param contextName e.g. '/calypso' or '/cal'
- */
- public void setContextName(String contextName) {
- this.contextName = contextName;
- }
-
- 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);
-
- if (playerType.equals(App.OMX_PLAYER)) {
- server.createContext(contextName + "/play", new PlayHandler(BasePlayer.F_PLAY));
- 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 + "/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 + "/pause", new DBusHandler(VLCPlayer.CMD_PAUSE_RESUME));
- //server.createContext(contextName + "/pause", new CmdHandler("pause"));
- //server.createContext(contextName + "/seek", new DBusHandler(VLCPlayer.CMD_SEEK));
- server.createContext(contextName + "/seek", new VLCSeekHandler(VLCPlayer.CMD_SEEK));
- server.createContext(contextName + "/stop", new VLCKillHandler());
- } else if (playerType.equals(App.M_PLAYER)) {
- server.createContext(contextName + "/play", new MPlayHandler());
- server.createContext(contextName + "/pause", new CmdHandler(MPlayer.CMD_PAUSE_RESUME));
- server.createContext(contextName + "/stop", new CmdHandler(MPlayer.CMD_STOP));
- } else if (playerType.equals(App.MPV_PLAYER)) {
- server.createContext(contextName + "/play", new MPVPlayHandler());
- server.createContext(contextName + "/pause", new SocketHandler(path + MPVPlayer.CMD_PAUSE_RESUME));
- server.createContext(contextName + "/seek", new MPVSeekHandler(path + MPVPlayer.CMD_SEEK));
- server.createContext(contextName + "/stop", new MPVKillHandler());
- }
- 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();
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/AbstractHandler.java b/src/de/uhilger/calypso/handler/AbstractHandler.java
deleted file mode 100644
index a46d368..0000000
--- a/src/de/uhilger/calypso/handler/AbstractHandler.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- AV-Direktor - Control OMXPlayer on Raspberry Pi via HTTP
- Copyright (C) 2021 Ulrich Hilger
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero 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 Affero General Public License for more details.
-
- 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.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpHandler;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author ulrich
- */
-public abstract class AbstractHandler implements HttpHandler {
-
- private static final Logger logger = Logger.getLogger(AbstractHandler.class.getName());
-
- protected String cmd;
- protected Map map;
-
- @Override
- public void handle(HttpExchange t) throws IOException {
- logger.log(Level.FINE, "RequestURI: {0}", t.getRequestURI().toString());
- StringBuilder params = buildParams(t);
- String antwort = process(t, params.toString());
- sendResponse(t, cmd, antwort);
- }
-
- protected abstract String process(HttpExchange t, String params);
-
- protected StringBuilder buildParams(HttpExchange t) {
- map = getQueryMap(t);
- StringBuilder params = new StringBuilder();
- return params;
- }
-
- protected void sendResponse(HttpExchange t, String cmd, String antwort) throws IOException {
- String response = getResponseString(map, cmd, antwort);
- t.sendResponseHeaders(200, response.length());
- OutputStream os = t.getResponseBody();
- os.write(response.getBytes());
- os.close();
- }
-
- public void setCmd(String cmd) {
- this.cmd = cmd;
- }
-
- public String getCmd(String cmd) {
- return this.cmd;
- }
-
- /* --- --- */
-
- /*
- Den Query-Teil einer URL in die Parameter zerlegen
-
- Die Zerlegung erfolgt mit String.split nach
- & und dann nach =
- */
- protected Map getQueryMap(HttpExchange t) {
- HashMap map = new HashMap();
- String query = t.getRequestURI().getQuery();
- if(query != null && query.length() > 0) {
- String qParts[] = query.split("&");
- for(String qPart : qParts) {
- logger.finer("qPart: " + qPart);
- String pParts[] = qPart.split("=");
- map.put(pParts[0], pParts[1]);
- logger.finer("pParts[0]: " + pParts[0] + ", pParts[1]: " + pParts[1]);
- }
- }
- return map;
- }
-
- protected String getResponseString(Map map, String cmd, String antwort) {
- Set keys = map.keySet();
- StringBuilder buf = new StringBuilder();
- buf.append(cmd);
- buf.append(System.lineSeparator());
- keys.forEach((Object key) -> {
- buf.append("key: ");
- buf.append(key);
- buf.append(System.lineSeparator());
- buf.append("value: ");
- buf.append(map.get(key));
- buf.append(System.lineSeparator());
- //logger.log(Level.FINE, "key {0} value {1}", new Object[]{key, map.get(key)});
- });
- buf.append(antwort);
- return buf.toString();
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/BasePlayer.java b/src/de/uhilger/calypso/handler/BasePlayer.java
deleted file mode 100644
index 19576a4..0000000
--- a/src/de/uhilger/calypso/handler/BasePlayer.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package de.uhilger.calypso.handler;
-
-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;
-
-/**
- *
- * @author ulli
- */
-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
- public void prozessBeendet(String meldeUrlStr) {
- logger.log(Level.INFO,
- "Abspielen beendet, sende Meldung an {0}.",
- new Object[]{meldeUrlStr});
- try {
- HttpURLConnection conn = (HttpURLConnection) new URL(meldeUrlStr).openConnection();
- conn.setRequestMethod("GET");
- conn.connect();
- int status = conn.getResponseCode();
- logger.log(Level.INFO,
- "Abspielen beendet, Meldung an {0} mit Statuscode {1} gesendet.",
- new Object[]{meldeUrlStr, status});
- /*
- 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);
- } catch(IOException ex) {
- logger.log(Level.INFO, ex.getMessage(), ex);
- }
- }
-
- @Override
- public String tilgen() {
- logger.log(Level.INFO,"Player tilgen.");
- String antwort; // = null;
- try {
- Process o = App.getPlayerProcess();
- if(o == null) {
- antwort = "Es ist kein Player zum Beenden vorhanden.";
- //App.setPlayerProcess(null);
- } else {
- kommando(CMD_STOP); // setzt den Prozess der App auf null
- antwort = "Player gestoppt.";
- }
- }
- catch(Exception ex) {
- antwort = "Fehler: " + ex.getMessage();
- }
- 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;
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/CmdHandler.java b/src/de/uhilger/calypso/handler/CmdHandler.java
deleted file mode 100644
index a8abc29..0000000
--- a/src/de/uhilger/calypso/handler/CmdHandler.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- AV-Direktor - Control OMXPlayer on Raspberry Pi via HTTP
- Copyright (C) 2021 Ulrich Hilger
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero 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 Affero General Public License for more details.
-
- 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.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author ulrich
- */
-public class CmdHandler extends AbstractHandler {
-
- private static final Logger logger = Logger.getLogger(CmdHandler.class.getName());
-
- public CmdHandler(String cmd) {
- this.cmd = cmd;
- }
-
- protected String process(HttpExchange t, String params) {
- String antwort = App.getPlayer().kommando(cmd);
- logger.log(Level.FINE, antwort);
- return antwort;
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/DBusHandler.java b/src/de/uhilger/calypso/handler/DBusHandler.java
deleted file mode 100644
index 0f6be4d..0000000
--- a/src/de/uhilger/calypso/handler/DBusHandler.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package de.uhilger.calypso.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Obwohl ein laufendes VLC-Programm mit Tastaturbefehlen gesteuert
- * werden kann, funktioniert es nicht, dem Prozess einen Tastaturbefehl
- * wie z.B. S fuer Stopp ueber process.getOutputStream zu 'schreiben',
- * moeglicherweise, weil auf dem Raspberry Pi das VLC als Kommando-
- * zeilenprogramm ohne UI laeuft. Im Augenblick gelingt nur die Steuerung
- * ueber dbus. Hier muss noch geprueft werden, ob das auch mit Windows und
- * Mac OS klappt, was aber fuer einen Einsatz auf dem Raspberry Pi
- * nebensaechlich ist.
- *
- * Die Steuerung von VLC via dbus wiederum folgt dem Standard mpris
- * (Media Player Remote Interfacing Specification) von freedesktop.org,
- * der von zahlreichen Mediaplayern unterstuetzt wird.
- *
- * @author Ulrich Hilger
- */
-public class DBusHandler extends CmdHandler {
-
- private static final Logger logger = Logger.getLogger(DBusHandler.class.getName());
-
- public DBusHandler(String cmd) {
- super(cmd);
- }
-
- @Override
- protected String process(HttpExchange t, String params) {
- String antwort;// = null;
- try {
- StringBuilder kommando = new StringBuilder();
- kommando.append(VLCPlayer.DBUS_PREFIX);
- kommando.append(cmd);
- logger.log(Level.FINE, "kommando: {0}", kommando.toString());
- Process player_process = Runtime.getRuntime().exec(kommando.toString());
- antwort = "Kommando ausgefuehrt: " + kommando;
- } catch (IOException ex) {
- antwort = "Fehler: " + ex.getMessage();
- }
- return antwort;
- }
-}
diff --git a/src/de/uhilger/calypso/handler/FileHandler.java b/src/de/uhilger/calypso/handler/FileHandler.java
deleted file mode 100644
index caaf149..0000000
--- a/src/de/uhilger/calypso/handler/FileHandler.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- AV-Direktor - Control OMXPlayer on Raspberry Pi via HTTP
- Copyright (C) 2021 Ulrich Hilger
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero 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 Affero General Public License for more details.
-
- 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.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpHandler;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.logging.Logger;
-
-/**
- *
- * @author ulrich
- */
-public class FileHandler implements HttpHandler {
-
- private static final Logger logger = Logger.getLogger(FileHandler.class.getName());
-
- private final String basePath;
-
- public FileHandler(String basePath) {
- this.basePath = basePath;
- }
-
- @Override
- public void handle(HttpExchange t) throws IOException {
- String ctxPath = t.getHttpContext().getPath();
- String uriPath = t.getRequestURI().getPath();
- String fName = uriPath.substring(ctxPath.length());
- if(fName.endsWith("/")) {
- fName += "index.html";
- }
- OutputStream os = t.getResponseBody();
- File file = new File(basePath, fName);
- if(file.exists()) {
- t.sendResponseHeaders(200, file.length());
- InputStream in = new FileInputStream(file);
- int b = in.read();
- while(b > -1) {
- os.write(b);
- b = in.read();
- }
- in.close();
- } else {
- String response = fName + " not found.";
- byte[] bytes = response.getBytes(StandardCharsets.UTF_8);
- t.sendResponseHeaders(404, bytes.length);
- os.write(bytes);
- }
- os.flush();
- os.close();
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/LogHandler.java b/src/de/uhilger/calypso/handler/LogHandler.java
deleted file mode 100644
index f22421c..0000000
--- a/src/de/uhilger/calypso/handler/LogHandler.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package de.uhilger.calypso.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.OMXLogLeser;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.text.ParseException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author ulrich
- */
-public class LogHandler extends AbstractHandler {
-
- private static final Logger logger = Logger.getLogger(LogHandler.class.getName());
-
- @Override
- public void handle(HttpExchange t) throws IOException {
- logger.log(Level.FINE, "RequestURI: {0}", t.getRequestURI().toString());
- StringBuilder params = buildParams(t);
- String antwort = process(t, params.toString());
- sendResponse(t, cmd, antwort);
- }
-
- @Override
- protected void sendResponse(HttpExchange t, String cmd, String antwort) throws IOException {
- t.sendResponseHeaders(200, antwort.length());
- OutputStream os = t.getResponseBody();
- os.write(antwort.getBytes());
- os.close();
- }
-
-
- @Override
- protected String process(HttpExchange t, String params) {
- /*
- OMXLogLeser leser = new OMXLogLeser();
- String lines = "Log nicht lesbar.";
- try {
- logger.info(new File(".").getAbsolutePath());
- lines = leser.lesen(new File("omxplayer.log"));
- } catch (IOException ex) {
- Logger.getLogger(LogHandler.class.getName()).log(Level.SEVERE, null, ex);
- } catch (ParseException ex) {
- Logger.getLogger(LogHandler.class.getName()).log(Level.SEVERE, null, ex);
- }
- */
- return "";
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/MPVKillHandler.java b/src/de/uhilger/calypso/handler/MPVKillHandler.java
deleted file mode 100644
index f3240f0..0000000
--- a/src/de/uhilger/calypso/handler/MPVKillHandler.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package de.uhilger.calypso.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-
-/**
- *
- * @author Ulrich Hilger
- */
-public class MPVKillHandler 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;
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/MPVPlayHandler.java b/src/de/uhilger/calypso/handler/MPVPlayHandler.java
deleted file mode 100644
index 52e84a1..0000000
--- a/src/de/uhilger/calypso/handler/MPVPlayHandler.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.uhilger.calypso.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author Ulrich Hilger
- */
-public class MPVPlayHandler extends AbstractHandler {
-
- private static final Logger logger = Logger.getLogger(MPVPlayHandler.class.getName());
-
- @Override
- protected String process(HttpExchange t, String params) {
- 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;
- }
-
-
-
-}
diff --git a/src/de/uhilger/calypso/handler/MPVPlayer.java b/src/de/uhilger/calypso/handler/MPVPlayer.java
deleted file mode 100644
index fc169dd..0000000
--- a/src/de/uhilger/calypso/handler/MPVPlayer.java
+++ /dev/null
@@ -1,123 +0,0 @@
-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;
-
-/**
- *
- * @author ulrich
- */
-public class MPVPlayer extends BasePlayer implements Player {
-
- private static final Logger logger = Logger.getLogger(MPVPlayer.class.getName());
-
- /*
-echo '{ "command": ["get_property", "playback-time"] }' | socat - /tmp/mpvsocket
-{"data":190.482000,"error":"success"}
-
-echo 'show-text ${playback-time}' | socat - /tmp/mpvsocket
-
- { "command": ["set_property", "pause", true] }
- { "error": "success" }
-
-{"command": ["cycle", "pause"]}
-
- */
- public static final String SOCK_PREFIX = "";
- public static final String CMD_PAUSE_RESUME = "pause";
- public static final String CMD_SEEK = "seek";
-
- @Override
- public String abspielen(String urlStr, String parameter, String meldeUrlStr, String token) {
- String antwort;// = null;
- try {
- //Object o = t.getAttribute(App.PI_PLAYER);
- Process o = App.getPlayerProcess();
- if(o != null) {
- tilgen();
- }
- StringBuilder kommando = new StringBuilder("mpv --input-ipc-server=/tmp/mpvsocket --no-terminal ");
-
- /*
- mpv versucht Musikstuecke mit Album-Bildern in den Metadaten als Video
- abzuspielen und bricht ab.
- (diese Einstellung muss noch parametriert und erweitert werden)
- */
- if(urlStr.contains(".mp3")) {
- kommando.append("--vo=null ");
- }
- /*
- if(parameter != null) {
- kommando.append(parameter);
- kommando.append(BLANK);
- }
- */
- if(urlStr.startsWith("http")) {
- kommando.append(urlStr.replace(" ", "%20"));
- kommando.append("?t=");
- kommando.append(token);
- } else {
- /*
- //url z.B.: Filme/H/HEAT_D2.m4v
-
- hier muss noch der Pfad hinzugefuegt werden, unter
- dem auf dem raspi die Datenquelle via NFS eingebunden ist,
- z.B. /media/mc/
- dieser Teil des Pfades muss in pirc als Init-Parameter oder
- etwas aehnliches hinterlegt sein, weil es lokal zum jeweils
- verwendeten raspi gehoert
-
- */
-
- String pfad = App.getInitParameter("nfs-prefix");
- kommando.append(pfad);
-
- kommando.append(urlStr);
- }
- //kommando.append(" vlc://quit");
- logger.log(Level.FINE, "kommando: {0}", kommando.toString());
- Process player_process = Runtime.getRuntime().exec(kommando.toString());
- if(meldeUrlStr != null) {
- MeldeThread mt = new MeldeThread();
- mt.setProcess(player_process);
- mt.lauscherHinzufuegen(this);
- mt.setMeldeUrl(meldeUrlStr);
- mt.start();
- }
- //servletContext.setAttribute(App.PI_PLAYER, player_process);
- //t.setAttribute(App.PI_PLAYER, player_process);
- App.setPlayerProcess(player_process);
- //Runtime.getRuntime().exec("killall dbus-daemon");
- antwort = "Abspielen gestartet, url: " + urlStr;
- }
- catch(IOException ex) {
- antwort = "Fehler: " + ex.getMessage();
- }
- return antwort;
- }
-
-
- /*
- public String kommando(String k) {
- if(k.equalsIgnoreCase(VLCPlayer.CMD_STOP)) {
- Process p = App.getPlayerProcess();
- p.destroy();
- App.setPlayerProcess(null);
- }
- String antwort = "Kommando '" + k + "' ausgefuehrt.";
- return antwort;
- }
-*/
-
- @Override
- public StringBuilder buildParams(HttpExchange t, Map m) {
- return new StringBuilder();
- }
-
-
-}
diff --git a/src/de/uhilger/calypso/handler/MPVSeekHandler.java b/src/de/uhilger/calypso/handler/MPVSeekHandler.java
deleted file mode 100644
index 097c6d4..0000000
--- a/src/de/uhilger/calypso/handler/MPVSeekHandler.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.uhilger.calypso.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * http://server:9090/calypso/seek?pos=30 (30 Sekunden vor) oder pos=-30 (zurueck)
- *
- * echo '{"command": ["seek", '30']}' | socat - /tmp/mpvsocket
- * echo '{"command": ["seek", '-30']}' | socat - /tmp/mpvsocket
- *
- * in einem Shell Skript
- * echo '{"command": ["seek", '$1']}' | socat - /tmp/mpvsocket
- *
- *
- * @author Ulrich Hilger
- */
-public class MPVSeekHandler extends CmdHandler {
-
- private static final Logger logger = Logger.getLogger(MPVSeekHandler.class.getName());
-
- public MPVSeekHandler(String cmd) {
- super(cmd);
- }
-
- @Override
- protected String process(HttpExchange t, String params) {
- String antwort;// = null;
- try {
- StringBuilder kommando = new StringBuilder();
- //kommando.append(VLCPlayer.DBUS_PREFIX);
- kommando.append(cmd);
- kommando.append(params);
- logger.log(Level.FINE, "kommando: {0}", kommando.toString());
- Process player_process = Runtime.getRuntime().exec(kommando.toString());
- antwort = "Kommando ausgefuehrt: " + kommando;
- } catch (IOException ex) {
- antwort = "Fehler: " + ex.getMessage();
- }
- return antwort;
- }
-
- @Override
- protected StringBuilder buildParams(HttpExchange t) {
- Player player = App.getPlayer();
- StringBuilder params = super.buildParams(t);
-
- if (player instanceof MPVPlayer) {
- String pos = player.getParam(map, "pos");
- if (!pos.isEmpty()) {
- params.append(" ");
- params.append(pos);
- }
- }
-
- logger.log(Level.FINER, "params: " + params.toString());
- return params;
- }
-}
diff --git a/src/de/uhilger/calypso/handler/MPlayHandler.java b/src/de/uhilger/calypso/handler/MPlayHandler.java
deleted file mode 100644
index 7ccb685..0000000
--- a/src/de/uhilger/calypso/handler/MPlayHandler.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.uhilger.calypso.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author Ulrich Hilger
- */
-public class MPlayHandler extends AbstractHandler {
-
- private static final Logger logger = Logger.getLogger(MPlayHandler.class.getName());
-
- @Override
- protected String process(HttpExchange t, String params) {
- 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;
- }
-
-
-
-}
diff --git a/src/de/uhilger/calypso/handler/MPlayer.java b/src/de/uhilger/calypso/handler/MPlayer.java
deleted file mode 100644
index 6539233..0000000
--- a/src/de/uhilger/calypso/handler/MPlayer.java
+++ /dev/null
@@ -1,88 +0,0 @@
-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;
-
-/**
- *
- * @author Ulrich Hilger
- */
-public class MPlayer extends BasePlayer {
-
- private static final Logger logger = Logger.getLogger(MPlayer.class.getName());
-
- public static final String CMD_STOP = "q";
- public static final String CMD_PAUSE_RESUME = "p";
-
- @Override
- public String abspielen(String urlStr, String parameter, String meldeUrlStr, String token) {
- String antwort;// = null;
- try {
- //Object o = t.getAttribute(App.PI_PLAYER);
- Process o = App.getPlayerProcess();
- if(o != null) {
- tilgen();
- }
- StringBuilder kommando = new StringBuilder("mplayer -cache 2048 -cache-min 80 -really-quiet -framedrop ");
- /*
- if(parameter != null) {
- kommando.append(parameter);
- kommando.append(BLANK);
- }
- */
- if(urlStr.startsWith("http")) {
- kommando.append(urlStr.replace(" ", "%20"));
- //kommando.append("?t=");
- //kommando.append(token);
- } else {
- /*
- //url z.B.: Filme/H/HEAT_D2.m4v
-
- hier muss noch der Pfad hinzugefuegt werden, unter
- dem auf dem raspi die Datenquelle via NFS eingebunden ist,
- z.B. /media/mc/
- dieser Teil des Pfades muss in pirc als Init-Parameter oder
- etwas aehnliches hinterlegt sein, weil es lokal zum jeweils
- verwendeten raspi gehoert
-
- */
-
- String pfad = App.getInitParameter("nfs-prefix");
- kommando.append(pfad);
-
- kommando.append(urlStr);
- }
- //kommando.append(" vlc://quit");
- //kommando.append(" >>/dev/null 2>&1");
- logger.log(Level.FINE, "kommando: {0}", kommando.toString());
- Process player_process = Runtime.getRuntime().exec(kommando.toString());
- if(meldeUrlStr != null) {
- MeldeThread mt = new MeldeThread();
- mt.setProcess(player_process);
- mt.lauscherHinzufuegen(this);
- mt.setMeldeUrl(meldeUrlStr);
- mt.start();
- }
- //servletContext.setAttribute(App.PI_PLAYER, player_process);
- //t.setAttribute(App.PI_PLAYER, player_process);
- App.setPlayerProcess(player_process);
- //Runtime.getRuntime().exec("killall dbus-daemon");
- antwort = "Abspielen gestartet, url: " + urlStr;
- }
- catch(IOException ex) {
- antwort = "Fehler: " + ex.getMessage();
- }
- return antwort;
- }
-
- @Override
- public StringBuilder buildParams(HttpExchange t, Map m) {
- return new StringBuilder();
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/OMXPlayer.java b/src/de/uhilger/calypso/handler/OMXPlayer.java
deleted file mode 100644
index f012ad9..0000000
--- a/src/de/uhilger/calypso/handler/OMXPlayer.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- AV-Direktor - Control OMXPlayer on Raspberry Pi via HTTP
- Copyright (C) 2021 Ulrich Hilger
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero 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 Affero General Public License for more details.
-
- 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.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-import de.uhilger.calypso.MeldeThread;
-import de.uhilger.calypso.ProzessLauscher;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-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;
-
-/**
- * Methoden zur Ausfuehrung des Programmes omxplayer des Raspberry Pi
- * sowie zum Senden von Kommandos an eine laufende Instanz des
- * omxplayer.
- *
- * Die Klasse OMXPlayer stellt als abstrakte Basisklasse ihre Methoden
- * den Handler-Klassen zur Verfuegung.
- *
- * @author ulrich
- */
-public class OMXPlayer extends BasePlayer implements Player , ProzessLauscher {
-
- private static final Logger logger = Logger.getLogger(OMXPlayer.class.getName());
-
- public static final String NAME = "omxplayer";
-
- public static final String BLANK = " ";
- public static final String CMD_TOGGLE_INFO = "z";
- public static final String CMD_DEC_SPEED = "1";
- public static final String CMD_DEC_VOL = "-";
- public static final String CMD_INC_SPEED = "2";
- public static final String CMD_INC_VOL = "="; // oder "+";
- public static final String CMD_NEXT_AUDIO = "k";
- public static final String CMD_NEXT_CHAPTER = "o";
- public static final String CMD_NEXT_SUB = "m";
- public static final String CMD_PAUSE_RESUME = "p";
- public static final String CMD_PREV_AUDIO = "j";
- public static final String CMD_PREV_CHAPTER = "i";
- 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_PLAY_ON = "playon";
- public static final String F_SEEK = "seek";
- public static final String OPT_HDMI_AUDIO = "-o%20hdmi";
- public static final String OPT_LOCAL_AUDIO = "-o%20local";
- public static final String PFEIL_HERAUF = "5b41";
- public static final String PFEIL_HERUNTER = "5b42";
- public static final String PFEIL_LINKS = "5b44";
- public static final String PFEIL_RECHTS = "5b43";
- public static final String SP_RUECK_30 = "rueck30";
- public static final String SP_RUECK_600 = "rueck600";
- public static final String SP_VOR_30 = "rueck30";
- public static final String SP_VOR_600 = "vor600";
-
- @Override
- public String abspielen(String urlStr, String parameter, String meldeUrlStr, String token) {
- String antwort;// = null;
- try {
- Process o = App.getPlayerProcess();
- if(o != null) {
- tilgen();
- }
- List<String> kommando = new ArrayList();
- kommando.add(NAME);
- kommando.addAll(Arrays.asList(parameter.split(BLANK)));
- if(urlStr.startsWith("http")) {
- kommando.add(urlStr.replace(" ", "%20"));
- } else {
- kommando.add(App.getInitParameter("nfs-prefix") + urlStr);
- }
- logger.log(Level.FINE, "parameter: {0}", parameter);
- logger.log(Level.FINE, "kommando: {0}", kommando.toString());
- ProcessBuilder pb = new ProcessBuilder(kommando);
- pb.directory(new File(System.getProperty("omx.wd")));
- Process player_process = pb.start();
- if(meldeUrlStr != null) {
- MeldeThread mt = new MeldeThread();
- mt.setProcess(player_process);
- mt.lauscherHinzufuegen(this);
- mt.setMeldeUrl(meldeUrlStr);
- mt.start();
- }
- App.setPlayerProcess(player_process);
- antwort = "Abspielen gestartet, url: " + urlStr;
- }
- catch(IOException ex) {
- antwort = "Fehler: " + ex.getMessage();
- }
- 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
- Abspielen zu Fehlern kommt und womoeglich der Servlet-Kontext noch
- eine Referenz zu einem Abspielprozess enthaelt, die nicht mehr
- aktuell ist.
- *
- * Mit der Methode tilgen kann man eine solche Referenz
- entfernen und gibt so das Objekt wieder frei fuer die Ausfuehrung
- weiterer Kommandos.
- *
- * @return die Antwort des Servers
- */
- /*
- @Override
- public String tilgen() {
- String antwort; // = null;
- try {
- Process o = App.getPlayerProcess();
- if(o == null) {
- antwort = "Es ist kein Player zum Beenden vorhanden.";
- //App.setPlayerProcess(null);
- } else {
- kommando(CMD_STOP); // setzt den Prozess der App auf null
- antwort = "Player gestoppt.";
- }
- }
- catch(Exception ex) {
- antwort = "Fehler: " + ex.getMessage();
- }
- return antwort;
- }
- */
-
- /* ------ Implementierung ProzessLauscher ----------------- */
-
- /*
- @Override
- public void prozessBeendet(String meldeUrlStr) {
- try {
- HttpURLConnection conn = (HttpURLConnection) new URL(meldeUrlStr).openConnection();
- conn.setRequestMethod("GET");
- conn.connect();
- int status = conn.getResponseCode();
- logger.log(Level.INFO,
- "Abspielen beendet, Meldung an {0} mit Statuscode {1} gesendet.",
- new Object[]{meldeUrlStr, status});
- /*
- 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);
- /*
- } catch(IOException ex) {
- logger.log(Level.INFO, ex.getMessage(), ex);
- }
- }
- */
-}
diff --git a/src/de/uhilger/calypso/handler/PingHandler.java b/src/de/uhilger/calypso/handler/PingHandler.java
deleted file mode 100644
index 5ecd735..0000000
--- a/src/de/uhilger/calypso/handler/PingHandler.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- AV-Direktor - Control OMXPlayer on Raspberry Pi via HTTP
- Copyright (C) 2021 Ulrich Hilger
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero 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 Affero General Public License for more details.
-
- 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.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author ulrich
- */
-public class PingHandler extends CmdHandler {
-
- private static final Logger logger = Logger.getLogger(PingHandler.class.getName());
-
- public PingHandler(String cmd) {
- super(cmd);
- }
-
- protected String process(HttpExchange t, String params) {
- logger.log(Level.FINE, cmd);
- return cmd;
- }
-
- protected void sendResponse(HttpExchange t, String cmd, String antwort) throws IOException {
- t.sendResponseHeaders(200, antwort.length());
- OutputStream os = t.getResponseBody();
- os.write(antwort.getBytes());
- os.close();
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/PlayHandler.java b/src/de/uhilger/calypso/handler/PlayHandler.java
deleted file mode 100644
index 7b09208..0000000
--- a/src/de/uhilger/calypso/handler/PlayHandler.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- AV-Direktor - Control OMXPlayer on Raspberry Pi via HTTP
- Copyright (C) 2021 Ulrich Hilger
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero 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 Affero General Public License for more details.
-
- 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.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-import java.io.IOException;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Play
- *
- * rpi4-az:9090/avd/play?titel=/Filme/S/sound_city.m4v&th=60&ti=60&o=local
- *
- * OMXPlayer.abspielenMitParameternUndRueckmeldung( String urlStr, String
- * parameter, String meldeUrlStr, String token)
- *
- * Parameter des Aufrufs play als query (th threshold, ti timeout)
- *
- * ?titel=/Filme/S/sound_city.m4v &ti=60 &th=60 &o=local|hdmi|both
- * &r=http://uhilger.de/mc/api/usw
- *
- * r muss ganz wegbleiben, wenn keine Rueckmeldung gewuescht ist
- *
- * @author ulrich
- */
-public class PlayHandler extends CmdHandler {
-
- private static final Logger logger = Logger.getLogger(PlayHandler.class.getName());
-
- public PlayHandler(String cmd) {
- 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 ");
- 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;
- }
- */
-
- @Override
- protected String process(HttpExchange t, String params) {
- if (cmd.equalsIgnoreCase(BasePlayer.F_PLAY)) {
- try {
- //FileUtils.deleteDirectory(new File(System.getProperty("omx.wd"), "omx-logs"));
- FileSystem fs = FileSystems.getDefault();
- Path path = fs.getPath(System.getProperty("omx.wd"), "omx-logs");
- if(path.toFile().exists()) {
- deleteDirectory(path);
- }
- //Files.delete(path);
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- }
- 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;
- }
-
- protected void deleteDirectory(Path start) throws IOException {
- Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
- throws IOException {
- Files.delete(file);
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path dir, IOException e)
- throws IOException {
- if (e == null) {
- Files.delete(dir);
- return FileVisitResult.CONTINUE;
- } else {
- // directory iteration failed
- throw e;
- }
- }
- });
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/PlayOnHandler.java b/src/de/uhilger/calypso/handler/PlayOnHandler.java
deleted file mode 100644
index 957677e..0000000
--- a/src/de/uhilger/calypso/handler/PlayOnHandler.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package de.uhilger.calypso.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-import de.uhilger.calypso.OMXLogLeser;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * z.B.
- * http://rpi4-az:9090/avd/playon?th=1&ti=240&o=local&log=true&titel=http://amd-srv:9090/srv/Filme/C/casino_royale.m4v
- *
- * @author ulrich
- */
-public class PlayOnHandler extends PlayHandler {
-
- private static final Logger logger = Logger.getLogger(PlayOnHandler.class.getName());
-
- public static final String LOG_DIR = "omx-logs";
- public static final String LOG_EXT = "log";
- public static final String DASH = "-";
- public static final String DOT = ".";
-
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
-
- public PlayOnHandler(String cmd) {
- super(cmd);
- }
-
- /*
- 1. buildParams
- 2. process
- */
- @Override
- protected StringBuilder buildParams(HttpExchange t) {
- File logDir = logSichern();
- StringBuilder params = super.buildParams(t);
- params.append(" --pos ");
- try {
- params.append(dauerBestimmen(logDir));
- } catch (IOException | ParseException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- return params;
- }
-
- private File logSichern() {
- String wd = System.getProperty(App.OMX_WD);
- File zielOrdner = new File(wd, LOG_DIR);
- try {
- // omxplayer.log umbenennen
- FileSystem fs = FileSystems.getDefault();
- Path logDatei = fs.getPath(wd, OMXPlayer.NAME + DOT + LOG_EXT);
- Date now = new Date();
- String neuerName = OMXPlayer.NAME + DASH + sdf.format(now) + DOT + LOG_EXT;
- Files.move(logDatei, logDatei.resolveSibling(neuerName));
-
- // Unterverzeichnis ggf. erzeugen
- zielOrdner.mkdirs();
-
- // omxplayer-datum.log verschieben
- Path quellDatei = fs.getPath(wd, neuerName);
- Path zielPfad = fs.getPath(wd, LOG_DIR);
- Files.move(quellDatei, zielPfad.resolve(quellDatei.getFileName()), REPLACE_EXISTING);
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- return zielOrdner;
- }
-
- private String dauerBestimmen(File logDir) throws IOException, FileNotFoundException, ParseException {
- OMXLogLeser leser = new OMXLogLeser();
- return leser.logDirLesen(logDir);
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/Player.java b/src/de/uhilger/calypso/handler/Player.java
deleted file mode 100644
index 9808bcb..0000000
--- a/src/de/uhilger/calypso/handler/Player.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package de.uhilger.calypso.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.ProzessLauscher;
-import java.util.Map;
-
-/**
- *
- * @author ulrich
- */
-public interface Player extends ProzessLauscher {
-
- /**
- * Einen Prozess zum Abspielen mit dem omxplayer starten
- * @param urlStr URL der Quelle, die abgespielt werden soll
- * @param token
- * @return Antwort des Servers
- */
- /*
- public String abspielen(String urlStr, String token) {
- return abspielenMitParametern(urlStr, null, token);
- }
- */
- /*
- public String abspielenMitRueckmeldung(String urlStr, String meldeUrlStr, String token) {
- return abspielenMitParameternUndRueckmeldung(urlStr, null, meldeUrlStr, token);
- }
- */
- /**
- * Einen Prozess zum Abspielen mit dem omxplayer starten
- * und Parameter uebergeben.Moegliche Parameter fuer das Abspielen mit dem omxplayer
- beschreibt die Seite
- <a href="https://github.com/huceke/omxplayer/blob/master/README.md"target="_blank">Aufstellung der Parameter</a>.Die Zeichenkette parameter enthaelt Eintraege wie z.B.
- * App.OPT_LOCAL_AUDIO oder App.OPT_HDMI_AUDIO.
- Mehrere Parameter werden mit App.BLANK getrennt.
- * @param urlStr der URL der Quelle, die abgespielt werden soll
- * @param parameter die Parameter, die vom omxplayer angewendet werden sollen
- * @param token
- * @return Antwort des Servers
- */
- /*
- public String abspielenMitParametern(String urlStr, String parameter, String token) {
- return abspielenMitParameternUndRueckmeldung(urlStr, parameter, null, token);
- }
- */
- String abspielen(String urlStr, String parameter, String meldeUrlStr, String token);
-
- /**
- * 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
- */
- String kommando(String k);
-
- StringBuilder buildParams(HttpExchange t, Map m);
-
- String getParam(Map map, String key);
-
- /* ------ Implementierung ProzessLauscher ----------------- */
- void prozessBeendet(String meldeUrlStr);
-
- /**
- * Einen eventuell laufenden Abspielprozess beenden und den
- * Servlet-Kontext bereinigen.Diese Methode kann auch verwendet werden, wenn es beim normalen
- Abspielen zu Fehlern kommt und womoeglich der Servlet-Kontext noch
- eine Referenz zu einem Abspielprozess enthaelt, die nicht mehr
- aktuell ist.
- *
- * Mit der Methode tilgen kann man eine solche Referenz
- entfernen und gibt so das Objekt wieder frei fuer die Ausfuehrung
- weiterer Kommandos.
- *
- * @return die Antwort des Servers
- */
- String tilgen();
-
-}
diff --git a/src/de/uhilger/calypso/handler/SeekHandler.java b/src/de/uhilger/calypso/handler/SeekHandler.java
deleted file mode 100644
index 9d3c255..0000000
--- a/src/de/uhilger/calypso/handler/SeekHandler.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- AV-Direktor - Control OMXPlayer on Raspberry Pi via HTTP
- Copyright (C) 2021 Ulrich Hilger
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero 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 Affero General Public License for more details.
-
- 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.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author ulrich
- */
-public class SeekHandler extends PlayHandler {
-
- private static final Logger logger = Logger.getLogger(SeekHandler.class.getName());
-
- public SeekHandler(String cmd) {
- super(cmd);
- }
-
- @Override
- protected String process(HttpExchange t, String params) {
- 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;
- }
-
- /*
- start "C:Program FilesVLCvlc.exe" rel="nofollow" "D:MoviesThe Italian Job.avi" --start-time 12 --stop-time 20
-
- You simply have to use the command line as given above, with the file paths and the time changed as needed.
- The numbers 12 and 20 in the command line indicate 12 seconds and 20 seconds respectively.
-
-
- --global-key-play-pause=<string>
- Play/Pause
- 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(player.getParam(map, "pos"));
- }
- return params;
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/SocketHandler.java b/src/de/uhilger/calypso/handler/SocketHandler.java
deleted file mode 100644
index 8fce603..0000000
--- a/src/de/uhilger/calypso/handler/SocketHandler.java
+++ /dev/null
@@ -1,46 +0,0 @@
-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;
-
-/**
- * Hier muss noch die Implementierung mit Unix Domain Sockets folgen,
- * sobald Java 16 fuer 64-bit Raspberry Pi 4 erhaeltlich ist.
- *
- * Bis dahin wird hier (dirty trick) ein Shell Skript aufgerufen,
- * das mit Hilfe des Tools socat das Kommando ausfuehrt. socat muss
- * dafuer auf dem Raspberry Pi installiert sein.
- *
- * Kommandos
- *
- * pause: echo '{"command": ["cycle", "pause"]}' | socat - /tmp/mpvsocket
- * seek: echo '{"command": ["seek", '30']}' | socat - /tmp/mpvsocket
- *
- * @author Ulrich Hilger
- */
-public class SocketHandler extends CmdHandler {
-
- private static final Logger logger = Logger.getLogger(SocketHandler.class.getName());
-
- public SocketHandler(String cmd) {
- super(cmd);
- }
-
- @Override
- protected String process(HttpExchange t, String params) {
- String antwort;// = null;
- try {
- StringBuilder kommando = new StringBuilder();
- kommando.append(MPVPlayer.SOCK_PREFIX);
- kommando.append(cmd);
- logger.log(Level.FINE, "kommando: {0}", kommando.toString());
- Process player_process = Runtime.getRuntime().exec(kommando.toString());
- antwort = "Kommando ausgefuehrt: " + kommando;
- } catch (IOException ex) {
- antwort = "Fehler: " + ex.getMessage();
- }
- return antwort;
- }
-}
diff --git a/src/de/uhilger/calypso/handler/StopServerHandler.java b/src/de/uhilger/calypso/handler/StopServerHandler.java
deleted file mode 100644
index 1bf848b..0000000
--- a/src/de/uhilger/calypso/handler/StopServerHandler.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- AV-Direktor - Control OMXPlayer on Raspberry Pi via HTTP
- Copyright (C) 2021 Ulrich Hilger
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero 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 Affero General Public License for more details.
-
- 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.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpHandler;
-import de.uhilger.calypso.App;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.logging.Logger;
-
-/**
- *
- * @author ulrich
- */
-public class StopServerHandler extends OMXPlayer implements HttpHandler {
-
- @Override
- public void handle(HttpExchange exchange) throws IOException {
- Logger.getLogger(StopServerHandler.class.getName()).info(exchange.getRequestURI().toString());
- this.kommando(CMD_STOP);
- String response = "Server stopped";
- exchange.sendResponseHeaders(200, response.length());
- OutputStream os = exchange.getResponseBody();
- os.write(response.getBytes());
- os.flush();
- os.close();
- Logger.getLogger(StopServerHandler.class.getName()).info("stopping app.");
- App.stop();
- //exchange.getHttpContext().getServer().stop(5);
- }
-
-
-}
diff --git a/src/de/uhilger/calypso/handler/VLCKillHandler.java b/src/de/uhilger/calypso/handler/VLCKillHandler.java
deleted file mode 100644
index 34325f1..0000000
--- a/src/de/uhilger/calypso/handler/VLCKillHandler.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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;
- }
-
-}
diff --git a/src/de/uhilger/calypso/handler/VLCPlayer.java b/src/de/uhilger/calypso/handler/VLCPlayer.java
deleted file mode 100644
index c2c1aba..0000000
--- a/src/de/uhilger/calypso/handler/VLCPlayer.java
+++ /dev/null
@@ -1,104 +0,0 @@
-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;
-
-/**
- *
- * @author ulrich
- */
-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 DBUS_PREFIX = "dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.";
- public static final String CMD_PAUSE_RESUME = "PlayPause";
- public static final String CMD_SEEK = "Seek";
- public static final String CMD_VOLUME = "Volume";
-
- @Override
- public String abspielen(String urlStr, String parameter, String meldeUrlStr, String token) {
- String antwort;// = null;
- try {
- //Object o = t.getAttribute(App.PI_PLAYER);
- Process o = App.getPlayerProcess();
- if(o != null) {
- tilgen();
- }
- StringBuilder kommando = new StringBuilder("vlc --fullscreen ");
- /*
- if(parameter != null) {
- kommando.append(parameter);
- kommando.append(BLANK);
- }
- */
- if(urlStr.startsWith("http")) {
- kommando.append(urlStr.replace(" ", "%20"));
- kommando.append("?t=");
- kommando.append(token);
- } else {
- /*
- //url z.B.: Filme/H/HEAT_D2.m4v
-
- hier muss noch der Pfad hinzugefuegt werden, unter
- dem auf dem raspi die Datenquelle via NFS eingebunden ist,
- z.B. /media/mc/
- dieser Teil des Pfades muss in pirc als Init-Parameter oder
- etwas aehnliches hinterlegt sein, weil es lokal zum jeweils
- verwendeten raspi gehoert
-
- */
-
- String pfad = App.getInitParameter("nfs-prefix");
- kommando.append(pfad);
-
- kommando.append(urlStr);
- }
- kommando.append(" vlc://quit");
- logger.log(Level.FINE, "kommando: {0}", kommando.toString());
- Process player_process = Runtime.getRuntime().exec(kommando.toString());
- if(meldeUrlStr != null) {
- MeldeThread mt = new MeldeThread();
- mt.setProcess(player_process);
- mt.lauscherHinzufuegen(this);
- mt.setMeldeUrl(meldeUrlStr);
- mt.start();
- }
- //servletContext.setAttribute(App.PI_PLAYER, player_process);
- //t.setAttribute(App.PI_PLAYER, player_process);
- App.setPlayerProcess(player_process);
- //Runtime.getRuntime().exec("killall dbus-daemon");
- antwort = "Abspielen gestartet, url: " + urlStr;
- }
- catch(IOException ex) {
- antwort = "Fehler: " + ex.getMessage();
- }
- return antwort;
- }
-
-
- /*
- public String kommando(String k) {
- if(k.equalsIgnoreCase(VLCPlayer.CMD_STOP)) {
- Process p = App.getPlayerProcess();
- p.destroy();
- App.setPlayerProcess(null);
- }
- String antwort = "Kommando '" + k + "' ausgefuehrt.";
- return antwort;
- }
-*/
-
- @Override
- public StringBuilder buildParams(HttpExchange t, Map m) {
- return new StringBuilder();
- }
-
-
-}
diff --git a/src/de/uhilger/calypso/handler/VLCSeekHandler.java b/src/de/uhilger/calypso/handler/VLCSeekHandler.java
deleted file mode 100644
index 8da3a3a..0000000
--- a/src/de/uhilger/calypso/handler/VLCSeekHandler.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package de.uhilger.calypso.handler;
-
-import com.sun.net.httpserver.HttpExchange;
-import de.uhilger.calypso.App;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2
- * org.mpris.MediaPlayer2.Player.Seek int64:-5000000
- *
- * @author Ulrich Hilger
- */
-public class VLCSeekHandler extends CmdHandler {
-
- private static final Logger logger = Logger.getLogger(VLCSeekHandler.class.getName());
-
- public VLCSeekHandler(String cmd) {
- super(cmd);
- }
-
- @Override
- protected String process(HttpExchange t, String params) {
- String antwort;// = null;
- try {
- StringBuilder kommando = new StringBuilder();
- kommando.append(VLCPlayer.DBUS_PREFIX);
- kommando.append(cmd);
- kommando.append(params);
- logger.log(Level.FINE, "kommando: {0}", kommando.toString());
- Process player_process = Runtime.getRuntime().exec(kommando.toString());
- antwort = "Kommando ausgefuehrt: " + kommando;
- } catch (IOException ex) {
- antwort = "Fehler: " + ex.getMessage();
- }
- return antwort;
- }
-
- @Override
- protected StringBuilder buildParams(HttpExchange t) {
- Player player = App.getPlayer();
- StringBuilder params = super.buildParams(t);
-
- if (player instanceof VLCPlayer) {
- String pos = player.getParam(map, "pos");
- if (!pos.isEmpty()) {
- params.append(" ");
- params.append("int64:");
- params.append(pos);
- params.append("000000"); // Mikrosekunden
- }
- }
-
- logger.log(Level.FINER, "params: " + params.toString());
- return params;
- }
-}
diff --git a/src/de/uhilger/calypso/neu/App.java b/src/de/uhilger/calypso/neu/App.java
index 603f4ea..602707f 100644
--- a/src/de/uhilger/calypso/neu/App.java
+++ b/src/de/uhilger/calypso/neu/App.java
@@ -1,5 +1,24 @@
+/*
+ Calypso - Media Player Remote Control via HTTP for Raspberry Pi
+ Copyright (C) 2021-2023 Ulrich Hilger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ 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.neu;
+import de.uhilger.calypso.neu.http.Server;
import java.util.HashMap;
/**
diff --git a/src/de/uhilger/calypso/neu/AppProperties.java b/src/de/uhilger/calypso/neu/AppProperties.java
index f80c4b8..aea7da8 100644
--- a/src/de/uhilger/calypso/neu/AppProperties.java
+++ b/src/de/uhilger/calypso/neu/AppProperties.java
@@ -59,20 +59,8 @@
Logger.getLogger(AppProperties.class.getName()).log(Level.INFO, fName);
InputStream in = null;
try {
- // Einstellungen aus Datei lesen
- //AppProperties einst = new AppProperties();
File einstellungenDatei = new File(fName);
in = new FileInputStream(einstellungenDatei);
-
- //BufferedReader br = new BufferedReader(new InputStreamReader(in));
- //String line = br.readLine();
- //while(line != null) {
- // System.out.println(line);
- // line = br.readLine();
- //}
- //br.close();
-
-
load(in);
in.close();
} catch (FileNotFoundException ex) {
@@ -86,8 +74,5 @@
Logger.getLogger(AppProperties.class.getName()).log(Level.SEVERE, null, ex);
}
}
-
-
}
-
}
diff --git a/src/de/uhilger/calypso/MeldeThread.java b/src/de/uhilger/calypso/neu/MeldeThread.java
similarity index 92%
rename from src/de/uhilger/calypso/MeldeThread.java
rename to src/de/uhilger/calypso/neu/MeldeThread.java
index 7d03fb5..a8ea023 100644
--- a/src/de/uhilger/calypso/MeldeThread.java
+++ b/src/de/uhilger/calypso/neu/MeldeThread.java
@@ -16,7 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package de.uhilger.calypso;
+package de.uhilger.calypso.neu;
import java.util.logging.Logger;
import java.util.logging.Level;
@@ -45,11 +45,17 @@
this.meldeUrlStr = meldeUrlStr;
}
+ /**
+ * ausfuehren des Threads
+ */
+ @Override
public void run() {
try {
exitValue = omxplayer.waitFor();
prozessBeendetMelden();
- } catch(Exception ex) {
+ lauscher.clear();
+ lauscher = null;
+ } catch(InterruptedException ex) {
logger.log(Level.FINE, ex.getMessage(), ex);
} finally {
aufraeumen();
diff --git a/src/de/uhilger/calypso/ProzessLauscher.java b/src/de/uhilger/calypso/neu/ProzessLauscher.java
similarity index 96%
rename from src/de/uhilger/calypso/ProzessLauscher.java
rename to src/de/uhilger/calypso/neu/ProzessLauscher.java
index 0fdb5d2..6adff11 100644
--- a/src/de/uhilger/calypso/ProzessLauscher.java
+++ b/src/de/uhilger/calypso/neu/ProzessLauscher.java
@@ -16,8 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package de.uhilger.calypso;
-
+package de.uhilger.calypso.neu;
public interface ProzessLauscher {
diff --git a/src/de/uhilger/calypso/neu/Rueckmelder.java b/src/de/uhilger/calypso/neu/Rueckmelder.java
new file mode 100644
index 0000000..1680653
--- /dev/null
+++ b/src/de/uhilger/calypso/neu/Rueckmelder.java
@@ -0,0 +1,46 @@
+package de.uhilger.calypso.neu;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Ulrich Hilger
+ */
+public class Rueckmelder implements ProzessLauscher {
+
+
+
+ @Override
+ public void prozessBeendet(String meldeUrlStr) {
+ Logger logger = Logger.getLogger(de.uhilger.calypso.neu.http.ApiHandler.class.getName());
+ logger.log(Level.INFO,
+ "Abspielen beendet, sende Meldung an {0}.",
+ new Object[]{meldeUrlStr});
+ try {
+ HttpURLConnection conn = (HttpURLConnection) new URL(meldeUrlStr).openConnection();
+ conn.setRequestMethod("GET");
+ conn.connect();
+ int status = conn.getResponseCode();
+ logger.log(Level.INFO,
+ "Abspielen beendet, Meldung an {0} mit Statuscode {1} gesendet.",
+ new Object[]{meldeUrlStr, status});
+ /*
+ 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);
+ } catch (IOException ex) {
+ logger.log(Level.INFO, ex.getMessage(), ex);
+ }
+ }
+
+
+
+}
diff --git a/src/de/uhilger/calypso/neu/Server.java b/src/de/uhilger/calypso/neu/Server.java
deleted file mode 100644
index db467ba..0000000
--- a/src/de/uhilger/calypso/neu/Server.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package de.uhilger.calypso.neu;
-
-import java.io.File;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author Ulrich Hilger
- */
-public class Server {
-
- private static final Logger logger = Logger.getLogger(de.uhilger.calypso.Server.class.getName());
-
- public static final String CONF = "conf";
- public static final String PORT = "port";
- public static final String SKRIPTE = "skripte";
-
- public static final String EQUAL = "=";
-
- private AppProperties einst;
-
- public void start(AppProperties einst) {
- logger.log(Level.INFO, "Server startet auf Port {0}", einst.getString(PORT));
- this.einst = einst;
- String skripte = einst.getString(SKRIPTE);
- File playSkript = new File(skripte, "play");
- if(playSkript.exists()) {
- logger.log(Level.INFO, "Skripte gefunden in {0}", playSkript.getParentFile().getAbsolutePath());
- } else {
- logger.log(Level.INFO, "Skripte nicht gefunden, Ordner laut Einstellungen: {0}", skripte);
- }
- }
-
-}
diff --git a/src/de/uhilger/calypso/neu/actor/PlayActor.java b/src/de/uhilger/calypso/neu/actor/PlayActor.java
new file mode 100644
index 0000000..d8a7a67
--- /dev/null
+++ b/src/de/uhilger/calypso/neu/actor/PlayActor.java
@@ -0,0 +1,87 @@
+/*
+ Calypso - Media Player Remote Control via HTTP for Raspberry Pi
+ Copyright (C) 2021-2023 Ulrich Hilger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ 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.neu.actor;
+
+import de.uhilger.calypso.neu.MeldeThread;
+import de.uhilger.calypso.neu.Rueckmelder;
+import de.uhilger.calypso.neu.http.Server;
+import java.io.IOException;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Der PlayActor loest das Abspielen eines Titels aus.
+ *
+ * Das koennte auch als Shell-Skript geschehen, aber abhaengig
+ * vom verwendeten Abspielprogramm benoetigt man das Prozessobjekt
+ * des laufenden Abspielprozesses im Verlauf des Abspielens noch, um
+ * weitere Kommandos zu senden.
+ *
+ * Beim Abspieler mpv werden Kommandos allerdings ueber Unix Domain
+ * Sockets gesendet, hierfuer waere also das Objekt des laufenden
+ * Abspielprozesses nicht noetig. Man benoetigt es aber auch um
+ * festzustellen, ob der Abspielprozess beendet ist.
+ *
+ * @author Ulrich Hilger
+ */
+public class PlayActor {
+
+ public Process run(Map parameter) {
+ String meldeUrlStr = null;
+ Object o = parameter.get("r");
+ if (o instanceof String) {
+ meldeUrlStr = (String) o;
+ }
+
+ StringBuilder kommando = new StringBuilder();
+ o = parameter.get("titel");
+ if (o instanceof String) {
+ String titel = (String) o;
+ if (titel.toLowerCase().endsWith(".mp3")) {
+ kommando.append("mpv --input-ipc-server=/tmp/mpvsocket --no-terminal --vo=null ");
+ } else {
+ kommando.append("mpv --input-ipc-server=/tmp/mpvsocket --no-terminal ");
+ }
+ kommando.append(Server.BLANK);
+ kommando.append(titel);
+ Logger.getLogger(PlayActor.class.getName()).log(Level.FINE, kommando.toString());
+ Process player_process;
+ try {
+ player_process = Runtime.getRuntime().exec(kommando.toString());
+ if (meldeUrlStr != null) {
+ MeldeThread mt = new MeldeThread();
+ mt.setProcess(player_process);
+ mt.lauscherHinzufuegen(new Rueckmelder());
+ mt.setMeldeUrl(meldeUrlStr);
+ mt.start();
+ }
+ return player_process;
+ } catch (IOException ex) {
+ Logger logger = Logger.getLogger(PlayActor.class.getName());
+ logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
+ ex.printStackTrace();
+ return null;
+ }
+ } else {
+ Logger.getLogger(PlayActor.class.getName()).log(Level.INFO, "Titel fehlt");
+ return null;
+ }
+ }
+}
diff --git a/src/de/uhilger/calypso/neu/actor/ShellActor.java b/src/de/uhilger/calypso/neu/actor/ShellActor.java
new file mode 100644
index 0000000..c912c51
--- /dev/null
+++ b/src/de/uhilger/calypso/neu/actor/ShellActor.java
@@ -0,0 +1,73 @@
+/*
+ Calypso - Media Player Remote Control via HTTP for Raspberry Pi
+ Copyright (C) 2021-2023 Ulrich Hilger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ 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.neu.actor;
+
+import de.uhilger.calypso.neu.http.Server;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ *
+ * Der mpv Abspieler erhaelt Kommandos waehrend des Abspielens
+ * ueber Unix Domain Sockets. Da diese erst mit Java 16 untersuetzt
+ * werden und Java 16 fuer den Raspberry Pi noch nicht erhaeltlich
+ * ist, werden diese Kommandos als Shell-Skript unter Verwendung
+ * des Linux-Programms socat gesendet.
+ *
+ * Der Shell Actor fuehrt Skripte aus. Wenn ein Kommando Parameter
+ * erfordert, werden diese aus dem Query-Teil des HTTP-Aufrufes
+ * entnommen.
+ *
+ *
+ * @author Ulrich Hilger
+ */
+public class ShellActor {
+
+ /**
+ * Ein Skript auf der Kommandozeile ausfuehren
+ *
+ * @param skriptDir das Verzeichnis, in dem das Skript liegt
+ * @param kommando der Name des Skript
+ * @throws IOException
+ */
+ //public void run(String skriptDir, String kommando) throws IOException {
+ // File skriptFile = new File(skriptDir, kommando);
+ // Process p = Runtime.getRuntime().exec(skriptFile.getAbsolutePath());
+ //}
+
+ /**
+ *
+ * @param skriptDir das Verzeichnis, in dem das Skript liegt
+ * @param kommando der Name des Skript
+ * @param params die Parameter des Shell-Kommandos, null, wenn keine
+ * @throws IOException
+ */
+ public void run(String skriptDir, String kommando, String... params) throws IOException {
+ StringBuilder sb = new StringBuilder();
+ File skriptFile = new File(skriptDir, kommando);
+ sb.append(skriptFile.getAbsolutePath());
+ if(params instanceof String[]) {
+ for (String param : params) {
+ sb.append(Server.BLANK);
+ sb.append(param);
+ }
+ }
+ Process p = Runtime.getRuntime().exec(sb.toString());
+ }
+}
diff --git a/src/de/uhilger/calypso/neu/actor/StopServerActor.java b/src/de/uhilger/calypso/neu/actor/StopServerActor.java
new file mode 100644
index 0000000..c73c6c0
--- /dev/null
+++ b/src/de/uhilger/calypso/neu/actor/StopServerActor.java
@@ -0,0 +1,53 @@
+/*
+ Calypso - Media Player Remote Control via HTTP for Raspberry Pi
+ Copyright (C) 2021-2023 Ulrich Hilger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ 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.neu.actor;
+
+import com.sun.net.httpserver.HttpContext;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.logging.Logger;
+
+/**
+ * Ein HTTP-Handler zum Stoppen der Anwendung
+ *
+ * @author Ulrich Hilger
+ */
+public class StopServerActor {
+
+ public void run(HttpContext thisContext) {
+ Logger.getLogger(StopServerActor.class.getName()).info("Server wird gestoppt..");
+ thisContext.getServer().stop(1); // diesen Server stoppen
+ Timer timer = new Timer();
+ timer.schedule(new AppStopper(), 1500); // die App auch beenden
+ }
+
+ /**
+ * Die Klasse AppStopper ermöglicht das asnychrone bzw.
+ * zeitgesteuerte Stoppen der Anwendung.
+ */
+ class AppStopper extends TimerTask {
+
+ @Override
+ public void run() {
+ Logger.getLogger(StopServerActor.class.getName()).info("Calypso beendet.");
+ System.exit(0);
+ }
+ }
+
+}
diff --git a/src/de/uhilger/calypso/neu/http/ApiHandler.java b/src/de/uhilger/calypso/neu/http/ApiHandler.java
new file mode 100644
index 0000000..e803df6
--- /dev/null
+++ b/src/de/uhilger/calypso/neu/http/ApiHandler.java
@@ -0,0 +1,146 @@
+/*
+ Calypso - Media Player Remote Control via HTTP for Raspberry Pi
+ Copyright (C) 2021-2023 Ulrich Hilger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ 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.neu.http;
+
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import de.uhilger.calypso.neu.actor.PlayActor;
+import de.uhilger.calypso.neu.actor.ShellActor;
+import de.uhilger.calypso.neu.actor.StopServerActor;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Der ApiHandler ist die proprietaer fuer Calypso vorgesehene
+ * Weise, HTTP-Anfragen zu verarbeiten.
+ *
+ * Der ApiHandler ist ein HttpHandler, der vom Server ueber die
+ * gesamte Laufzeit des Programmes hinweg gehalten wird. Deswegen
+ * beschraenkt sich der Programmcode des ApiHandlers auf die
+ * Verteilung der Kommandos auf Aktoren. Die Aktoren werden je nach
+ * Bedarf instanziiert und enthalten zusammengenommen den Code
+ * des Anwendungskerns.
+ *
+ * @author Ulrich Hilger
+ */
+public class ApiHandler extends HttpApi {
+
+ public static final int PLAYERCMD = 2;
+ public static final int SERVERCMD = 3;
+ public static final String PLAY = "play";
+ public static final String PAUSE = "pause";
+ public static final String SEEK = "seek";
+ public static final String STOP = "stop";
+ public static final String SERVER = "server";
+ public static final String PING = "ping";
+
+ public static final String PLAYER = "player-proc";
+
+ /**
+ * Die HTTP-Anfrage ausführen
+ *
+ * WICHTIG: Die HTTP-Parameter aus dem Query-Teil muessen in
+ * der Reihenfolge sein, die vom Shell-Skript erwartet wird.
+ *
+ * @param elems die Elemente des URI-Pfads
+ * @param parameter die Parameter des Query-Teils der URI
+ * @param exchange das Objekt mit Infos zum HTTP-Aufruf
+ * @return die Antwort, die gesendet werden soll
+ */
+ @Override
+ protected String process(String[] elems, Map parameter, HttpExchange exchange) {
+ String antwort;
+ Object o;
+
+ switch (elems[PLAYERCMD]) {
+ case PLAY:
+ PlayActor a = new PlayActor();
+ o = a.run(parameter);
+ if (o instanceof Process) {
+ exchange.getHttpContext().getAttributes().put(PLAYER, o);
+ antwort = "Abspielprozess gestartet.";
+ } else {
+ // kein Prozess, es ist etwas schief gelaufen
+ antwort = "Abspielen konnte nicht gestartet werden.";
+ }
+ break;
+
+ case PAUSE:
+ case SEEK:
+ ShellActor pa = new ShellActor();
+ try {
+ pa.run(getSkriptDir(exchange), elems[PLAYERCMD], toShellParams(parameter));
+ antwort = elems[PLAYERCMD] + " ausgefuehrt";
+ } catch (IOException ex) {
+ Logger.getLogger(ApiHandler.class.getName()).log(Level.SEVERE, null, ex);
+ antwort = "Fehler bei der Ausfuehrung von " + elems[PLAYERCMD];
+ }
+ break;
+
+ case STOP:
+ o = exchange.getHttpContext().getAttributes().get(PLAYER);
+ if(o instanceof Process) {
+ Process p = (Process) o;
+ p.destroy();
+ antwort = "Player gestoppt.";
+ } else {
+ antwort = "Es wurde kein Player-Prozess zum Stoppen gefunden.";
+ }
+ break;
+
+ case SERVER:
+ if(elems[SERVERCMD].equals(STOP)) {
+ new StopServerActor().run(exchange.getHttpContext());
+ antwort = "Calypso: Der Server wird angehalten und die App beendet.";
+ } else {
+ antwort = elems[SERVERCMD] + " ist ein unbekanntes Serverkommando";
+ }
+ break;
+
+ case PING:
+ antwort = elems[PLAYERCMD];
+ break;
+
+ default:
+ antwort = "Kommando " + elems[PLAYERCMD] + " unbekannt";
+ break;
+ }
+
+ return antwort;
+ }
+
+ private String[] toShellParams(Map parameter) {
+ Collection<String> c = parameter.values();
+ return c.toArray(String[]::new);
+ }
+
+ private String getSkriptDir(HttpExchange exchange) {
+ HttpContext context = exchange.getHttpContext();
+ Object o = context.getAttributes().get(Server.SKRIPT_DIR);
+ if (o instanceof String) {
+ return (String) o;
+ } else {
+ // kein Skript-Dir
+ return "";
+ }
+ }
+}
diff --git a/src/de/uhilger/calypso/neu/http/HttpApi.java b/src/de/uhilger/calypso/neu/http/HttpApi.java
new file mode 100644
index 0000000..ed87d17
--- /dev/null
+++ b/src/de/uhilger/calypso/neu/http/HttpApi.java
@@ -0,0 +1,97 @@
+package de.uhilger.calypso.neu.http;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Die Klasse HttpApi verwendet die von der Klasse HttpExchange
+ * gelieferten Elemente einer HTTP-Anfrage und leitet sie an
+ * die abstrakte Methode process, wo Subklassen das jeweilige
+ * Kommando aus der HTTP-Anfrage ausfuehren können.
+ *
+ * @author Ulrich Hilger
+ */
+public abstract class HttpApi implements HttpHandler {
+
+ public static final String AMP = "&";
+ public static final String SLASH = "/";
+
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ String path = exchange.getRequestURI().getPath();
+ String[] elems = path.split(SLASH);
+ Map params = getQueryMap(exchange);
+ String antwort = process(elems, params, exchange);
+ antwortSenden(exchange, params, path, antwort);
+ }
+
+ /**
+ * Eine HTTP-Anfrage ausführen
+ *
+ * @param elems die Elemente des URI-Pfads
+ * @param parameter die Parameter des Query-Teils der URI
+ * @return die Antwort, die gesendet werden soll
+ */
+ protected abstract String process(String[] elems, Map parameter, HttpExchange exchange);
+
+ /*
+ Den Query-Teil einer URL in die Parameter zerlegen
+
+ Die Zerlegung erfolgt mit String.split nach
+ & und dann nach =
+ */
+ protected Map getQueryMap(HttpExchange t) {
+ HashMap map = new HashMap();
+ String query = t.getRequestURI().getQuery();
+ if(query != null && query.length() > 0) {
+ String qParts[] = query.split("&");
+ for(String qPart : qParts) {
+ Logger logger = Logger.getLogger(de.uhilger.calypso.neu.http.HttpApi.class.getName());
+ logger.log(Level.FINER, "qPart: {0}", qPart);
+ String pParts[] = qPart.split("=");
+ map.put(pParts[0], pParts[1]);
+ logger.log(Level.FINER, "pParts[0]: {0} pParts[1]: {1}", new Object[]{pParts[0], pParts[1]});
+ }
+ }
+ return map;
+ }
+
+ protected void antwortSenden(HttpExchange exchange, Map params, String cmd, String antwort) throws IOException {
+ String httpResponseStr = getResponseString(params, cmd, antwort);
+ sendResponse(exchange, httpResponseStr);
+ }
+
+ protected String getResponseString(Map map, String cmd, String antwort) {
+ Set keys = map.keySet();
+ StringBuilder buf = new StringBuilder();
+ buf.append(cmd);
+ buf.append(System.lineSeparator());
+ keys.forEach((Object key) -> {
+ buf.append("key: ");
+ buf.append(key);
+ buf.append(System.lineSeparator());
+ buf.append("value: ");
+ buf.append(map.get(key));
+ buf.append(System.lineSeparator());
+ //logger.log(Level.FINE, "key {0} value {1}", new Object[]{key, map.get(key)});
+ });
+ buf.append(antwort);
+ return buf.toString();
+ }
+
+ protected void sendResponse(HttpExchange t, String response) throws IOException {
+ t.sendResponseHeaders(200, response.length());
+ OutputStream os = t.getResponseBody();
+ os.write(response.getBytes());
+ os.close();
+ }
+
+
+}
diff --git a/src/de/uhilger/calypso/neu/http/Server.java b/src/de/uhilger/calypso/neu/http/Server.java
new file mode 100644
index 0000000..168d3c9
--- /dev/null
+++ b/src/de/uhilger/calypso/neu/http/Server.java
@@ -0,0 +1,69 @@
+/*
+ Calypso - Media Player Remote Control via HTTP for Raspberry Pi
+ Copyright (C) 2021-2023 Ulrich Hilger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ 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.neu.http;
+
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpServer;
+import de.uhilger.calypso.neu.AppProperties;
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executors;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Ulrich Hilger
+ */
+public class Server {
+
+ //private static final Logger logger = Logger.getLogger(de.uhilger.calypso.Server.class.getName());
+
+ public static final String CONF = "conf";
+ public static final String PORT = "port";
+ public static final String SKRIPTE = "skripte";
+ public static final String CTX = "ctx";
+ public static final String EQUAL = "=";
+ public static final String BLANK = " ";
+ public static final String SKRIPT_DIR = "skript-dir";
+
+
+ public void start(AppProperties einst) {
+ Logger logger = Logger.getLogger(de.uhilger.calypso.neu.http.Server.class.getName());
+ logger.log(Level.INFO, "Server startet auf Port {0}", einst.getString(PORT));
+ String skripte = einst.getString(SKRIPTE);
+ File skript = new File(skripte, "pause");
+ if(skript.exists()) {
+ logger.log(Level.INFO, "Skripte gefunden in {0}", skript.getParentFile().getAbsolutePath());
+ } else {
+ logger.log(Level.INFO, "Skripte nicht gefunden, Ordner laut Einstellungen: {0}", skripte);
+ }
+ try {
+ HttpServer server = HttpServer.create(new InetSocketAddress(einst.getInt(PORT)), 0);
+ String ctx = einst.getString(CTX);
+ HttpContext context = server.createContext(ctx, new ApiHandler());
+ context.getAttributes().put(SKRIPT_DIR, einst.getString(SKRIPTE));
+ server.setExecutor(Executors.newFixedThreadPool(20));
+ server.start();
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ }
+}
diff --git a/src/logging.properties b/src/logging.properties
deleted file mode 100644
index aa7cc61..0000000
--- a/src/logging.properties
+++ /dev/null
@@ -1,72 +0,0 @@
-############################################################
-# Default Logging Configuration File
-#
-# You can use a different file by specifying a filename
-# with the java.util.logging.config.file system property.
-# For example java -Djava.util.logging.config.file=myfile
-############################################################
-
-############################################################
-# Global properties
-############################################################
-
-# "handlers" specifies a comma separated list of log Handler
-# classes. These handlers will be installed during VM startup.
-# Note that these classes must be on the system classpath.
-# By default we only configure a ConsoleHandler, which will only
-# show messages at the INFO and above levels.
-# handlers= java.util.logging.ConsoleHandler
-
-# To also add the FileHandler, use the following line instead.
-# handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
-
-# Default global logging level.
-# This specifies which kinds of events are logged across
-# all loggers. For any given facility this global level
-# can be overriden by a facility specific level
-# Note that the ConsoleHandler also has a separate level
-# setting to limit messages printed to the console.
-# .level= FINE
-.level = OFF
-
-############################################################
-# Handler specific properties.
-# Describes specific configuration info for Handlers.
-############################################################
-
-# default file output is in user's home directory.
-java.util.logging.FileHandler.pattern = %h/java%u.log
-# java.util.logging.FileHandler.pattern = /media/extmirror/tomcat747/logs/tv_%u.log
-# java.util.logging.FileHandler.pattern = ${catalina.base}/logs/file-cms_%u.log
-# java.util.logging.FileHandler.limit = 50000
-# java.util.logging.FileHandler.count = 1
-# java.util.logging.FileHandler.count = 2
-# java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
-java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
-# java.util.logging.FileHandler.level = FINER
-
-# Limit the message that are printed on the console to INFO and above.
-# java.util.logging.ConsoleHandler.level = INFO
-# java.util.logging.ConsoleHandler.level = FINER
-# java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
-
-# Example to customize the SimpleFormatter output format
-# to print one-line log message like this:
-# <level>: <log message> [<date/time>]
-#
-# java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
-
-############################################################
-# Facility specific properties.
-# Provides extra control for each logger.
-############################################################
-
-# For example, set the com.xyz.foo logger to only log SEVERE
-# messages:
-# com.xyz.foo.level = SEVERE
-# de.uhilger.filecms.handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
-# de.uhilger.filecms.level = FINEST
-# de.uhilger.wbx.handlers = java.util.logging.ConsoleHandler
-# de.uhilger.wbx.level = FINEST
-de.uhilger.avdirektor.handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
-de.uhilger.avdirektor.level = FINEST
\ No newline at end of file
--
Gitblit v1.9.3