Gestern hat digitalhandwerk Radio die Marke von 1000 Hörerinnen und Hörern geknackt. Danke dafür, ehrlich. Zwischen den Glückwünschen kam aber auch Kritik, und die war berechtigt: Im Auto konnte man den Sender nicht hören. Wer ihn über CarPlay oder in einer Radio-App aufdrehen wollte, fand schlicht nichts.
Der Grund ist unspektakulär. Mein Radio war bis heute kein Internetradio im eigentlichen Sinn, sondern eine Webseite, die sehr überzeugend so tut, als wäre sie eins. Seit heute gibt es einen echten HLS-Stream. Nach diesem Artikel weißt du, warum dieser Unterschied so groß ist, wie ich den Stream ohne laufenden Serverprozess gebaut hab und wo du den Sender jetzt findest. Starten wir bei dem, was einem Sender fehlt, der nur im Browser lebt.
Ein Webplayer macht aus einer Webseite noch keinen Radiosender. Erst eine einzige Adresse, die endlos läuft, macht ihn für Autos, Apps und Verzeichnisse hörbar.
Kurz erklärt:
- HLS (HTTP Live Streaming): ein von Apple entwickeltes Streaming-Verfahren, bei dem Audio in kurze Stücke zerlegt und über eine Playlist ausgeliefert wird. Offen spezifiziert in der IETF-Spezifikation RFC 8216 zu HTTP Live Streaming.
- m3u8: die Playlist-Datei, die ein Player laufend neu abruft, um die nächsten Stücke zu finden. Ihre Adresse ist die Stream-URL.
- radio-browser.info: eine offene Community-Datenbank für Internetradiosender, aus der sich viele Radio-Apps bedienen.
Warum war mein Radio vorher kein echtes Internetradio?
Wer die Senderseite schon kennt (und die bleibt auch!), weiß, wie sie arbeitet. Ich hab ausführlich beschrieben, wie das vollautonome KI-Webradio auf radio.digitalhandwerk.rocks entstanden ist: Ein KI-Moderator stellt Beiträge aus meinem Blog vor, dazwischen läuft Rock und die eine oder andere italienische Ballade aus meinem Suno-Bestand, jeder Titel durch meinen selbst gebauten Mastering-Dienst für KI-Musik. Dazu kommen stündlich KI-Interviews, bei denen der Gast bewusst keinen Namen trägt.
Technisch ist die Sendung aber kein Stream. Sie besteht aus einer Manifest-Datei und einem Haufen MP3s. Der Player im Browser liest das Manifest, schaut auf die Uhr und rechnet aus, an welcher Stelle der Sendung er gerade sein müsste. Dadurch hören alle dieselbe Stelle, obwohl nirgends ein Stream läuft. Zur Laufzeit braucht das keine Datenbank und keinen Server, der irgendwas tut. Für den Browser ist das elegant.
Das Autoradio sieht das anders. CarPlay, Android Auto, eine Radio-App oder ein WLAN-Radio in der Küche führen mein JavaScript nicht aus. Die wollen genau eine Adresse, hinter der Ton kommt, und zwar endlos. Diese Adresse hatte mein Sender nicht. Ich hab das beim Bauen schlicht nicht mitgedacht, weil ich das Radio immer am Rechner oder am Handy im Browser gehört hab. Blinder Fleck, klassisch.
Warum hab ich nicht einfach Icecast genommen?
Die naheliegende Lösung für Internetradio heißt seit Jahrzehnten Icecast. Ein Streaming-Server, der ununterbrochen Audio an jeden verbundenen Hörer schiebt. Funktioniert, ist erprobt, und trotzdem hab ich mich dagegen entschieden.
Was das konkret bedeutet: Icecast braucht einen Prozess, der rund um die Uhr läuft. Bei mir wäre das auf dem Hetzner-Server gelandet, wo auf Coolify der Worker sitzt, der die Sendung nachts produziert. Jeder Hörer hätte dort Traffic verursacht. Bei 128 kbit/s sind das 57,6 Megabyte pro Hörerstunde. Tausend Hörerstunden ergeben also rund 57,6 Gigabyte, und die Zahl wächst mit jedem, der einschaltet. Genau das, was man sich bei einem wachsenden Sender eigentlich wünscht, wird dann zum Kostenrisiko.
Deshalb gilt bei mir eine einfache Regel: Hörer-Traffic läuft nie über Hetzner. Hetzner produziert, Mittwald liefert aus. Beide sind deutsche Anbieter, die Kette bleibt damit bei EU-Hostern. Für ein Projekt unter meinem Namen ist das keine Kür.
Wie funktioniert ein HLS-Stream ohne laufenden Server?
Das ist der Punkt, an dem es interessant wird. HLS braucht keinen laufenden Prozess. Ein HLS-Stream ist im Kern nichts anderes als ein Stapel kurzer Audiodateien plus eine Playlist, die sagt, welche davon gerade dran sind.
Mein Worker zerlegt jede Tondatei der Sendung per ffmpeg -c:a copy in MPEG-TS-Stücke von rund zehn Sekunden. Das copy heißt: kein neues Encoding, also kein Qualitätsverlust und kaum Rechenzeit. Die Stücke landen unter einem Fingerabdruck ihres Inhalts, hochgeladen wird nur, was neu ist. Die Musik liegt also einmal am Server und wird nicht jede Nacht neu übertragen.
Auf Mittwald liegt dann ein kleines PHP-Skript, hls/live.php. Bei jeder Anfrage rechnet es dieselbe Position aus wie der Webplayer und gibt ein Fenster von sechs Stücken aus. Der Player in deinem Auto holt sich diese Liste alle paar Sekunden neu und findet so immer die nächsten zehn Sekunden. Für die App fühlt sich das wie ein Livestream an. In Wahrheit ist es eine Rechnung, die bei jedem Abruf neu gemacht wird.
Wer die m3u8-Adresse im Browser öffnet, sieht das sehr direkt: eine Liste von Stücken, jedes mit Uhrzeit und Titel, dazwischen Markierungen, wo ein Element endet und das nächste beginnt. Etwa ein Interview, danach die KI-Kennzeichnung, danach Musik.
Ein Detail, das mir wichtig war: Scheitert die HLS-Stufe im Nachtlauf, läuft die Sendung trotzdem. Der Stream ist ein Zusatz, keine neue Abhängigkeit.
Drei Fallen, die mich Zeit gekostet haben
Die erste Idee war, die MP3s gar nicht zu zerlegen, sondern per Byte-Range in Stücke zu adressieren. Klingt sparsam, läuft aber nur in der JavaScript-Bibliothek hls.js. Chrome und Apple lehnen das nativ ab. MPEG-TS dagegen läuft überall, auch am iPhone.
Die zweite Falle hat mit Chrome zu tun. Der Browser behauptet, HLS selbst abspielen zu können, liefert dann aber keine Uhrzeit pro Stück. Die brauche ich, weil meine Hörseite damit nachschaut, welcher Titel und welches Cover gerade laufen. Also nimmt die Seite zuerst hls.js und erst dann den eingebauten Player.
Die dritte war eine Apache-Eigenheit, die ich eigentlich hätte kennen müssen: Eine .htaccess im Unterordner ersetzt die Rewrite-Regeln der Hauptdatei, statt sie zu ergänzen. Der Schutz, der fehlende Dateien sauber mit 404 statt mit einem Serverfehler beantwortet, musste dort noch einmal hinein.
Getestet hab ich das alles in einem eigenen Testordner. Danach waren die Dateien des laufenden Senders byte-gleich mit vorher, der Testordner ist gelöscht. Wer tausend Hörer hat, experimentiert nicht am offenen Sender.
Wo findest du digitalhandwerk Radio jetzt?
Die Stream-Adresse lautet:
https://radio.digitalhandwerk.rocks/hls/live.m3u8
Unter radio.digitalhandwerk.rocks/hls/ gibt es dazu eine schlanke Hörseite mit Cover und Titel, dort steht die Adresse auch zum Kopieren.
Eingetragen ist der Sender bei radio-browser.info, der Online-Check dort ist bestanden. Und das ist der Hebel, der ihn in die Apps bringt. Die iOS-App Eter von Apparent Software greift auf genau diese Datenbank zu. Wenn du dort nach „digitalhandwerk“ suchst, findest du den Sender bereits. Eter läuft auf iPhone, Mac, Apple Watch und Apple TV, unterstützt CarPlay sowie Android Auto und gibt es auch als eigene Android-Version. Für das reine Hören reicht die Gratisversion. Ich find die App richtig gut, und nein, ich bekomm dafür nichts.
Daneben funktioniert jede App und jedes Gerät, das eine HLS-Adresse manuell annimmt. Einfach die URL oben eintragen.
Bei den anderen Verzeichnissen bin ich noch dran. radio.net nimmt nach meinem Stand nur MP3- oder AAC-Streams an, dort passt HLS nicht. Andere Verzeichnisse prüfe ich gerade, schauen wir mal, wer HLS sauber schluckt.
Was kann der Stream noch nicht?
Ehrlich gesagt ein paar Dinge. Titel und Cover pro Song zeigt nur meine eigene Hörseite, weil sie die Uhrzeit aus dem Stream liest und damit nachschlägt. Verzeichnisse und Apps zeigen das Senderlogo.
Beim nächtlichen Sendungswechsel beginnt die Nummerierung der Stücke neu. Wer genau in diesem Moment zuhört, puffert wahrscheinlich kurz nach. Ich bin mir nicht ganz sicher, wie viele das tatsächlich trifft, mein Eindruck ist aber, dass es eher wenige sind. Beobachten werd ich es trotzdem.
Und dann ist da noch die Kennzeichnung. Artikel 50 der EU-KI-Verordnung verlangt, dass KI-generierte Inhalte als solche erkennbar sind. Im Webplayer steht das in einem dauerhaft sichtbaren Feld. In Eter oder im Auto gibt es dieses Feld nicht. Hier zahlt sich eine Entscheidung aus, die ich vor Wochen getroffen hab: Die Kennzeichnung ist bei mir nicht nur Text, sondern gesprochen. Ein Jingle mindestens alle 15 Minuten, vor jedem Interview ein eigener Hinweis, dass beide Stimmen künstlich sind. Weil das im Ton steckt, fährt die Kennzeichnung automatisch mit ins Auto. Ein reiner Textvermerk wäre in dem Moment verloren gewesen, in dem der Ton die Webseite verlässt.
Das ist übrigens die Erkenntnis, die ich aus diesem Umbau am ehesten in meine Beratungsarbeit mitnehme: Kennzeichnung gehört ins Material selbst, nicht in die Verpackung. Verpackungen wechseln schneller, als man denkt.
Und jetzt?
Die 1000 waren ein schöner Anlass. Die Kritik war der bessere. Ohne den Hinweis, dass man mein Radio im Auto nicht hören kann, hätte ich den Stream wahrscheinlich noch Wochen vor mir hergeschoben, weil im Browser ja eh alles funktioniert hat.
Trag die Adresse in deine Radio-App ein, nimm digitalhandwerk Radio auf die nächste Fahrt mit und schreib mir, wo es hakt. Die letzte Kritik hat einen Stream hervorgebracht. Mal sehen, was die nächste bringt.
Und bitte nie vergessen: auch der Stream ist in Beta! Wenn ihr Fehler findet: Ihr wisst, wie ihr mich erreichen könnt.




