App zur Steuerung des mpv Mediaplayers auf einem Raspberry Pi über HTTP
undisclosed
2023-01-08 e27ab178fa3a2f967823c1bfc81951086e15b642
Package-Namen zurueckgesetzt, weitere Anpassungen nachgezogen, Readme erneuert.
1 files modified
11 files renamed
202 ■■■■ changed files
README.md 143 ●●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/App.java 4 ●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/AppProperties.java 2 ●●● patch | view | raw | blame | history
src/de/uhilger/calypso/MeldeThread.java 4 ●●● patch | view | raw | blame | history
src/de/uhilger/calypso/ProzessLauscher.java 2 ●●● patch | view | raw | blame | history
src/de/uhilger/calypso/Rueckmelder.java 4 ●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/actor/PlayActor.java 8 ●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/actor/ShellActor.java 4 ●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/actor/StopServerActor.java 2 ●●● patch | view | raw | blame | history
src/de/uhilger/calypso/http/ApiHandler.java 19 ●●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/http/HttpApi.java 4 ●●●● patch | view | raw | blame | history
src/de/uhilger/calypso/http/Server.java 6 ●●●● patch | view | raw | blame | history
README.md
@@ -41,7 +41,7 @@
mkdir classes
mkdir dist
$JDK/bin/javac -d classes src/de/uhilger/calypso/*.java src/de/uhilger/calypso/handler/*.java
$JDK/bin/javac -d classes src/de/uhilger/calypso/*.java src/de/uhilger/calypso/actor/*.java  src/de/uhilger/calypso/http/*.java
$JDK/bin/jar -cf dist/calypso.jar -C classes .
rm -r classes
@@ -49,144 +49,3 @@
Das fertig verwendbare Programm liegt anschließend unter `$CALYPSO/dist/calypso.jar`.
## Media-Quellen einrichen
Calypso kann in zwei Betriebsarten gestartet werden:
1. NFS-Client
1. HTTP-Client
### NFS-Client
Mit dem Parameter `nfs-prefix` spielt Calypso Media-Inhalte aus Quellen ab, die über das Network File System (NFS) eingebunden sind.
```
java -jar calypso.jar nfs-prefix="/media/mc" port=9090
```
In dieser Betriebsart wird dem Inhalt, der beim Abspielen über den Parameter `title` angegeben wird, der Präfix aus dem Parameter `nfs-prefix` vorangestellt. Wird Calypso beispielsweise mit folgendem URL aufgerufen:
```
http://rpi4-wz:9090/calypso/play?title=/Filme/H/heat.m4v
```
wird die Datei `/media/mc/Filme/H/heat.m4v` abgespielt.
#### Betriebsart NFS-Client einrichten
Zur Verwendung Calypsos in der Betriebsart NFS-Client muss der Raspberry Pi die Softwarepakete für den NFS-Client installiert haben. Zudem muss auf dem Raspberry Pi in der Datei `/etc/fstab` ein Eintrag gemacht werden, der die entsprechende Quelle angibt, z.B.
```
mein-media-server:/media/extssd/mc /media/mc nfs rw 0 0
```
Welche Quellen für einen solchen Eintrag verfügbar sind lässt sich auf dem Raspberry Pi mit folgendem Kommando sehen.
```
showmount -e mein-media-server
```
Die Maschine `mein-media-server` in den obigen Beispielen muss dafür als NFS-Server eingerichtet sein und Inhalte entsprechend via NFS freigeben.
### HTTP-Client
Das folgende Kommando startet Calypso als HTTP-Client.
```
java -jar calypso.jar port=9090
```
Wird der Parameter `nfs-prefix` beim Start Calypsos weggelassen, werden im Parameter `titel` Uniform Resource Locators (URLs) zu Media-Quellen erwartet wie z.B. in
```
http://mein-raspi:9090/calypso/play?title=http://mein-media-server:8080/tango/media/Filme/H/heat.m4v
```
Für das Abspielen über HTTP muss der Raspberry Pi nicht als NFS-Client eingerichtet werden. Der Media-Server muss dann das Streaming über HTTP implementieren.
## Steuerbefehle
Die folgenden Service-Endpunkte werden von Calypso bereitgestellt.
/calypso/play +
/calypso/seek +
/calypso/pause +
/calypso/stop +
/calypso/ping +
/calypso/server/stop
### play
Text
### seek
Text
### pause
Test
### stop
Text
### ping
Text
### server/stop
Text
## Calypso als Dienst einrichten
Das Verteilpaket Calypsos enthält eine Beispieldatei namens `calypso.service`. Diese verweist auf das ebenfalls im Verteilpaket enthaltene Beispiel-Startskript namens `start`. Nach Anpassung der Pfade in `calypso.service` kann die Datei wie in folgendem Beispiel in das passende Systemverzeichnis des Raspberry Pi kopiert werden.
```
cd /home/pi/prg/calypso
sudo cp calypso.service /etc/systemd/system/calypso.service
```
### Dienst starten
Mit folgendem Kommando kann der Dienst probehalber gestartet werden.
```
sudo systemctl start calypso.service
```
### Dienst stoppen
Der laufende Dienst kann mit folgendem Signal via HTTP veranlasst werden, sich zu beenden.
```
http://mein-raspi:9090/calypso/server/stop
```
Ueber systemd kann stattdessen der Prozess wie folgt 'hart' beendet werden.
```
sudo systemctl stop calypso.service
```
### Dienst dauerhaft aktivieren
Der folgende Befehl bewirkt, dass der Dienst nach einem Neustart des Raspberry Pi automatisch startet.
```
sudo systemctl enable calypso.service
```
### Dienst deaktivieren
```
sudo systemctl disable calypso.service
```
### Status des Dienstes pruefen
```
sudo systemctl status calypso
```
src/de/uhilger/calypso/App.java
File was renamed from src/de/uhilger/calypso/neu/App.java
@@ -16,9 +16,9 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso.neu;
package de.uhilger.calypso;
import de.uhilger.calypso.neu.http.Server;
import de.uhilger.calypso.http.Server;
import java.util.HashMap;
/**
src/de/uhilger/calypso/AppProperties.java
File was renamed from src/de/uhilger/calypso/neu/AppProperties.java
@@ -16,7 +16,7 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso.neu;
package de.uhilger.calypso;
import java.io.File;
import java.io.FileInputStream;
src/de/uhilger/calypso/MeldeThread.java
File was renamed from 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.neu;
package de.uhilger.calypso;
import java.util.logging.Logger;
import java.util.logging.Level;
@@ -53,8 +53,6 @@
    try {
      exitValue = omxplayer.waitFor();
      prozessBeendetMelden();
      lauscher.clear();
      lauscher = null;
    } catch(InterruptedException ex) {
      logger.log(Level.FINE, ex.getMessage(), ex);
    } finally {
src/de/uhilger/calypso/ProzessLauscher.java
File was renamed from src/de/uhilger/calypso/neu/ProzessLauscher.java
@@ -16,7 +16,7 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso.neu;
package de.uhilger.calypso;
public interface ProzessLauscher {
  
src/de/uhilger/calypso/Rueckmelder.java
File was renamed from src/de/uhilger/calypso/neu/Rueckmelder.java
@@ -16,7 +16,7 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso.neu;
package de.uhilger.calypso;
import java.io.IOException;
import java.net.HttpURLConnection;
@@ -34,7 +34,7 @@
  @Override
  public void prozessBeendet(String meldeUrlStr) {
    Logger logger = Logger.getLogger(de.uhilger.calypso.neu.http.ApiHandler.class.getName());
    Logger logger = Logger.getLogger(de.uhilger.calypso.http.ApiHandler.class.getName());
    logger.log(Level.INFO,
            "Abspielen beendet, sende Meldung an {0}.",
            new Object[]{meldeUrlStr});
src/de/uhilger/calypso/actor/PlayActor.java
File was renamed from src/de/uhilger/calypso/neu/actor/PlayActor.java
@@ -16,11 +16,11 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso.neu.actor;
package de.uhilger.calypso.actor;
import de.uhilger.calypso.neu.MeldeThread;
import de.uhilger.calypso.neu.Rueckmelder;
import de.uhilger.calypso.neu.http.Server;
import de.uhilger.calypso.MeldeThread;
import de.uhilger.calypso.Rueckmelder;
import de.uhilger.calypso.http.Server;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
src/de/uhilger/calypso/actor/ShellActor.java
File was renamed from src/de/uhilger/calypso/neu/actor/ShellActor.java
@@ -16,9 +16,9 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso.neu.actor;
package de.uhilger.calypso.actor;
import de.uhilger.calypso.neu.http.Server;
import de.uhilger.calypso.http.Server;
import java.io.File;
import java.io.IOException;
src/de/uhilger/calypso/actor/StopServerActor.java
File was renamed from src/de/uhilger/calypso/neu/actor/StopServerActor.java
@@ -16,7 +16,7 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso.neu.actor;
package de.uhilger.calypso.actor;
import com.sun.net.httpserver.HttpContext;
import java.util.Timer;
src/de/uhilger/calypso/http/ApiHandler.java
File was renamed from src/de/uhilger/calypso/neu/http/ApiHandler.java
@@ -16,14 +16,15 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso.neu.http;
package de.uhilger.calypso.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 de.uhilger.calypso.actor.PlayActor;
import de.uhilger.calypso.actor.ShellActor;
import de.uhilger.calypso.actor.StopServerActor;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Map;
import java.util.logging.Level;
@@ -109,8 +110,14 @@
        
      case SERVER:
        if(elems[SERVERCMD].equals(STOP)) {
          new StopServerActor().run(exchange.getHttpContext());
          antwort = "Calypso: Der Server wird angehalten und die App beendet.";
          try {
            antwort = "Calypso: Der Server wird angehalten und die App beendet.";
            sendResponse(exchange, antwort);
            new StopServerActor().run(exchange.getHttpContext());
          } catch (IOException ex) {
            Logger.getLogger(ApiHandler.class.getName()).log(Level.SEVERE, null, ex);
            antwort = "Fehler: " + ex.getLocalizedMessage();
          }
        } else {
          antwort = elems[SERVERCMD] + " ist ein unbekanntes Serverkommando";
        }
src/de/uhilger/calypso/http/HttpApi.java
File was renamed from src/de/uhilger/calypso/neu/http/HttpApi.java
@@ -16,7 +16,7 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso.neu.http;
package de.uhilger.calypso.http;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
@@ -71,7 +71,7 @@
    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 logger = Logger.getLogger(de.uhilger.calypso.http.HttpApi.class.getName());
        logger.log(Level.FINER, "qPart: {0}", qPart);
        String pParts[] = qPart.split("=");
        map.put(pParts[0], pParts[1]);
src/de/uhilger/calypso/http/Server.java
File was renamed from src/de/uhilger/calypso/neu/http/Server.java
@@ -16,11 +16,11 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
package de.uhilger.calypso.neu.http;
package de.uhilger.calypso.http;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpServer;
import de.uhilger.calypso.neu.AppProperties;
import de.uhilger.calypso.AppProperties;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
@@ -46,7 +46,7 @@
  
  public void start(AppProperties einst) {
    Logger logger = Logger.getLogger(de.uhilger.calypso.neu.http.Server.class.getName());
    Logger logger = Logger.getLogger(de.uhilger.calypso.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");