Bedienoberfläche für Webradio
ulrich
2018-01-07 c70430dc43ff3d8dc786d699f3eda0194e53c8ec
commit | author | age
623a61 1 # radio-ui
U 2
3 Eine Bedienoberfläche für Webradio
851c9c 4
70e1ff 5 ## Prototyp
U 6
ec55bf 7 Diese Anwendung ist zur Zeit im Bau. Der aktuelle Prototyp zum Stand des Codes in diesem Repository ist hier zu sehen: [Link zum Prototyp](/data/ulrich/test/radio-ui).
851c9c 8
ad1fef 9 ## Vorgesehene Funktionen
U 10
11 Das radio-ui zeigt eine Übersicht von Radiosendern. Antippen eines Senders in der Übersicht spielt den Sender ab.
12
13 Radiosender können hinzugefügt, geändert und gelöscht werden. Ein Suchfeld ermöglicht das Einschränken der Übersicht auf bestimmte Sender.
14
fe1cb2 15 Das Abspiel-Ziel ist konfigurierbar: Ein Radionsender kann entweder auf dem Gerät abgespielt werden, auf dem das radio-ui im Browser läuft oder auf einem anderen Gerät wie z.B. einem Raspberry Pi.
ad1fef 16
U 17 Zum Abspielen auf einem Raspberry Pi ist die Nutzung der Anwendung [pirc](/gitblit/docs/pirc.git) vorgesehen, die zum Spielen von Audiostreams den [omxplayer](https://elinux.org/Omxplayer) mit einer unter [Tomcat](https://de.wikipedia.org/wiki/Apache_Tomcat) laufenden Fernbedienung kombiniert, die per HTTP gesteuert werden kann.
18
8d53d7 19 ## Beispielcharakter
U 20
21 Neben dem praktischen Nutzen veranschaulicht das radio-ui verschiedene Aspekte des Baus von Webanwendungen:
22
96834e 23 + app-layout
8d53d7 24 + Vorlagen
96834e 25 + app-menu
8d53d7 26 + CRUD-Muster (Create, Read, Update, Delete)
U 27
28 Wie in der Anwendung radio-ui die obigen Themen umgesetzt sind, ist nachfolgend kurz betrachtet.
96834e 29
U 30 ### app-layout
31
32 Das radio-ui verwendet das [app-layout](/gitblit/docs/web!app-layout.git), das mit Hilfe von HTML und CSS die Grundlage einer für Webanwendungen geeigneten Bedienoberfläche schafft. Der nachfolgende Vergleich von Webseiten mit Webanwendungen will das verdeutlichen.
33
34 #### Webseiten
35
36 Charakteristisch für eine Webseite ist ihr Seitencharakter, bei dem der Webbrowser Inhalte von links nach rechts und von oben nach unten darstellt.
37
38 Inhalte, die über den Raum auf dem Bildschirm hinausgehen, setzen sich jenseits des unteren Bildrands fort und werden durch Rollen nach unten sichtbar. Dabei verschwinden am oberen Bildrand untergebrachte Kontrollelemente mit den dort befindlichen Inhalten.
39
6d5a45 40 Eine Webseite kann viele dynamische Funktionen enthalten und in diesem Punkt einer Webanwendung gleichen. Charakteristisch für Webseiten ist aber die Darstellung von Inhalten und nicht so sehr die Ausführung von Funktionen.
96834e 41
U 42 #### Webanwendungen
43
44 Charakteristisch für Webanwendungen ist der Schwerpunkt auf Funktionen und ihre Bedienung. Eine Webanwendung nutzt die Mittel von HTML, CSS und Javascript u.a. zur Herstellung einer Bedienoberfläche.
45
46 Die Bedienelemente der Anwendung bleiben stets erreichbar, auch, wenn Inhalte den verfügbaren Raum auf dem Bildschirm überschreiten. Bereiche zur Darstellung von Inhalten und deren Bearbeitung sind gemischt mit Kontroll- und Bedienelementen. Die Anordnung dieser Elemente folgt im Verlauf der Nutzung individuell den Erfordernissen des jeweiligen Anwendungsfalls.
47
48 Das Layout der Bedienoberfläche bleibt insgesamt stets gleich, zu keiner Zeit führt ein Wechsel von Teilen des Bildschirminhalts zu einer Veränderung des Layouts oder zum vollständigen Verschwinden von Bedien- und Kontrollelementen.
49
50 Die Webanwendung ist auf verschiedenen Geräten verwendbar und funktioniert mit unterschiedlichen Bildschirmen (Größe, Auflösung) und Eingabegeräten (Maus, Tastatur, berührungsempfindlicher Bildschirm)  gleichartig.
51
52 Die hier beschriebenen Eigenschaften einer Webanwendung werden mit dem Einsatz des app-layout hergestellt.
8d53d7 53
U 54 ### Nutzung von Vorlagen
851c9c 55
e8a097 56 Die Anwendung radio-ui ist ein Beispiel für die Nutzung von Vorlagen in Webanwendungen. Die Datei `index.html` definiert Bereiche einer HTML-Seite als `div`-Elemente, die während der Ausführung des Programmes dynamisch mit wechselnden Inhalten gefüllt werden.
U 57
6592dc 58 Inhalte werden dabei mit Hilfe von [Mustache](https://github.com/janl/mustache.js) aus einer Vorlage und einer Inhaltsbeschreibung in [JSON](https://de.wikipedia.org/wiki/JavaScript_Object_Notation) zu [HTML](https://de.wikipedia.org/wiki/Hypertext_Markup_Language) zusammengesetzt.
96834e 59
U 60 Durch die Nutzung von Vorlagen lassen sich dynamische und statische Inhalte sowie deren Gestaltung und Struktur optimal und frei von Redundanzen zusammenführen.
61
62 ### app-menu
63
6d5a45 64 Das [app-menu](/gitblit/docs/web!app-menu.git) setzt auf die Nutzung von Vorlagen auf und fügt dem radio-ui ein Menü zur Bedienung der Anwendung hinzu. Es ist zudem eingebettet in die Funktion des app-layout. Das radio-ui zeigt so den Einsatz des app-menu und mithin das Zusammenspiel von Vorlagen, app-layout und Menü am praktischen Beispiel.
851c9c 65
8d53d7 66 ### CRUD-Muster
U 67
68 CRUD (Create, Read, Update, Delete) ist ein häufig vorkommendes Nutzungsmuster von Anwendungen, Daten werden erzeugt, gelesen, bearbeitet und gelöscht. Bei Webanwendungen zerfällt es in einen Teil, der auf dem Server ausgeführt wird und einen, der im Browser abläuft (Bedienoberfläche).
69
6d5a45 70 Allein bezogen auf den Umgang mit den Daten auf der Serverseite ist das CRUD-Muster schnell umgesetzt. Eine Datenstruktur wird erzeugt, gelesen, gespeichert und gelöscht. Eine Bedienoberfläche zur Ausführung dieser Operationen erfordert allerdings mehr als nur den Anstoß der jeweiligen Operation.
U 71
72 Beim radio-ui wird beispielsweise mit den Daten der Radiosender auf diese Weise umgegangen. Die folgende Tabelle veranschaulicht die benötigten Funktionen.
8d53d7 73
U 74 | Operation        | Bedienoberfläche (radio-ui)           | Server  |
75 | ------------- |-------------| -----|
76 | Create      | Funktion zum Auslösen der Erstellung eines neuen Senders, Dialog zur Eingabe der Daten, Funktion zum Senden der neuen Daten  | Speichern eines neuen Senders |
96834e 77 | Read      | Funktion zum Abruf der Senderliste, Lesen der Senderliste, Darstellen der Liste als Kacheln      |   Ausgeben einer Liste von Sendern |
8d53d7 78 | Update | Funktion zum Auslösen der Änderung an einem Sender, Funktion zur Auswahl eines Senders aus einer Liste, Darstellen der Daten des gewählten Senders in einem Dialog zum Bearbeiten, Funktion zum Senden der Änderungen    |    Speichern von Änderungen an einem bestehenden Sender |
U 79 | Delete | Funktion zum Auslösen der Löschfunktion, Funktion zur Auswahl eines Senders oder mehrerer Sender aus einer Liste, Funktion zum Senden einer Liste zu löschender Sender, Funktion zur Absicherung gegenüber versehentlichem Löschen    |    Löschen eines Senders oder mehrerer Sender |
80
81 Die Tabelle läßt ahnen, dass der größere Aufwand zur Herstellung eines CRUD-Musters auf die Bedienoberfläche entfällt.
82
96834e 83 Mit seinen Menüfunktionen und der Art, wie mit Daten als Liste und als einzelnem Datensatz umgegangen wird sowie der Kombination dieser Funktionen mit der Verwendung von Vorlagen zeigt das radio-ui einen generischen Lösungsansatz, der sich für die Wiederverwendung in anderen Anwendungen eignet und dabei wenige Abhängigkeiten erfordert.
8d53d7 84
36646e 85 ## Abhängigkeiten
f927ec 86
36646e 87 Zur Verwendung des radio-ui sind die folgenden Komponenten erforderlich
f927ec 88
36646e 89 + [jQuery](http://jquery.com/)
U 90 + [Mustache](https://github.com/janl/mustache.js)
91 + [app-menu](/gitblit/docs/web!app-menu.git)
f927ec 92
36646e 93 Diese sind in der Datei `index.html` über die folgenden Einträge eingebunden.
f927ec 94
36646e 95 ````
U 96 <link rel="stylesheet" type="text/css" href="../jslib/app-menu/app-menu.css">
97 <script src="../jslib/jquery-1.11.1/jquery-1.11.1.min.js"></script>
98 <script src="../jslib/mustache/mustache.min.js"></script>
99 <script src="../jslib/app-menu/app-menu.js"></script>
100 ````
851c9c 101
899220 102 Sollen einzelne Komponenten von einem anderen Ort wie beispielsweise einem Content Delivery Network (CDN) eingebunden werden, müssen nur die obigen Einträge entsprechend angepasst werden.
851c9c 103
fe1cb2 104 ## Kombination von pirc und radio-ui
U 105
106 Zur Verwendung des radio-ui mit pirc kann die Anwendung radio-ui direkt auf einen Raspberry Pi installiert werden, beispielsweise ähnlich wie pirc als Webanwendung für Tomcat. Stattdessen kann radio-ui auch von einer anderen Maschine aus die pirc-Instanz auf einen Raspberry Pi aufrufen.
107
108 Auch eine direkte Steuerung des omxplay aus radio-ui heraus ist denkbar. Das wäre allerdings eine Doppelung der meisten der in pirc bereits enthaltenen Funktionen. Zudem würde die engere Koppelung zwischen Pi und radio-ui die Verwendbarkeit des radio-ui einschränken.
109
110 ### Abspielen auf dem Raspberry Pi
111
112 Kommandos an pirc werden via HTTP an die betreffende Maschine gesendet und bestehen aus einem Klassennamen `c`, einem Methodennamen `m` und einem Parameter `p`. Ein Kommando setzt sich wie folgt zusammen
113
114 1. `http://raspi:8080/` - URL der Maschine
115 1. `pirc/` - Name des Kontext, unter dem die Anwendung pirc läuft
116 1. `sys/rpc` - Service-Endpunkt der pirc-API
117 1. `c=de.uhilger.pirc.App` - Name der Klasse von pirc, die die Abspielmethode enthält
118 1. `m=abspielen` - Name der Methode zum Abspielen
119 1. `p=Sender-URL` - der Parameter mit dem URL zum Audiostream des Webradiosenders
120
121 Zum Aufruf des Kommandos mit dem radio-ui kann es weitgehend unverändert bleiben. Nur der Teil 6. mit dem URL des Senders muss veränderlich gestaltet sein.
122
123 #### Beispiel Abspielen
124
125 Ist die Fernbedienung pirc auf einem Raspberry Pi installiert, lautet das Kommando zum Abspielen des Webradiosenders radiobob (vgl. Senderliste weiter unten) wie folgt
126
127 ````
abef80 128 http://raspi:8080/pirc/sys/rpc?c=de.uhilger.pirc.App&m=abspielen&p=http://bob.hoerradar.de/radiobob-live-mp3-hq&p=
fe1cb2 129 ````
U 130
131 Das obige Kommando geht davon aus, dass der betreffende Raspberry Pi unter dem Namen `raspi` auf Port `8080` über `HTTP` erreichbar ist und dass auf dem Pi die Anwendung pirc unter dem Kontextnamen `pirc` installiert wurde. Es bewirkt, dass auf dem betreffenden Raspberry Pi eine Instanz des omxplayer gestartet wird und diese fortlaufend den Webradio-Stream unter der angegebenen Adresse abspielt.
132
133 #### Beispiel Stoppen
134
135 Zum Stoppen des zur Zeit abgespielten Webradios dient das folgende Kommando
136
137 ````
138 http://raspi:8080/sys/rpc?c=de.uhilger.pirc.App&m=kommando&p=q
139 ````
140
141 Mit dem obigen Aufruf wird das Kommando `q` an den laufenden Prozess des omxplayer gesendet. Das bewirkt, dass der omxplayer das Abspielen stoppt und der laufende omxplayer-Prozess endet.
142
143
899220 144 ## Radiostreams
851c9c 145
899220 146 Nachfolgend die Adressen einiger Radiostreams
851c9c 147
899220 148 ### hr3
851c9c 149
899220 150 [Livestream-Übersicht](http://www.hr3.de/service/hr3-online-hoeren,webradio-100.html)
851c9c 151
899220 152 128 kbit http://hr-hrinfo-live.cast.addradio.de/hr/hrinfo/live/mp3/128/stream.mp3
851c9c 153
899220 154 48 kbit http://hr-hr3-live.cast.addradio.de/hr/hr3/live/mp3/48/stream.mp3
f927ec 155
899220 156 ### hr info
f927ec 157
899220 158 [Livestream-Übersicht](http://www.hr-inforadio.de/livestream/index.html)
f927ec 159
899220 160 128 kBit/s http://hr-hrinfo-live.cast.addradio.de/hr/hrinfo/live/mp3/128/stream.mp3
f927ec 161
899220 162 48 kBit/s http://hr-hrinfo-live.cast.addradio.de/hr/hrinfo/live/mp3/48/stream.mp3
36646e 163
899220 164 ### radiobob
36646e 165
899220 166 [Livestream-Übersicht](http://www.radiobob.de/radiobob/empfang/livestream)
36646e 167
899220 168 MP3: http://bob.hoerradar.de/radiobob-live-mp3-hq
36646e 169
899220 170 Mobile Nutzung: http://bob.hoerradar.de/aac-radiobob
36646e 171
899220 172 ### FFH
36646e 173
899220 174 [Livestream-Übersicht](https://www.ffh.de/musik/webradios/stream-adressen.html)
36646e 175
899220 176 128kbps http://mp3.ffh.de/radioffh/hqlivestream.mp3
36646e 177
899220 178 48kbps http://mp3.ffh.de/radioffh/livestream.aac
576085 179
U 180 ## Noch zu erledigen
181
182 ### Templates für Mustache dynamisch laden
183
184 Spart Ladezeit zu Beginn. Lösungsansatz: Eine Funktion, die als Parameter das Element erhält, dessen html mit dem gerenderten Template ersetzt werden soll und den zu rendernden Inhalt. Die dynamische Ladefunktion
185
186 1. prüft, ob das Template schon im cache ist
187 1. Lädt das Template, wenn nicht
188 1. wartet, bis das Template geladen ist
189 1. rendert das Template mit dem übergebenen Inhalt
190 1. schreibt das Ergebnis ins html des übergebenen Elements
191
192 Der letzte Teil des Ablaufs muss asynchron gefasst sein, damit auf das Laden gewartet werden kann.
193
194 ## Schnittstellenbeschreibung
195
6a62bd 196 Für den Prototyp des radio-ui können verschiedene Arten des Umgangs mit Sendern und Abspielern hergestellt werden. Die folgenden Angaben zeigen die Punkte auf, an denen eine konkrete Implementierung ansetzen kann.
576085 197
6a62bd 198 ### Sender
U 199
200 #### Senderliste lesen
576085 201
U 202 Aufruf
068ce7 203
576085 204 ````
U 205 data/sender.json
206 ````
207
208 Antwort
068ce7 209
576085 210 ````
U 211 {
212   "senderliste": {
213     "titel": "Senderliste",
214     "inhalt":  [
215       {
216         "senderid": 1,
217         "sendername": "hr info",
218         "senderurl": "http://hr-hrinfo-live.cast.addradio.de/hr/hrinfo/live/mp3/128/stream.mp3",
219         "senderlogo": "../bilder/hr-info.png"
220       },
221       {
222         "senderid": 2,
223         "sendername": "radiobob",
224         "senderurl": "http://bob.hoerradar.de/radiobob-live-mp3-hq",
225         "senderlogo": "../bilder/radio-bob-logo-80.png"
226       },
227       usw.
228     ]
229   }
230 }
231 ````
232
6a62bd 233 #### Neuen Sender speichern
576085 234
U 235 Noch nicht realisiert.
236
6a62bd 237 #### Änderungen an einem Sender speichern
576085 238
U 239 Noch nicht realisiert.
240
6a62bd 241 #### Sender löschen
U 242
243 Noch nicht realisiert.
244
245 ### Abspieler
246
247 #### Abspielerliste lesen
248
249 Aufruf
250
251 ````
252 data/abspieler.json
253 ````
254
255 Antwort
256
257 ````
258 {
259   "abspielerliste": {
260     "titel": "Abspielerliste",
261     "inhalt":  [
262       {
263         "abspielerid": 1,
264         "abspielername": "dieses Gerät",
265         "abspielerurl": "",
266         "abspielertyp":"lokal",
267         "abspielerbild": "",
268         "abspielerzustand":""
269       },
270       {
271         "abspielerid": 2,
272         "abspielername": "Raspberry Pi Wohnzimmer",
273         "abspielerurl": "",
274         "abspielertyp":"pirc",
275         "abspielerbild": "",
276         "abspielerzustand":"selected"
277       },
278       usw.
279     ]
280   }
281 }
282 ````
283
284 #### Neuen Abspieler speichern
285
286 Noch nicht realisiert.
287
288 #### Änderungen an einem Abspieler speichern
289
290 Noch nicht realisiert.
291
292 #### Abspieler löschen
576085 293
U 294 Noch nicht realisiert.