App zur Steuerung des mpv Mediaplayers auf einem Raspberry Pi über HTTP
...
ulrich
2021-03-23 b6a8f02169ecea91936e81c297e8ce0f1b2f107b
commit | author | age
8e2038 1 package de.uhilger.avdirektor.handler;
U 2
3 import de.uhilger.avdirektor.App;
4 import de.uhilger.avdirektor.MeldeThread;
5 import de.uhilger.avdirektor.ProzessLauscher;
6 import java.io.BufferedWriter;
7 import java.io.IOException;
8 import java.io.OutputStream;
9 import java.io.OutputStreamWriter;
10 import java.io.Writer;
11 import java.net.HttpURLConnection;
12 import java.net.URL;
13 import java.util.logging.Level;
14 import java.util.logging.Logger;
15
16 /**
cc2a32 17  * Methoden zur Ausfuehrung des Programmes omxplayer des Raspberry Pi 
U 18  * sowie zum Senden von Kommandos an eine laufende Instanz des 
19  * omxplayer.
20  * 
21  * Die Klasse OMXPlayer stellt als abstrakte Basisklasse ihre Methoden 
22  * den Handler-Klassen zur Verfuegung.
8e2038 23  *
U 24  * @author ulrich
25  */
26 public abstract class OMXPlayer implements ProzessLauscher {
27   
28   private static final Logger logger = Logger.getLogger(OMXPlayer.class.getName());
0c8d27 29   
8e2038 30   /**
U 31    * Einen Prozess zum Abspielen mit dem omxplayer starten
32    * @param urlStr  URL der Quelle, die abgespielt werden soll
33    * @param token
34    * @return Antwort des Servers
35    */
b6a8f0 36   /*
a7f0a1 37   public String abspielen(String urlStr, String token) {
U 38     return abspielenMitParametern(urlStr, null, token);
8e2038 39   }
b6a8f0 40   */
8e2038 41   
b6a8f0 42   /*
a7f0a1 43   public String abspielenMitRueckmeldung(String urlStr, String meldeUrlStr, String token) {
U 44     return abspielenMitParameternUndRueckmeldung(urlStr, null, meldeUrlStr, token);
8e2038 45   }
b6a8f0 46   */
8e2038 47   
U 48   /**
49    * Einen Prozess zum Abspielen mit dem omxplayer starten 
50    * und Parameter uebergeben.Moegliche Parameter fuer das Abspielen mit dem omxplayer 
51  beschreibt die Seite 
52   <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.
53    * App.OPT_LOCAL_AUDIO oder App.OPT_HDMI_AUDIO.
54  Mehrere Parameter werden mit App.BLANK getrennt.
55    * @param urlStr  der URL der Quelle, die abgespielt werden soll
56    * @param parameter  die Parameter, die vom omxplayer angewendet werden sollen
57    * @param token
58    * @return Antwort des Servers
59    */
b6a8f0 60   /*
a7f0a1 61   public String abspielenMitParametern(String urlStr, String parameter, String token) {
U 62     return abspielenMitParameternUndRueckmeldung(urlStr, parameter, null, token);
8e2038 63   }
b6a8f0 64   */
8e2038 65   
b6a8f0 66   public String abspielen(String urlStr, String parameter, String meldeUrlStr, String token) {
8e2038 67     String antwort;// = null;
U 68     try {
a7f0a1 69       //Object o = t.getAttribute(App.PI_PLAYER);
U 70       Process o = App.getPlayerProcess();
8e2038 71       if(o != null) {
a7f0a1 72         tilgen();        
8e2038 73       }
U 74       StringBuilder kommando = new StringBuilder("omxplayer ");
75       if(parameter != null) {
76         kommando.append(parameter);
77         kommando.append(App.BLANK);
78       }
79       if(urlStr.startsWith("http")) {
80         kommando.append(urlStr.replace(" ", "%20"));
81         kommando.append("?t=");
82         kommando.append(token);
83       } else {
84         /*
85           //url z.B.: Filme/H/HEAT_D2.m4v
86         
87           hier muss noch der Pfad hinzugefuegt werden, unter 
88           dem auf dem raspi die Datenquelle via NFS eingebunden ist,
89           z.B. /media/mc/
90           dieser Teil des Pfades muss in pirc als Init-Parameter oder 
91           etwas aehnliches hinterlegt sein, weil es lokal zum jeweils 
92           verwendeten raspi gehoert
93   
94         */
95         
96         String pfad = App.getInitParameter("nfs-prefix");
97         kommando.append(pfad);
98         
99         kommando.append(urlStr);
100       }
101       logger.log(Level.FINE, "kommando: {0}", kommando.toString());
102       Process player_process = Runtime.getRuntime().exec(kommando.toString());
103       if(meldeUrlStr != null) {
104         MeldeThread mt = new MeldeThread();
105         mt.setProcess(player_process);
106         mt.lauscherHinzufuegen(this);
107         mt.setMeldeUrl(meldeUrlStr);
108         mt.start();
109       }
110       //servletContext.setAttribute(App.PI_PLAYER, player_process);
a7f0a1 111       //t.setAttribute(App.PI_PLAYER, player_process);
U 112       App.setPlayerProcess(player_process);
8e2038 113       //Runtime.getRuntime().exec("killall dbus-daemon");
U 114       antwort = "Abspielen gestartet, url: " + urlStr;
115     }
116     catch(IOException ex) {
117       antwort = "Fehler: " + ex.getMessage();
118     }
119     return antwort;
120   }
121     
122   /**
123    * Einen eventuell laufenden Abspielprozess beenden und den 
124    * Servlet-Kontext bereinigen.Diese Methode kann auch verwendet werden, wenn es beim normalen
125  Abspielen zu Fehlern kommt und womoeglich der Servlet-Kontext noch 
126  eine Referenz zu einem Abspielprozess enthaelt, die nicht mehr 
127  aktuell ist.
128    * 
129    * Mit der Methode tilgen kann man eine solche Referenz 
130  entfernen und gibt so das Objekt wieder frei fuer die Ausfuehrung 
131  weiterer Kommandos.
132    *
133    * @return die Antwort des Servers
134    */
a7f0a1 135   public String tilgen() {
8e2038 136     String antwort; // = null;
U 137     try {
a7f0a1 138       //Object o = t.getAttribute(App.PI_PLAYER);
U 139       Process o = App.getPlayerProcess();
8e2038 140       if(o == null) {
a7f0a1 141         //t.setAttribute(App.PI_PLAYER, null);
U 142         App.setPlayerProcess(null);
8e2038 143         // t.removeAttribute(App.PI_PLAYER);
U 144         antwort = "Es ist kein Player zum Beenden vorhanden, aber der Servlet-Kontext wurde bereinigt.";
145       } else {
a7f0a1 146         kommando(App.CMD_STOP);
8e2038 147         //t.removeAttribute(PI_PLAYER);
U 148         antwort = "Player gestoppt, Kontext bereinigt.";
149       }
150     } 
151     catch(Exception ex) {
152       antwort = "Fehler: " + ex.getMessage();
153     }
154     return antwort;
155   }
156   
157   
158   /**
159    * Dem laufenden Abspielprozess ein Kommando uebermitteln
160    * @param k  das Kommando laut 
161    * <a href="https://github.com/huceke/omxplayer/blob/master/README.md" target="_blank">Liste der Kommandos</a>
162    * @return die Antwort des Servers
163    */
a7f0a1 164   public String kommando(String k) {
8e2038 165     String antwort; // = null;
U 166     try {
a7f0a1 167       //Object o = t.getAttribute(App.PI_PLAYER);
U 168       Process o = App.getPlayerProcess();
8e2038 169       if(o == null) {
a7f0a1 170         App.setPlayerProcess(null);
8e2038 171         //servletContext.removeAttribute(PI_PLAYER);
a7f0a1 172         //t.setAttribute(App.PI_PLAYER, null);
8e2038 173         antwort = "Es wird nichts abgespielt dem ein Kommando gesendet werden kann.";
U 174       } else {
a7f0a1 175         Process player_process = o;
8e2038 176         OutputStream os = player_process.getOutputStream();
U 177         Writer out = new BufferedWriter(new OutputStreamWriter(os));
178         out.write(k);
179         out.flush();
180         if(k.equals(App.CMD_STOP)) {
181           out.close();
a7f0a1 182           App.setPlayerProcess(null);
8e2038 183           //player_process.destroy();
U 184           //player_process = null;
a7f0a1 185           //t.setAttribute(App.PI_PLAYER, null);
8e2038 186           //servletContext.removeAttribute(PI_PLAYER);
U 187         }
188         antwort = "Kommando '" + k + "' ausgefuehrt.";
189       }
190     } 
191     catch(IOException ex) {
192       antwort = "Fehler: " + ex.getMessage();
193     }
194     return antwort;
195   }
196   
197   /* ------ Implementierung ProzessLauscher ----------------- */
198   
199   @Override
200   public void prozessBeendet(String meldeUrlStr) {
201     try {
202       HttpURLConnection conn = (HttpURLConnection) new URL(meldeUrlStr).openConnection();
203       conn.setRequestMethod("GET");
204       conn.connect();
205       int status = conn.getResponseCode();
206       logger.log(Level.INFO, "Abspielen beendet, Meldung an {0} mit Statuscode {1} gesendet.", new Object[]{meldeUrlStr, status});
207     } catch(IOException ex) {
208       logger.log(Level.INFO, ex.getMessage(), ex);
209     }
210   }
211   
212 }