Engineering

So folgt der Text deiner Stimme

Satz-genaue Timestamps mit Deepgram Nova-2, Fuzzy Matching gegen den Originaltext und Live-Highlighting im Player. Ein Blick hinter die Technik.

9. März 2026 7 Min. Lesezeit

Das Ziel

Beim Zuhoeren den Faden verlieren – das kennt jeder. Man scrollt nebenbei, der Blick wandert, und ploetzlich weiss man nicht mehr, wo der Sprecher gerade ist. Die Loesung: Der aktive Absatz wird automatisch hervorgehoben, waehrend man zuhoert. Der Text folgt der Stimme.

So sieht das im Browser aus, wenn jemand einen OKAYPLAY-Artikel abspielt:

Live-Highlighting

Mulchen: Der stille Held im Market Garden

Mulchen klingt nicht spektakulaer. Kein fancy Werkzeug, keine Hightech-Loesung – einfach nur eine Schicht organisches Material auf dem Boden. Und doch war Mulch im FREILANDWERK einer unserer wichtigsten Verbuendeten.

Was Mulch wirklich leistet

Eine gute Mulchschicht aus Stroh, Grasschnitt oder gehaeckseltem Laub haelt die Feuchtigkeit im Boden, unterdrueckt Unkraut und fuettert die Bodenlebewesen. In heissen Sommern war der Unterschied zwischen gemulchten und offenen Beeten dramatisch.

Die richtige Schichtdicke

Wir haben mit 5 bis 10 Zentimetern gearbeitet …

Der bereits gelesene Absatz ist leicht ausgeblendet. Die aktive Stelle – Ueberschrift und Absatz – bekommt einen sanften gelben Hintergrund und einen Akzent-Strich links. Der Rest wartet. Kein Raten, kein Suchen. Einfach mitlaufen.

Zwei Systeme, ein Ergebnis

Im letzten Post haben wir beschrieben, wie OKAYPLAY Absatz-Timestamps waehrend der Aufnahme erzeugt – per Web Speech API direkt im Browser des Sprechers. Das funktioniert, hat aber eine Einschraenkung: Die Granularitaet ist absatzweise, und die Qualitaet haengt vom Browser ab.

Deshalb gibt es eine zweite Schicht: Deepgram Nova-2, ein Speech-to-Text-Modell, das die fertige Audiodatei serverseitig analysiert und praezise Wort-Timestamps zurueckliefert. Aus diesen Wort-Timestamps baut OKAYPLAY automatisch Satz-Timestamps – die Basis fuer das Highlighting im Player.

AUFNAHME
Web Speech API
Absatz-Timestamps
im Browser
UPLOAD
Deepgram Nova-2
Wort-Timestamps
serverseitig
MATCHING
Fuzzy Alignment
Worte → Absaetze
per Overlap
PLAYER
Live-Highlighting
CSS-Klassen
per currentTime

Deepgram: Von Audio zu Wort-Timestamps

Sobald ein Sprecher seine Aufnahme hochlaedt, wird die Audiodatei asynchron an die Deepgram-API geschickt. Das Modell: Nova-2, optimiert fuer deutsche Sprache. Zurueck kommen einzelne Woerter mit Start- und Endzeit – auf Hundertstelsekunden genau.

// Deepgram-Antwort (vereinfacht) { "transcript": "Mulchen klingt nicht spektakulaer...", "confidence": 0.99, "words": [ { "word": "mulchen", "start": 1.20, "end": 1.68 }, { "word": "klingt", "start": 1.76, "end": 2.14 }, { "word": "nicht", "start": 2.16, "end": 2.40 }, // ... hunderte weitere Woerter ] }

Jetzt kommt der entscheidende Schritt: Diese Wort-Liste muss den Absaetzen des Originalartikels zugeordnet werden. Denn Deepgram kennt den Artikeltext nicht – es liefert nur, was es hoert.

Fuzzy Matching: Gesprochenes trifft Geschriebenes

Die Zuordnung laeuft in drei Schritten: Pausen erkennen, Chunks bilden, Chunks den Absaetzen zuordnen.

Schritt 1: Natuerliche Pausen finden

