src/de/uhilger/mediaz/api/AbstractHandler.java | ●●●●● patch | view | raw | blame | history | |
src/de/uhilger/mediaz/api/ListFileHandler.java | ●●●●● patch | view | raw | blame | history | |
src/de/uhilger/mediaz/api/MediaSteuerung.java | ●●●●● patch | view | raw | blame | history | |
src/de/uhilger/mediaz/api/StorageHandler.java | ●●●●● patch | view | raw | blame | history | |
src/de/uhilger/mediaz/entity/Livestream.java | ●●●●● patch | view | raw | blame | history | |
src/de/uhilger/mediaz/store/FileStorage.java | ●●●●● patch | view | raw | blame | history | |
www/ui/data/tpl/form_livestream.txt | ●●●●● patch | view | raw | blame | history | |
www/ui/data/tpl/livestream_liste.txt | ●●●●● patch | view | raw | blame | history | |
www/ui/index.html | ●●●●● patch | view | raw | blame | history | |
www/ui/js/app.js | ●●●●● patch | view | raw | blame | history |
src/de/uhilger/mediaz/api/AbstractHandler.java
@@ -69,7 +69,7 @@ response = json; } else { response = "nicht gefunden"; returnCode = RTC_NOT_FOUND; //returnCode = RTC_NOT_FOUND; } break; src/de/uhilger/mediaz/api/ListFileHandler.java
@@ -33,7 +33,6 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; src/de/uhilger/mediaz/api/MediaSteuerung.java
@@ -26,6 +26,7 @@ import de.uhilger.mediaz.entity.Abspielliste; import de.uhilger.mediaz.entity.Einstellung; import de.uhilger.mediaz.entity.Entity; import de.uhilger.mediaz.entity.Livestream; import de.uhilger.mediaz.entity.Titel; import de.uhilger.mediaz.store.FileStorage; import de.uhilger.mediaz.store.Storage; @@ -45,7 +46,8 @@ * HTTP GET /mz/api/strg/abspieler/play/liste/[name] * HTTP GET /mz/api/strg/abspieler/ende * * HTTP POST /mz/api/strg/abspieler/play mit dem Titel im Body * HTTP POST /mz/api/strg/abspieler/play/titel mit dem Titel im Body * HTTP POST /mz/api/strg/abspieler/play/stream mit dem Livestream im Body (nur Name gefuellt) * * HTTP GET /mz/api/strg/abspieler/pause * HTTP GET /mz/api/strg/abspieler/stop @@ -128,7 +130,7 @@ String path = e.getRequestURI().toString(); String[] elems = path.split(Server.SLASH); FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF))); if(elems[5].equalsIgnoreCase("titel")) { String titelJson = bodyLesen(e); Gson gson = new Gson(); Object o = gson.fromJson(titelJson, fs.typeFromName(Titel.class.getSimpleName()).getType()); @@ -148,6 +150,33 @@ } else { return meldung("Ungueltiger Titel.", 404); } } else if(elems[5].equalsIgnoreCase("stream")) { String streamJson = bodyLesen(e); Gson gson = new Gson(); Object o = gson.fromJson(streamJson, fs.typeFromName(Livestream.class.getSimpleName()).getType()); if(o instanceof Livestream) { Entity entity = fs.read(FileStorage.ST_LIVESTREAM, ((Livestream) o).getName()); if(entity instanceof Livestream) { Livestream stream = (Livestream) entity; entity = fs.read(FileStorage.ST_ABSPIELER, elems[4]); if (entity instanceof Abspieler) { Abspieler abspieler = (Abspieler) entity; String server = ""; String signal = abspielKommando(fs, abspieler, server, stream.getUrl()).toString(); abspielerKommandoSenden(signal); return signal + "gesendet."; } else { return meldung("Ungueltiger Abspieler.", 404); } } else { return meldung("Ungueltiger Livestream.", 404); } } else { return meldung("Ungueltiger Livestream.", 404); } } else { return meldung("Ungueltiger URL.", 404); } } private String kommandoSenden(Storage s, String aName, String kommando) { src/de/uhilger/mediaz/api/StorageHandler.java
@@ -24,6 +24,7 @@ import de.uhilger.mediaz.Server; import de.uhilger.mediaz.store.FileStorage; import de.uhilger.mediaz.entity.Entity; import static de.uhilger.mediaz.store.FileStorage.ST_ABLAGEORT; import java.io.IOException; import java.util.List; import java.util.logging.Level; @@ -86,6 +87,9 @@ String type = elems[elems.length - 2]; logger.fine(type); list = fs.list(type); if(type.equalsIgnoreCase(ST_ABLAGEORT)) { list.add("Livestreams"); } } else { String type = elems[elems.length - 1]; logger.fine(type); src/de/uhilger/mediaz/entity/Livestream.java
New file @@ -0,0 +1,47 @@ /* Mediazentrale - Personal Media Center Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. */ package de.uhilger.mediaz.entity; /** * * @author Ulrich Hilger */ public class Livestream implements Entity { private String name; private String url; @Override public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } } src/de/uhilger/mediaz/store/FileStorage.java
@@ -19,7 +19,6 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import de.uhilger.mediaz.App; import de.uhilger.mediaz.Server; import de.uhilger.mediaz.entity.Ablageort; import de.uhilger.mediaz.entity.Abspieler; @@ -33,6 +32,7 @@ import java.io.IOException; import java.util.logging.Logger; import de.uhilger.mediaz.entity.Entity; import de.uhilger.mediaz.entity.Livestream; import de.uhilger.mediaz.entity.Titel; import java.util.ArrayList; import java.util.HashMap; @@ -60,6 +60,7 @@ public static final String ST_EINSTELLUNG = "Einstellung"; public static final String ST_ABSPIELER = "Abspieler"; public static final String ST_ABSPIELLISTE = "Abspielliste"; public static final String ST_LIVESTREAM = "Livestream"; private final String fileBase; @@ -73,6 +74,7 @@ TypeToken<Einstellung> ttEinstellung = new TypeToken<Einstellung>() {}; TypeToken<Abspieler> ttAbspieler = new TypeToken<Abspieler>() {}; TypeToken<Abspielliste> ttAbspielliste = new TypeToken<Abspielliste>() {}; TypeToken<Livestream> ttLivestream = new TypeToken<Livestream>() {}; TypeToken<Titel> ttTitel = new TypeToken<Titel>() {}; types = new HashMap(); types.put(Ablageort.class.getSimpleName(), ttAblageort); @@ -80,6 +82,7 @@ types.put(Abspieler.class.getSimpleName(), ttAbspieler); types.put(Abspielliste.class.getSimpleName(), ttAbspielliste); types.put(Titel.class.getSimpleName(), ttTitel); types.put(Livestream.class.getSimpleName(), ttLivestream); } /** www/ui/data/tpl/form_livestream.txt
New file @@ -0,0 +1,11 @@ <form> <div class="entity-formular"> <input name="name" class="entity-element" type="text" id="livestream-name" placeholder="Name" value="{{name}}" /> <input name="url" class="entity-element" type="text" id="livestream-url" placeholder="Pfad" value="{{url}}" /> <div class="entity-buttons"> <button type="submit" class="button-primary" id="ok-btn">Speichern</button> <button class="button" id="cancel-btn">Abbrechen</button> <button class="button" id="loeschen-btn">Löschen</button> </div> </div> </form> www/ui/data/tpl/livestream_liste.txt
New file @@ -0,0 +1,7 @@ <div class='entity-formular'> <ul class='entity-liste'> {{#ArrayList}} <li class='entity-eintrag'>{{.}}</li> {{/ArrayList}} </ul> </div> www/ui/index.html
@@ -52,7 +52,7 @@ <a id="mi-listen"><i class="icon-list"></i> Abspiellisten</a> <a id="mi-orte"><i class="icon-database"></i> Kataloge</a> <a id="mi-player"><i class="icon-play"></i> Abspieler</a> <a id="mi-radio"><i class="icon-ellipsis-vert"></i> Radio</a> <a id="mi-live"><i class="icon-ellipsis-vert"></i> Livestream</a> <a id="mi-prefs"><i class="icon-sliders"></i> Einstellungen</a> </div> </div> www/ui/js/app.js
@@ -30,6 +30,7 @@ self.addEvtListener('#mi-player', 'click', self.abspieler_liste); self.addEvtListener('#mi-listen', 'click', self.abspielliste_liste); self.addEvtListener('#mi-list', 'click', self.titel_liste); self.addEvtListener('#mi-live', 'click', self.livestream_liste); self.fusszeile_umschalten(); self.seitenleiste_umschalten(); @@ -37,6 +38,21 @@ }; /* ---------------- Entitaets-Listen ----------------- */ this.livestream_selection = function() { document.querySelector('.breadcrumb-behaelter').textContent = ''; document.querySelector('.bereich-name').textContent = 'Livestream-Auswahl'; self.http_get('../api/store/Livestream/liste/', function(responseText) { self.vorlage_laden_und_fuellen("data/tpl/livestream_liste.txt", JSON.parse(responseText), function (html) { document.querySelector(".zentraler-inhalt").innerHTML = html; self.addEvtListener('.entity-eintrag', 'click', function (event) { var t = event.target; self.removeClassMulti('selected'); t.classList.add('selected'); }); }); }); }; // auf der obersten Ebene werden die Kataloge angezeigt, // darunter der Inhalt des aktuellen Pfades @@ -55,11 +71,15 @@ self.addEvtListener('.entity-eintrag', 'click', function (event) { var t = event.target; self.katName = t.textContent; if(self.katName !== "Livestreams") { self.http_get('../api/store/Ablageort/' + t.textContent, function(responseText) { var ablageort = JSON.parse(responseText); self.ortPfad = ablageort.url; self.media_liste(); }); } else { self.livestream_selection(); } }); }); }); @@ -161,6 +181,15 @@ }); }; this.livestream_liste = function() { self.entitaet_liste('Livestream','../api/store/Livestream/liste/', "data/tpl/livestream_liste.txt", '../api/store/Livestream/', "self.livestream_form", function(responseText) { var livestream = JSON.parse(responseText); self.livestream_form(livestream); }); }; this.abspielliste_liste = function() { self.entitaet_liste('Abspielliste','../api/store/Abspielliste/liste/', "data/tpl/abspielliste_liste.txt", '../api/store/Abspielliste/', @@ -191,6 +220,14 @@ '#abspieler-name', function() { self.abspieler_auswahl_fuellen(); self.abspieler_liste(); }); }; this.livestream_form = function(ls) { self.entitaet_form('Livestream', ls, ls.name, "data/tpl/form_livestream.txt", '../api/store/Livestream/', '#livestream-name', function() { self.livestream_liste(); }); }; @@ -322,7 +359,14 @@ url: /media/test/M/Muenchener-Freiheit/01-Ohne-Dich-schlaf-ich-heut-Nacht-nicht-ein.mp3 */ console.log('plname: ' + playername + ' url: ' + titel.katalogUrl + titel.pfad + titel.name); self.http_post('../api/strg/' + playername, JSON.stringify(titel), function(responseText) { self.http_post('../api/strg/' + playername + '/titel', JSON.stringify(titel), function(responseText) { self.meldung_mit_timeout(responseText, 1500); }); } else if(bereichName === 'Livestream-Auswahl') { var streamName = document.querySelector(".selected").textContent; var playername = document.querySelector('#abspieler').value; var stream = new Livestream(streamName, '-'); self.http_post('../api/strg/' + playername + '/stream', JSON.stringify(stream), function(responseText) { self.meldung_mit_timeout(responseText, 1500); }); } else { @@ -772,6 +816,11 @@ this.url = u; } function Livestream(n, u) { this.name = n; this.url = u; } function Abspielliste(n) { this.name = n; }