Darf ich vorstellen? Der neue Rock Antenne Webplayer!

In den letzten Wochen habe ich mich recht intensiv mit dem Design und der Umsetzung eines Radio-Webplayers beschäftigt. Auftraggeber ist Rock Antenne, die als digitaler Tochtersender des bekannten Antenne Bayern fungiert und – wie der Name schon sagt – Rockmusik im Fokus hat. Das ganze auf (zurzeit) vier Kanälen, und mit unterschiedlichsten Schnittstellen zu Livesongs, Playlisten und Künstlerbildern. Ich möchte gerne ein paar der Konzepte erläutern, die bei der Entwicklung des Players eine Rolle gespielt haben.

Rock Antenne

Der Player besteht aus ziemlich vielen Funktionen, die alle in einem übersichtlichen Interface abgebildet werden:

  • Auswahlliste der vorhandenen Streams (wird über ein XML-Konfigurationsfile dynamisch erstellt)
  • Die Anzeige der aktuell laufenden Titel (wird nicht über den Stream geliefert, sondern läuft auf ständig aktualisierten XML-Dateien mit)
  • Der Streamplayer an sich (flashbasiert, holt sich ebenfalls per XML die benötigten Verbindungsdaten und probiert bei Bedarf mehrere Protokolle aus)
  • Die Bildergalerie des aktuellen Künstlers (speist sich aus einer unabhängigen SQL-Bilddatenbank und aktualisiert sich automatisch)
  • Die Playlisten der vergangenen 7 Tage (kommen aus einer anderen SQL-Datenbank)
  • Webcam (simpel, im Vergleich)
  • Community-RSS (die letzten Einträge im Forum, per SimplePie als RSS eingebunden)
  • Kleines Ajax-Mailformular (handgeschrieben)

Klingt insgesamt noch nicht nach einem Riesenaufwand, doch war dann in der Praxis recht kniffelig, weil zwei entscheidende Anforderungen gewährleistet sein mussten: Ressourcenschonung und Kompatibilität. Beides unter einen Hut zu bringen, war das eigentlich Spannende an diesem Projekt.

Ressourcenschonung durch Ajax und Caching

Der Webplayer basiert komplett auf Ajax-Requests, soll heißen: Man startet nur ein einziges Mal einen Komplett-Aufruf der Website-Ressourcen – alles andere lädt später dynamisch nach und fügt sich in den DOM-Baum ein. Das Anklicken der Navigations-Tabs führt zu einem Wechsel der Sichtbarkeit der einzelnen Panels (wobei die inaktiven Panels nur in den unsichtbaren Bereich verschoben werden – der Flashplayer würde sonst nämlich anhalten, wenn man ihn als display:none; markiert). Nur beim Wechsel der aktiven Station (linke Navigation) wird der Flashplayer logischerweise gestoppt und neu geladen.

Zusätzlich zu den User-Interaktionen gibt es mehrere Refresh-Zyklen, die in unterschiedlichen Abständen laufen. Die aktuellen Songs der vier Kanäle werden alle 10 Sekunden nachgeprüft, das Webcam-Bild alle 30 Sekunden aktualisiert, und die kompletten Playlisten alle 3 Minuten. Ergibt sich beim Song-Refresh eine Änderung des aktuell angezeigten Künstlers, wird natürlich noch die Bilddatenbank angezapft und nach vorhandenen Bildern gesucht, die dann per Gallery-Script dargestellt werden.

Da jede laufende Instanz des Webplayers also alle paar Sekunden einige Server-Requests von sich gibt, und viele Leute so einen Webplayer stundenlang laufen lassen, würde die Anzahl der PHP-Aufrufe und DB-Abfragen riesig sein! Von daher wir gecacht, was nur geht! Es läuft alle paar Sekunden ein Cronjob, der sich aus diversen Quellen die aktuellen Infos holt und in eine strukturierte, statische XML-Datei hineinschreibt. Diese kann ohne große Leistungskosten aufgerufen und von jQuery auf dem Client wunderbar verarbeitet werden.

Das ist überhaupt das große Motto gewesen bei der Entwicklung der Player-Architektur: Die Last von Server wegzunehmen und auf den Client zu übertragen. Soviel Caching wie möglich, nur soviele wiederkehrende Server-Requests wie absolut nötig. Von daher friert beispielsweise die Bildergalerie-Funktion ein, wenn das Browserfenster im Hintergrund ist – so werden Traffickosten gespart, wenn sich der User eh nicht mit den Bildern beschäftigt, sondern nur hören will.

Kompatibilität über Fallbacks

Wie erreicht man Kompatibilität bei einer voll ajaxfizierten Website? Man überlegt sich, welche Features wichtiger sind und setzt nur diese um. Und man trickst! Die Tab-Navigation lässt sich auch ohne JavaScript lösen, nämlich mit Sprunglinks! Beim Wechsel der Station wird die Website natürlich komplett neu aufgerufen. Der Flashplayer wird ohne Zuhilfnahme von swfobject.js dargestellt und funktioniert trotzdem (fast) überall. Bildergalerie und Live-Song-Updates funktionieren naturgemäß nicht, aber immerhin: Man kann auch ohne JavaScript viele der Player-Funktionen nutzen!

Und wie steht’s mit Flash-losen Clients? Kein Problem! Glücklicherweise bietet das <object>-Element eine simple Fallback-Funktion an, die auch von fast allen Bowsern (bis auf IE6) gut umgesetzt wird. Falls kein Flash vorhanden ist, geht’s zunächst runter auf einen Windows-Media-Player mit entsprechendem Stream, und falls auch dies nicht möglich ist, wird ein simples <audio>-Element aus HTML5 bemüht, was unter Mac/Safari, iPad und iPhone wunderbar mit einem AAC-Stream funktioniert. Wie ihr seht, besteht fast keine Möglichkeit, das Webradio nicht nutzen zu können, außer, man befindet sich hinter einer paranoiden Firewall – klar!

Selbst das Feedback-Formular, welches eine schicke clientseitige Validierung als Ajax-Request unterstützt, reagiert auch auf einen traditionellen javascriptlosen POST-Request und spuckt die Fehler- oder Erfolgsmeldung dann einfach auf eine leeren neuen Seite aus.

Insgesamt

Es hat sehr großen Spaß gemacht, dieses Projekt umzusetzen – komplett ohne CMS oder serverseitigem Framework. HTML, CSS, XML, Flash, Typekit, PHP, MySQL, Ajax/jQuery – fast alle Gebiete, auf denen ich mich auskenne, konnte ich hier sinnvoll zum Einsatz bringen, das kommt selten vor!

Negativer Nebeneffekt: Ich kann jetzt noch weniger mit Rockmusik anfangen als vorher ;-)