Zwischen Absaetzen macht jeder Sprecher eine kurze Pause. Wenn der zeitliche Abstand zwischen zwei Woertern groesser als 0,8 Sekunden ist, wird an dieser Stelle ein neuer Chunk gestartet. So entstehen Audio-Segmente, die typischerweise einem gesprochenen Absatz entsprechen.

// Pause Detection for ($i = 1; $i < count($words); $i++) { $gap = $words[$i]['start'] - $words[$i-1]['end']; if ($gap >= 0.8) { // Neuer Chunk: Sprecher hat pausiert $chunks[] = [ 'start' => $words[$chunkStart]['start'], 'end' => $words[$i-1]['end'], ]; $chunkStart = $i; } }

Schritt 2: Wort-Overlap berechnen

Jeder Chunk wird gegen alle Artikelabsaetze verglichen. Die Woerter werden normalisiert – Kleinschreibung, Umlaute aufloesen, Satzzeichen entfernen – und dann per Set-Intersection abgeglichen. Der Absatz mit dem hoechsten Overlap gewinnt. Mindest-Schwelle: 20%.

Das klingt simpel, ist aber erstaunlich robust. Selbst wenn Deepgram einzelne Woerter falsch erkennt (was bei Fachbegriffen oder Eigennamen vorkommt), reichen die restlichen Woerter locker fuer eine eindeutige Zuordnung.

Schritt 3: Chunks zusammenfuehren

Mehrere Chunks, die demselben Absatz zugeordnet werden, werden zeitlich zusammengefuehrt. Das Ergebnis: Pro Absatz ein Zeitfenster mit Start- und Endzeit. Genau die Datenstruktur, die der Player braucht.

// Fertige Timestamps pro Absatz { "sentences": [ { "start": 1.20, "end": 3.70, "text": "Mulchen: Der stille Held..." }, { "start": 4.88, "end": 17.60, "text": "Mulchen klingt nicht..." }, { "start": 18.70, "end": 20.20, "text": "Was Mulch wirklich leistet" }, { "start": 21.34, "end": 42.97, "text": "Eine gute Mulchschicht..." }, { "start": 44.60, "end": 45.90, "text": "Die richtige Schichtdicke" }, // ... ], "confidence": 0.991 }

Im Player: Text folgt Audio

Wenn jemand auf Play drueckt, laedt der OKAYPLAY-Player die Timestamp-Daten per API. Dann passiert Folgendes:

Der Player sucht auf der Publisher-Seite nach Absaetzen und Ueberschriften (p, h1h4, li) und ordnet sie den Timestamp-Saetzen zu – wieder per Fuzzy Matching, diesmal direkt im Browser. Alle 200 Millisekunden vergleicht ein Intervall die aktuelle Abspielzeit mit den Timestamps und setzt die CSS-Klasse okp-reading auf den passenden Absatz.

// Player-Highlighting (vereinfacht) function _tsUpdate(currentTime) { for (var i = 0; i < sentences.length; i++) { if (currentTime >= sentences[i].start && currentTime < sentences[i].end) { // Alten Absatz ausblenden old.classList.remove('okp-reading'); // Neuen Absatz hervorheben paragraphMap[i].classList.add('okp-reading'); paragraphMap[i].scrollIntoView({ behavior: 'smooth', block: 'center' }); } } }

Das Scrollen passiert sanft und nur wenn noetig – wenn der aktive Absatz ausserhalb des Viewports liegt. Der Uebergang zwischen Absaetzen wird per CSS-Transition animiert: Der gelbe Hintergrund blendet in 0,4 Sekunden ein und in 0,6 Sekunden wieder aus. Kein harter Sprung, sondern ein fliessender Wechsel.

Ein paar Zahlen

0,99
Confidence
7
Sentences
78s
Audio-Dauer

Das sind die Werte fuer den Mulchen-Artikel von FREILANDWERK – einen typischen Blogpost mit Titel, vier Absaetzen und zwei Zwischenueberschriften. Deepgram erkennt 99,1% der Woerter korrekt, das Matching ordnet alle sieben Abschnitte den richtigen Stellen im Text zu. Auch die Ueberschriften – obwohl sie nur wenige Woerter lang sind – werden sauber erkannt und getimestampt.

Warum nicht einfach Whisper?

