/*
* 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.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());
/**
* 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
Aufstellung der Parameter.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);
//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
* Liste der Kommandos
* @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);
}
}
}