/*
Calypso - Media Player Remote Control via HTTP for Raspberry Pi
Copyright (C) 2021-2023 Ulrich Hilger
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
package de.uhilger.calypso;
import com.sun.net.httpserver.HttpServer;
import de.uhilger.calypso.handler.BasePlayer;
import de.uhilger.calypso.handler.CmdHandler;
import de.uhilger.calypso.handler.DBusHandler;
import de.uhilger.calypso.handler.FileHandler;
import de.uhilger.calypso.handler.LogHandler;
import de.uhilger.calypso.handler.MPVKillHandler;
import de.uhilger.calypso.handler.MPVPlayHandler;
import de.uhilger.calypso.handler.MPVPlayer;
import de.uhilger.calypso.handler.MPVSeekHandler;
import de.uhilger.calypso.handler.MPlayHandler;
import de.uhilger.calypso.handler.MPlayer;
import de.uhilger.calypso.handler.OMXPlayer;
import de.uhilger.calypso.handler.PingHandler;
import de.uhilger.calypso.handler.PlayHandler;
import de.uhilger.calypso.handler.PlayOnHandler;
import de.uhilger.calypso.handler.SeekHandler;
import de.uhilger.calypso.handler.SocketHandler;
import de.uhilger.calypso.handler.StopServerHandler;
import de.uhilger.calypso.handler.VLCKillHandler;
import de.uhilger.calypso.handler.VLCPlayer;
import de.uhilger.calypso.handler.VLCSeekHandler;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.logging.Level;
/**
* Die Klasse Server implementiert die HTTP-Schnittstelle zum
* Mediaplayer. Es wird ein Player-Prozesss fuer das Abspielen
* eines Titels gestartet. Mit Stopp oder Ende des Titels endet
* auch der Abspielprozess.
*
* zum Abspielen:
* /calypso/play?title=http://ein.titel.mp3&r=http://rueckmelde.url
*
* waehrend des Abspielens:
* /calypso/pause
* /calypso/seek?pos=[sekunden]
* /calypso/stop
*
* sonstige Funktionen:
* /calypso/ping
* /calypso/server/stop
*
* verworfene Funktionen
* /calypso/vol-inc
* /calypso/vol-dec
* Die Lautstaerke wird in aller Regel am Geraet geregelt, an das der
* Zuspieler (der Raspi) angeschlossen ist. Eine Regelung ueber den
* Zuspieler ist daher eher selten erforderlich.
*
* @author Ulrich Hilger
*/
public class Server {
private static final Logger logger = Logger.getLogger(Server.class.getName());
private int port;
private String contextName;
private String path;
public Server(int port) {
this.port = port;
}
public void setPort(int port) {
this.port = port;
}
public void setPath(String path) {
this.path = path;
}
/**
*
* @param contextName e.g. '/calypso' or '/cal'
*/
public void setContextName(String contextName) {
this.contextName = contextName;
}
public void start(String playerType) throws IOException {
logger.log(Level.INFO, "Server starting on port {0}", port);
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
if (playerType.equals(App.OMX_PLAYER)) {
server.createContext(contextName + "/play", new PlayHandler(BasePlayer.F_PLAY));
server.createContext(contextName + "/seek", new SeekHandler(OMXPlayer.F_SEEK));
server.createContext(contextName + "/stop", new CmdHandler(OMXPlayer.CMD_STOP));
server.createContext(contextName + "/pause", new CmdHandler(OMXPlayer.CMD_PAUSE_RESUME));
server.createContext(contextName + "/vol-inc", new CmdHandler(OMXPlayer.CMD_INC_VOL));
server.createContext(contextName + "/vol-dec", new CmdHandler(OMXPlayer.CMD_DEC_VOL));
server.createContext(contextName + "/info", new CmdHandler(OMXPlayer.CMD_TOGGLE_INFO));
server.createContext(contextName + "/log", new LogHandler());
server.createContext(contextName + "/playon", new PlayOnHandler(OMXPlayer.F_PLAY_ON));
} else if (playerType.equals(App.VLC_PLAYER)) {
server.createContext(contextName + "/play", new PlayHandler(BasePlayer.F_PLAY));
server.createContext(contextName + "/pause", new DBusHandler(VLCPlayer.CMD_PAUSE_RESUME));
//server.createContext(contextName + "/pause", new CmdHandler("pause"));
//server.createContext(contextName + "/seek", new DBusHandler(VLCPlayer.CMD_SEEK));
server.createContext(contextName + "/seek", new VLCSeekHandler(VLCPlayer.CMD_SEEK));
server.createContext(contextName + "/stop", new VLCKillHandler());
} else if (playerType.equals(App.M_PLAYER)) {
server.createContext(contextName + "/play", new MPlayHandler());
server.createContext(contextName + "/pause", new CmdHandler(MPlayer.CMD_PAUSE_RESUME));
server.createContext(contextName + "/stop", new CmdHandler(MPlayer.CMD_STOP));
} else if (playerType.equals(App.MPV_PLAYER)) {
server.createContext(contextName + "/play", new MPVPlayHandler());
server.createContext(contextName + "/pause", new SocketHandler(path + MPVPlayer.CMD_PAUSE_RESUME));
server.createContext(contextName + "/seek", new MPVSeekHandler(path + MPVPlayer.CMD_SEEK));
server.createContext(contextName + "/stop", new MPVKillHandler());
}
server.createContext(contextName + "/ui", new FileHandler(App.getInitParameter(App.IP_WWW_DATA)));
server.createContext(contextName + "/ping", new PingHandler(BasePlayer.F_PING));
server.createContext(contextName + "/server/stop", new StopServerHandler());
//server.setExecutor(null); // creates a default executor
server.setExecutor(Executors.newFixedThreadPool(20));
server.start();
}
}