OpenAIs Whisper ist eine starke Alternative. OKAYPLAY nutzt Deepgram aus einem pragmatischen Grund: Es laeuft auf Shared Hosting. Kein GPU-Server, kein Docker, kein Python-Stack. Deepgram ist eine API – Audio rein, JSON raus, fertig. Das passt zu einem Laravel-Projekt auf klassischem Webhosting.

KriteriumWhisper (Self-hosted)Deepgram Nova-2
InfrastrukturGPU-Server noetigAPI-Call
LatenzJe nach HardwareUnter 5 Sekunden
Deutsche SpracheGutSehr gut
Wort-TimestampsJaJa
Shared HostingNicht moeglichProblemlos

Qualitaetssicherung: Text Match Score

Als Nebenprodukt des Matchings entsteht ein Text Match Score: Wie viel Prozent des Artikeltexts hat der Sprecher tatsaechlich eingelesen? Der Score vergleicht das Deepgram-Transkript wortweise mit dem Originaltext – inklusive Levenshtein-Alignment fuer Reihenfolge und Overlap-Berechnung als Fallback.

Das ist gleichzeitig eine Qualitaetssicherung: Wenn ein Sprecher nur die Haelfte des Textes liest oder stark abweicht, faellt das auf. Nicht als Blocker, sondern als Signal.

Wo wir hinwollen

Das Highlighting funktioniert. Aber es gibt noch Raum nach oben.

Live
Absatz-Highlighting
Aktiver Absatz wird hervorgehoben, automatisches Scrollen zum aktuellen Abschnitt.
Live
Ueberschriften-Sync
Auch kurze Zwischenueberschriften werden erkannt und getimestampt.
Live
Satz-genaues Highlighting
Einzelne Saetze innerhalb eines Absatzes werden hervorgehoben – naeher an Spotify Lyrics.
Live
Klick-to-Seek
Auf einen Satz oder Absatz klicken und direkt an die richtige Stelle im Audio springen.
Live
Kapitel-Sprungmarken
Ueberschriften erscheinen als Marker auf der Fortschrittsleiste – ein Klick springt zum naechsten Abschnitt.
Live
Leseposition merken
Seite verlassen und spaeter genau dort weiterlesen, wo der Sprecher aufgehoert hat – bis zu 30 Tage lang.
Als Naechstes
Sprecher-Vorschau
Vor dem Abspielen eine kurze Stimmprobe hoeren – damit man weiss, wer gleich vorliest.

Alle TextSync-Funktionen sind jetzt live: Satz-Highlighting, Klick-to-Seek, Kapitel-Sprungmarken und Leseposition merken. Jede Funktion baut auf den Wort-Timestamps von Deepgram auf. Als Naechstes: Eine kurze Sprecher-Vorschau direkt am Play-Button, damit Zuhoerer die Stimme kennenlernen, bevor sie starten Alle drei Funktionen bauen auf den Wort-Timestamps von Deepgram auf. Als Naechstes: Leseposition dauerhaft merken, damit Zuhoerer auch nach Tagen genau dort weitermachen koennen, wo sie aufgehoert haben Beide Funktionen bauen auf den Wort-Timestamps von Deepgram auf. Als Naechstes: Kapitel-Sprungmarken, die Ueberschriften als visuelle Marker direkt auf der Player-Timeline anzeigen – die Wort-Timestamps von Deepgram sind praezise genug, um einzelne Saetze innerhalb eines Absatzes zu isolieren. Klick-to-Seek ist dann nur noch eine Lookup-Tabelle: Absatz-Index zu Audio-Sekunde.

Fazit

Zuhoeren macht mehr Spass, wenn man sieht, wo man ist. Text-Highlighting verwandelt passives Abspielen in ein Erlebnis, bei dem Lesen und Hoeren zusammenspielen.

Die Kombination aus Browser-seitigem Forced Alignment (waehrend der Aufnahme) und serverseitigem Deepgram-Matching (nach dem Upload) liefert das Beste aus beiden Welten: Echtzeit-Feedback fuer den Sprecher und praezise Timestamps fuer den Zuhoerer. Die Technik verschwindet im Hintergrund – was bleibt, ist der gelbe Balken, der durch den Text wandert.

Bereit fuer echte Stimmen?

Integration in 2 Minuten. Keine KI.

Jetzt Publisher werden
Oder: Als Sprecher Geld verdienen →