/*
|
* 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.avdirektor.handler;
|
|
import com.sun.net.httpserver.HttpExchange;
|
import de.uhilger.avdirektor.App;
|
import de.uhilger.avdirektor.MeldeThread;
|
import de.uhilger.avdirektor.ProzessLauscher;
|
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.HashMap;
|
import java.util.Map;
|
import java.util.Set;
|
import java.util.logging.Level;
|
import java.util.logging.Logger;
|
|
/**
|
*
|
* @author ulrich
|
*/
|
public abstract class OMXPlayer implements ProzessLauscher {
|
|
private static final Logger logger = Logger.getLogger(OMXPlayer.class.getName());
|
|
protected String getParam(Map map, String key) {
|
Object o = map.get(key);
|
if(o != null) {
|
return o.toString();
|
} else {
|
return null;
|
}
|
}
|
|
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.info("qPart: " + qPart);
|
String pParts[] = qPart.split("=");
|
map.put(pParts[0], pParts[1]);
|
}
|
}
|
return map;
|
}
|
|
protected String getResponseString(Map map, String cmd, String antwort) {
|
Set keys = map.keySet();
|
StringBuilder buf = new StringBuilder();
|
buf.append("play");
|
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();
|
}
|
|
/**
|
* Einen Prozess zum Abspielen mit dem omxplayer starten
|
* @param t
|
* @param urlStr URL der Quelle, die abgespielt werden soll
|
* @param token
|
* @return Antwort des Servers
|
*/
|
public String abspielen(HttpExchange t, String urlStr, String token) {
|
return abspielenMitParametern(t, urlStr, null, token);
|
}
|
|
public String abspielenMitRueckmeldung(HttpExchange t, String urlStr, String meldeUrlStr, String token) {
|
return abspielenMitParameternUndRueckmeldung(t, 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 t
|
* @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(HttpExchange t, String urlStr, String parameter, String token) {
|
return abspielenMitParameternUndRueckmeldung(t, urlStr, parameter, null, token);
|
}
|
|
public String abspielenMitParameternUndRueckmeldung(HttpExchange t, String urlStr, String parameter, String meldeUrlStr, String token) {
|
String antwort;// = null;
|
try {
|
Object o = t.getAttribute(App.PI_PLAYER);
|
if(o != null) {
|
tilgen(t);
|
}
|
StringBuilder kommando = new StringBuilder("omxplayer ");
|
if(parameter != null) {
|
kommando.append(parameter);
|
kommando.append(App.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);
|
}
|
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);
|
//Runtime.getRuntime().exec("killall dbus-daemon");
|
antwort = "Abspielen gestartet, url: " + urlStr;
|
}
|
catch(IOException ex) {
|
antwort = "Fehler: " + ex.getMessage();
|
}
|
return antwort;
|
}
|
|
/**
|
* 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.
|
*
|
* @param t
|
* @return die Antwort des Servers
|
*/
|
public String tilgen(HttpExchange t) {
|
String antwort; // = null;
|
try {
|
Object o = t.getAttribute(App.PI_PLAYER);
|
if(o == null) {
|
t.setAttribute(App.PI_PLAYER, null);
|
// t.removeAttribute(App.PI_PLAYER);
|
antwort = "Es ist kein Player zum Beenden vorhanden, aber der Servlet-Kontext wurde bereinigt.";
|
} else {
|
kommando(t, App.CMD_STOP);
|
//t.removeAttribute(PI_PLAYER);
|
antwort = "Player gestoppt, Kontext bereinigt.";
|
}
|
}
|
catch(Exception ex) {
|
antwort = "Fehler: " + ex.getMessage();
|
}
|
return antwort;
|
}
|
|
|
/**
|
* Dem laufenden Abspielprozess ein Kommando uebermitteln
|
* @param t
|
* @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
|
*/
|
public String kommando(HttpExchange t, String k) {
|
String antwort; // = null;
|
try {
|
Object o = t.getAttribute(App.PI_PLAYER);
|
if(o == 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 = (Process) o;
|
OutputStream os = player_process.getOutputStream();
|
Writer out = new BufferedWriter(new OutputStreamWriter(os));
|
out.write(k);
|
out.flush();
|
if(k.equals(App.CMD_STOP)) {
|
out.close();
|
//player_process.destroy();
|
//player_process = null;
|
t.setAttribute(App.PI_PLAYER, null);
|
//servletContext.removeAttribute(PI_PLAYER);
|
}
|
antwort = "Kommando '" + k + "' ausgefuehrt.";
|
}
|
}
|
catch(IOException ex) {
|
antwort = "Fehler: " + ex.getMessage();
|
}
|
return antwort;
|
}
|
|
/* ------ Implementierung ProzessLauscher ----------------- */
|
|
@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});
|
} catch(IOException ex) {
|
logger.log(Level.INFO, ex.getMessage(), ex);
|
}
|
}
|
|
}
|