App zur Steuerung des mpv Mediaplayers auf einem Raspberry Pi über HTTP
ulrich
2021-04-01 2dd7a5b331b57db5c7aa5bef9540e3e198848060
commit | author | age
60719c 1 /*
U 2     AV-Direktor - Control OMXPlayer on Raspberry Pi via HTTP
3     Copyright (C) 2021  Ulrich Hilger
4
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU Affero General Public License as
7     published by the Free Software Foundation, either version 3 of the
8     License, or (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU Affero General Public License for more details.
14
15     You should have received a copy of the GNU Affero General Public License
16     along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
8e2038 19 package de.uhilger.avdirektor.handler;
U 20
21 import de.uhilger.avdirektor.App;
22 import de.uhilger.avdirektor.MeldeThread;
23 import de.uhilger.avdirektor.ProzessLauscher;
24 import java.io.BufferedWriter;
2dd7a5 25 import java.io.File;
8e2038 26 import java.io.IOException;
U 27 import java.io.OutputStream;
28 import java.io.OutputStreamWriter;
29 import java.io.Writer;
30 import java.net.HttpURLConnection;
31 import java.net.URL;
2dd7a5 32 import java.util.ArrayList;
U 33 import java.util.Arrays;
34 import java.util.List;
8e2038 35 import java.util.logging.Level;
U 36 import java.util.logging.Logger;
37
38 /**
cc2a32 39  * Methoden zur Ausfuehrung des Programmes omxplayer des Raspberry Pi 
U 40  * sowie zum Senden von Kommandos an eine laufende Instanz des 
41  * omxplayer.
42  * 
43  * Die Klasse OMXPlayer stellt als abstrakte Basisklasse ihre Methoden 
44  * den Handler-Klassen zur Verfuegung.
8e2038 45  *
U 46  * @author ulrich
47  */
cfe367 48 public class OMXPlayer implements Player , ProzessLauscher {
8e2038 49   
U 50   private static final Logger logger = Logger.getLogger(OMXPlayer.class.getName());
0c8d27 51   
cfe367 52   public static final String BLANK = " ";
0af362 53   public static final String CMD_DEC_SPEED = "1";
U 54   public static final String CMD_DEC_VOL = "-";
cfe367 55   public static final String CMD_INC_SPEED = "2";
0af362 56   public static final String CMD_INC_VOL = "+";
cfe367 57   public static final String CMD_NEXT_AUDIO = "k";
U 58   public static final String CMD_NEXT_CHAPTER = "o";
59   public static final String CMD_NEXT_SUB = "m";
60   public static final String CMD_PAUSE_RESUME = "p";
61   public static final String CMD_PREV_AUDIO = "j";
62   public static final String CMD_PREV_CHAPTER = "i";
63   public static final String CMD_PREV_SUB = "n";
64   public static final String CMD_STOP = "q";
65   public static final String CMD_TOGGLE_SUB = "s";
66   public static final String F_PING = "ping";
0af362 67   public static final String F_PLAY = "play";
2dd7a5 68   public static final String F_PLAY_ON = "playon";
0af362 69   public static final String F_SEEK = "seek";
cfe367 70   public static final String OPT_HDMI_AUDIO = "-o%20hdmi";
U 71   public static final String OPT_LOCAL_AUDIO = "-o%20local";
72   public static final String PFEIL_HERAUF = "5b41";
73   public static final String PFEIL_HERUNTER = "5b42";
74   public static final String PFEIL_LINKS = "5b44";
75   public static final String PFEIL_RECHTS = "5b43";
76   public static final String SP_RUECK_30 = "rueck30";
77   public static final String SP_RUECK_600 = "rueck600";
78   public static final String SP_VOR_30 = "rueck30";
79   public static final String SP_VOR_600 = "vor600";
0af362 80
cfe367 81   @Override
b6a8f0 82   public String abspielen(String urlStr, String parameter, String meldeUrlStr, String token) {
8e2038 83     String antwort;// = null;
U 84     try {
a7f0a1 85       Process o = App.getPlayerProcess();
8e2038 86       if(o != null) {
a7f0a1 87         tilgen();        
8e2038 88       }
2dd7a5 89       List<String> kommando = new ArrayList();
U 90       kommando.add("omxplayer");
91       kommando.addAll(Arrays.asList(parameter.split(BLANK)));
8e2038 92       if(urlStr.startsWith("http")) {
2dd7a5 93         kommando.add(urlStr.replace(" ", "%20"));
8e2038 94       } else {
2dd7a5 95         kommando.add(App.getInitParameter("nfs-prefix") + urlStr);        
U 96       }      
97       logger.log(Level.FINE, "parameter: {0}", parameter);
8e2038 98       logger.log(Level.FINE, "kommando: {0}", kommando.toString());
2dd7a5 99       ProcessBuilder pb = new ProcessBuilder(kommando);
U 100       pb.directory(new File(System.getProperty("omx.wd")));
101       Process player_process = pb.start();
8e2038 102       if(meldeUrlStr != null) {
U 103         MeldeThread mt = new MeldeThread();
104         mt.setProcess(player_process);
105         mt.lauscherHinzufuegen(this);
106         mt.setMeldeUrl(meldeUrlStr);
107         mt.start();
108       }
a7f0a1 109       App.setPlayerProcess(player_process);
8e2038 110       antwort = "Abspielen gestartet, url: " + urlStr;
U 111     }
112     catch(IOException ex) {
113       antwort = "Fehler: " + ex.getMessage();
114     }
115     return antwort;
116   }
117     
118   /**
119    * Einen eventuell laufenden Abspielprozess beenden und den 
120    * Servlet-Kontext bereinigen.Diese Methode kann auch verwendet werden, wenn es beim normalen
121  Abspielen zu Fehlern kommt und womoeglich der Servlet-Kontext noch 
122  eine Referenz zu einem Abspielprozess enthaelt, die nicht mehr 
123  aktuell ist.
124    * 
125    * Mit der Methode tilgen kann man eine solche Referenz 
126  entfernen und gibt so das Objekt wieder frei fuer die Ausfuehrung 
127  weiterer Kommandos.
128    *
129    * @return die Antwort des Servers
130    */
cfe367 131   @Override
a7f0a1 132   public String tilgen() {
8e2038 133     String antwort; // = null;
U 134     try {
a7f0a1 135       Process o = App.getPlayerProcess();
8e2038 136       if(o == null) {
U 137         antwort = "Es ist kein Player zum Beenden vorhanden, aber der Servlet-Kontext wurde bereinigt.";
2dd7a5 138         App.setPlayerProcess(null);
8e2038 139       } else {
2dd7a5 140         kommando(CMD_STOP); // setzt den Prozess der App auf null
8e2038 141         antwort = "Player gestoppt, Kontext bereinigt.";
U 142       }
143     } 
144     catch(Exception ex) {
145       antwort = "Fehler: " + ex.getMessage();
146     }
147     return antwort;
148   }
149   
150   
151   /**
152    * Dem laufenden Abspielprozess ein Kommando uebermitteln
153    * @param k  das Kommando laut 
154    * <a href="https://github.com/huceke/omxplayer/blob/master/README.md" target="_blank">Liste der Kommandos</a>
155    * @return die Antwort des Servers
156    */
cfe367 157   @Override
a7f0a1 158   public String kommando(String k) {
8e2038 159     String antwort; // = null;
U 160     try {
a7f0a1 161       //Object o = t.getAttribute(App.PI_PLAYER);
U 162       Process o = App.getPlayerProcess();
8e2038 163       if(o == null) {
a7f0a1 164         App.setPlayerProcess(null);
8e2038 165         //servletContext.removeAttribute(PI_PLAYER);
a7f0a1 166         //t.setAttribute(App.PI_PLAYER, null);
8e2038 167         antwort = "Es wird nichts abgespielt dem ein Kommando gesendet werden kann.";
U 168       } else {
a7f0a1 169         Process player_process = o;
8e2038 170         OutputStream os = player_process.getOutputStream();
U 171         Writer out = new BufferedWriter(new OutputStreamWriter(os));
172         out.write(k);
173         out.flush();
0af362 174         if(k.equals(CMD_STOP)) {
8e2038 175           out.close();
a7f0a1 176           App.setPlayerProcess(null);
8e2038 177           //player_process.destroy();
U 178           //player_process = null;
a7f0a1 179           //t.setAttribute(App.PI_PLAYER, null);
8e2038 180           //servletContext.removeAttribute(PI_PLAYER);
U 181         }
182         antwort = "Kommando '" + k + "' ausgefuehrt.";
183       }
184     } 
185     catch(IOException ex) {
186       antwort = "Fehler: " + ex.getMessage();
187     }
188     return antwort;
189   }
190   
191   /* ------ Implementierung ProzessLauscher ----------------- */
192   
193   @Override
194   public void prozessBeendet(String meldeUrlStr) {
195     try {
196       HttpURLConnection conn = (HttpURLConnection) new URL(meldeUrlStr).openConnection();
197       conn.setRequestMethod("GET");
198       conn.connect();
199       int status = conn.getResponseCode();
2dd7a5 200       logger.log(Level.INFO, 
U 201               "Abspielen beendet, Meldung an {0} mit Statuscode {1} gesendet.", 
202               new Object[]{meldeUrlStr, status});
203       App.setPlayerProcess(null);
8e2038 204     } catch(IOException ex) {
U 205       logger.log(Level.INFO, ex.getMessage(), ex);
206     }
207   }
208   
209 }