fix(audio): Wiedergabe-MP3 als CBR ohne Xing-Tabelle -- Wortmarkierung war 28 s voraus
Die Markierung im Transkript stand auf einem Wort, gesprochen wurde eins vier Zeilen weiter oben (gemessen an #85: 24 s Vorlauf). Nicht die Ursache -- jeweils per Gegenprobe ausgeschlossen: die Wortzeiten (Ausschnitte bei 600/1240/3400 s einzeln transkribiert, enthalten exakt die Wörter der DB), MP3- vs WAV-Zeitachse (identisch), ffmpeg-Seek (trifft), ontimeupdate-Logik (korrekt). Ursache war der Sprung im Browser: in einer VBR-Datei gibt es keine feste Byte-pro-Sekunde-Regel, also nutzt er die Xing-Tabelle -- 100 Stützstellen, bei 63 Minuten ein 38-s-Raster. Er landet auf der Stützstelle davor, meldet über currentTime aber die angefragte Zeit. Nachgerechnet: Ziel 20:40 spielt ab 20:11,5 (-28,5 s). Fix: -b:a 64k -ar 48000 -ac 1 -write_xing 0 statt -qscale:a 3. Byte-Position proportional zur Zeit. Die Tabelle muss auch bei CBR weg, sie rastert auf 1/256 der Dateigröße (~15 s pro Stunde, Restfehler bis -6,4 s gemessen). Ohne sie rechnet der Decoder linear: Restfehler 0,02 s an neun Stichpunkten. lab/recode-cbr.sh schreibt den Altbestand einmalig um (Quelle WAV, sonst die MP3 selbst), lab/tocerr.py ist das Messwerkzeug dahinter. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3496b4a2df
commit
d9554c590c
@@ -75,6 +75,41 @@ stateDiagram-v2
|
||||
- **GUI-Anzeige „⏱ Analysezeit“:** `analysis_started_at`/`analysis_ms` in der DB; beim Polling auf
|
||||
`analysis_status` achten, NICHT auf `status` (sonst wirkt die Summary „leer“).
|
||||
|
||||
## Wiedergabe-MP3: konstante Bitrate, keine Xing-Tabelle
|
||||
|
||||
Die WAV ist die Arbeitskopie (Whisper, Diarization), die MP3 ist nur fürs Abspielen im Browser —
|
||||
`highpass=f=80` gegen Rumpeln, `loudnorm` für gleichmäßige Lautstärke. Beim Codec sind aber **zwei
|
||||
Einstellungen nicht verhandelbar**, sonst läuft die Wortmarkierung im Transkript aus dem Takt:
|
||||
|
||||
```
|
||||
-codec:a libmp3lame -b:a 64k -ar 48000 -ac 1 -write_xing 0
|
||||
```
|
||||
|
||||
**Kein VBR** (früher `-qscale:a 3`) und **keine Xing-Tabelle**. Der Grund liegt im Sprung, nicht in der
|
||||
Wiedergabe:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Klick auf 20:40<br/>audio.currentTime = 1240"] --> B{Wie findet der<br/>Browser das Byte?}
|
||||
B -->|"VBR: Xing-Tabelle<br/>100 Stützstellen ≈ 38 s Raster"| C["landet bei 20:11,5<br/>meldet aber 20:40"]
|
||||
B -->|"CBR ohne Tabelle:<br/>Byte = Zeit × Bitrate"| D["landet bei 20:40,0<br/>Fehler 0,02 s"]
|
||||
C --> E["Ton hinkt 28 s nach,<br/>Markierung läuft voraus"]
|
||||
D --> F["synchron"]
|
||||
```
|
||||
|
||||
Nachgemessen an #85 (63 min): ein Sprung auf 20:40 spielte in Wahrheit ab **20:11,5 (−28,5 s)** — genau
|
||||
das Bild, das der Nutzer meldete („markiert ist ein Wort vier Zeilen unter dem, was ich höre"). Die
|
||||
Wortzeitstempel selbst waren dabei korrekt; per Gegenprobe transkribierte Ausschnitte an t = 600/1240/3400 s
|
||||
enthielten exakt die Wörter, die die Datenbank dort führt.
|
||||
|
||||
Die Tabelle muss auch bei CBR weg: sie speichert Byte-Positionen in 1/256 der Dateigröße, was bei einer
|
||||
Stunde Audio rund 15 s Rundung sind (gemessen: bis −6,4 s Restfehler). Ohne sie rechnet der Decoder
|
||||
linear — bei konstanter Bitrate exakt.
|
||||
|
||||
64 kbit CBR entspricht praktisch der bisherigen Durchschnittsrate (68 kbit); #85 schrumpfte von 32,3 auf
|
||||
30,3 MB. Der Altbestand wurde einmalig mit `lab/recode-cbr.sh` umgeschrieben (Quelle: die WAV, wo noch
|
||||
vorhanden — sonst die MP3 selbst, dann ohne erneute Filter).
|
||||
|
||||
## API-Endpunkte (Auszug)
|
||||
|
||||
| Endpunkt | Zweck |
|
||||
|
||||
Reference in New Issue
Block a user