Forum: Mikrocontroller und Digitale Elektronik Wie in VBR MP3 sekundengenau springen?


von Mampf F. (mampf) Benutzerseite


Lesenswert?

Guten Abend,

es haben hier sicher schon einige MP3-Player selbst gebaut und kennen 
das Problem sicherlich.

Wie würde man z.B. eine 30Sekunden zurück-spring-Funktion 
implementieren?

Oder wie würde man eine Funktion implementieren, die zu einem genauen 
Zeitindex des MP3s springt?

Das beste, das mir bisher eingefallen ist, beim Abspielen eine Liste mit 
den Timestamps der Frames anzulegen. Dann wäre zurück springen kein 
Problem.

Aber vorspringen?

Oder würde man sich tatäschlich durch alle MP3-Frames hangeln ohne diese 
zu dekodieren und versuchen so die Timestamps zu ermitteln?

Ich verwende den Helix-MP3-Decoder.

*edit*: Beim googeln gefunden:

> The only way to reliably get this information is to actually decode
> the stream up to that point, which you probably don't want to do. This
> is why even professional players such as XMMS cannot reliably update
> the slider when you skip around.

Ja, das hab ich mir schon fast gedacht ... Das Internet ist voll mit 
Bug-Reports von (namhaften) Playern, die es nicht gebacken bekommen.

*edit2*: Ich glaub ich verwende zum zurückspringen eine Liste, die ich 
beim Abspielen anlege und beim vorwärtsspringen dekodier ich "einfach 
schneller" (=überspringe Samples in meinem Ringpuffer) ... Mal schauen, 
ob das von der Usability praktikabel ist.

Vielen Dank für Ideen!
Mampf

von c-hater (Gast)


Lesenswert?

Mampf F. schrieb:

> Aber vorspringen?
>
> Oder würde man sich tatäschlich durch alle MP3-Frames hangeln ohne diese
> zu dekodieren und versuchen so die Timestamps zu ermitteln?

Natürlich. Wenn man exakte Ergebnisse haben will, muss man exakt 
programmieren, was denn sonst?

Übrigens stehen in den MP3-Headern keine Zeitstempel drin. Die muss man 
anhand der Daten, die tatsächlich drinstehen selbst errechnen. Das ist 
der Nachteil der hochkompakten MP3-Header.

Der Vorteil ist: man muss pro Frame bloß vier Bytes lesen, um alles über 
das Frame zu erfahren.

von Hurra (Gast)


Lesenswert?

Mampf F. schrieb:
> Guten Abend,
>
> es haben hier sicher schon einige MP3-Player selbst gebaut und kennen
> das Problem sicherlich.
>
> Wie würde man z.B. eine 30Sekunden zurück-spring-Funktion
> implementieren?

MP3s sind ja in Frames aufgeteilt, jedes hat so 20ms. Eigentlich ist es 
nur eine Frage, wievile Frames man springen will.

Es gibt da mehrere Wege:

Variante1 (was ich getan habe):
Man nimmt an, die Bitrate wäre konstant. Sich dann im File 
herumzunavigieren ist einfach - aus Bitrate und Filegröße kann man die 
Laufzeit berechnen. Sekunden mal Bitrate kann man als Offset für den 
Filepointer nehmen.
Diese Variante ist simpel, und so habe ich es implementiert.
Sie funktioniert für MP3s mit konstanter Framerate exakt, und ist 
schnell.
Nachteil: Bei MP3s mit variabler Bitrate liefert das komische 
Ergebnisse.

Variante2:
man mappt das File, d.h. man nudelt es duch, sucht alle Frameheader und 
macht sich eine Liste.
Diese Variante ist exakt, braucht aber RAM und ist auf einem µC wenig 
lustig, denn der braucht schon einige Zeit, es ist eigentlich nötig, das 
File abzuspielen (um festzustellen, ob die Header "echt" sind). Ein µC 
kommt da schon in Schwitzen.

Variante3:
Man hangelt sich frameweise durch das File. Also Buffer laden, 
frameheader suchen. Wiederholen ohne Abspielen. Das solange machen, bis 
man die definierte Anzahl an Frames durchgenudelt hat.
Das ist auf einem µC lahm, und rückwärts kompliziert (man weiß ja nicht, 
wie lange das Frame WIRKLICH ist).

Mit Variante 1 kommt man recht weit. Leider sind Files mit vairabler 
Bitrate nicht selten, ich habe davon einiege (insbesondere youtube 
scheint das zu verwenden). Für den Hausgebrauch (Musikhören) bin ich 
damit bisher trotzdem ausgekommen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.