Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Spieldauer eines MP3s ermitteln? (https://www.delphipraxis.net/5080-spieldauer-eines-mp3s-ermitteln.html)

mjenke 23. Mai 2003 07:17


Spieldauer eines MP3s ermitteln?
 
Hallo, alle miteinander!

Weiss jemand, wie ich aus einer mp3-Datei die Spieldauer ermitteln kann? Inwieweit spielt die Bit-Rate dabei eine Rolle, und wie kann ich diese aus der Datei erfahren? Ich gehe mal davon aus, wenn ich die Bit-Rate kenne und die Dateigrösse habe, kann ich auch eine Spieldauer errechnen. Nur wie?

Wäre klasse, wenn mir jemand weiterhelfen könnte!

:?:
Matthias

Stanlay Hanks 23. Mai 2003 13:42

Das hab ich in nem anderen Forum mal gefunden...

Delphi-Quellcode:
Type
  TID3Tag = record
    ID: string[3];
    Titel: string[30];
    Artist: string[30];
    Album: string[30];
    Year: string[4];
    Comment: string[30];
    Genre: byte;
    dauer: longint; //in sekunden;
    sample: integer;
    bits: byte;
    vers: byte;
    layers: byte;
end;

const
  MPEG_BIT_RATES : array[1..3] of array[1..3] of array[0..15] of word =
  { Version 1, Layer I }
    (((0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0),
  { Version 1, Layer II }
    (0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,0),
  { Version 1, Layer III }
    (0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,0)),
  { Version 2, Layer I }
    ((0,32,48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0),
  { Version 2, Layer II }
    (0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0),
  { Version 2, Layer III }
    (0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0)),
  { Version 2.5, Layer I }
    ((0,32,48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0),
  { Version 2.5, Layer II }
    (0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0),
  { Version 2.5, Layer III }
    (0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0)));

  sample_rates: array[1..3] of array [0..3] of word=
    ((44100,48000,32000,0),
    (22050,24000,16000,0),
    (11025,12000,8000,0));



Es folgt die eigentliche „Auslese" Procedure:

var
  ID3Tag: TID3Tag;

procedure Lese_ID3Tag(Filename: string);
var
  Buffer: array[1..128] of char;
  F: File;
  mp3hdrread: array[1..4] of byte;
  mp3hdr: longint absolute mp3hdrread;
  tempbyte, bitrateindex, versionindex: byte;
  bitrate, version, layer, groese: longint;
begin
  AssignFile(F, Filename);

  Reset(F,1);
  groese:=filesize(f);
  blockread(f,mp3hdrread,4);
  tempbyte:=mp3hdrread[1];
  mp3hdrread[1]:=mp3hdrread[4];
  mp3hdrread[4]:=tempbyte;
  tempbyte:=mp3hdrread[2];
  mp3hdrread[2]:=mp3hdrread[3];
  mp3hdrread[3]:=tempbyte;

  reset(f,1);
  Seek(F,FileSize(F)-128);
  BlockRead(F, Buffer, SizeOf(Buffer));
  CloseFile(F);
  bitrateindex:=((mp3hdr shr 12) and $F);
  versionindex:=((mp3hdr shr 19) and $3);

  case versionindex of
    0: version:=3;
    1: version:=0; //unbekannt
    2: version:=2;
    3: version:=1;
  end;

  layer:=4-((mp3hdr shr 17) and $3);

  if version<>0 then
    bitrate:=MPEG_BIT_RATES[version][layer][bitrateindex]
  else
    bitrate:=128;

  with ID3Tag do
  begin
    ID:=copy(Buffer,1,3);
    Titel:=copy(Buffer,4,30);
    Artist:=copy(Buffer,34,30);
    Album:=copy(Buffer,64,30);
    Year:=copy(Buffer,94,4);
    Comment:=copy(Buffer,98,30);
    Genre:=ord(Buffer[128]);
    sample:=sample_rates[version][((mp3hdr shr 10) and $3)];
    dauer:=(groese*8) div ((bitrate)*1000);
    bits:=bitrate;
    vers:=version;
    layers:=layer;
  end;
end;


Die Procedure kann man dann folgendermaßen Anwenden:


procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    Lese_ID3Tag(OpenDialog1.FileName);

    Titel.Caption:=ID3Tag.Titel;
    Artist.Caption:=ID3Tag.Artist;
    Album.Caption:=ID3Tag.Album;
    Year.Caption:=ID3Tag.Year;
    Comment.Caption:=ID3Tag.Comment;
    Genre.Caption:=IntToStr(ID3Tag.Genre);

    Duration.Caption:=IntToStr(id3tag.dauer);
    Samplerate.Caption:=IntToStr(id3tag.sample);
    Bitrate.Caption:=IntToStr(id3tag.bits);
    Layer.caption:=IntToStr(id3tag.layers);
    Yersion.caption:=IntToStr(id3tag.vers);
  end;
end;
Damit kann man praktisch alles von ner mp3 auslesen

Sebastian Nintemann 23. Mai 2003 14:08

Hallo!
Zitat:

Zitat von Stanlay Hanks
Damit kann man praktisch alles von ner mp3 auslesen

Sofern die Mp3 nen id3_v1-Tag hat. Diese Tags werden aber (zurecht wie ich finde) immer weniger, da man zB. nur 30 Zeichen für Titel und Interpret hat. Die neueren Id3_v2 Tags sind dynamisch, die Zeichenzahl kann variieren. Leider bringt das allerdings auch mit sich, dass sie wesentlich schwerer zu lesen sind als id3_v1 Tags...

Gruß, Sebastian

Daniel B 23. Mai 2003 14:11

Hallo,

ich habe den Thread nach Multimedia verschoben. Die Sparte Programmieren allgemein ist nur für andere Programmiersprachen. Wenn Du nicht weisst wo es hin soll, dann benutze das nächste mal Sonstiges.

Grüsse, Daniel :hi:

Stanlay Hanks 23. Mai 2003 14:33

Hallo Grotesquery

Ich hab mich noch nicht mit diesem Theam befasst, ich hab, wie schon erwähnt, das obenstehende nur in einem anderen Forum mal gelesen und gespeichert. Hab also keine Ahnung, ob das funzt oder nicht. :hi: Stanlay

Sebastian Nintemann 23. Mai 2003 14:39

Hallo!

Was mir auch noch eingefallen ist: Man sollte vorsichtig sein beim berechnen der Zeit über bitrate, du solltest auch Dateien mit variabler Bitrate (VBR) berücksichtigen. Ich hab den Quellcode nicht ganz durchgesehen, aber das wird häufig übersehen.
Wenn dus dir einfach machen willst könntest du ja auch ne Komponente/Unit nehmen die dir die Arbeit mit den Tags und den Infos zu Spieldauer etc. abnimmt, bin sicher da lässt sich bei Torry was finden :wink:

Gruß, Sebastian

Stanlay Hanks 23. Mai 2003 14:54

Genau das hab ich vor ner Stunde gemacht, weil mir eingefallen is, dass ich sowas in mein neues Programm integrieren könnte....bei Torry gibtd die Teile massenhaft

tommie-lie 23. Mai 2003 15:12

Tags (egal welche Version) sind für diesen Zweck so ziemlich das ungeeignetste, was es gibt. Es kann sein, daß der entsprechende Tag nicht benutzt wird, oder daß die Daten, die in ihm stehen, schlichtweg falsch sind. Einige MP3-Player schreiben beim Rippen nämlich weder den Playcounter-Frame, noch den Length-Frame, bringen also gar nichts.
Die tatsächliche Länge steht wie immer in den Dateiheadern, und zwar in denen des MPEG2.5-Streams. Den muss man auslesen. Praktische Bibltiotheken dafür wären BASS und FMOD, die zudem das ganze auch noch abspielen können (auch MP2, diverse Mod-Formate, OggVorbis und alle anderen PCM-Verfahren). Wer mit dem TMediaPlayer abspielt, läuft Gefahr, daß die Musik auf einem anderen Rechner nicht ertönt.
Wenn man aus bitrate und Dateigröße die spiellänge berechnen will, muss man die beiden Tags (ID3v1 und ID3v2) und zusätzlich noch das Padding von ID3v2 beachten, ganz zu schweigen von den MPEG-Headern. Ist also alles andere als genau. Ich empfehle daher FMOD, da zusätzlich auch noch plattformunabhängig. Zu finden unter www.fmod.org

flomei 23. Mai 2003 15:17

Zitat:

Zitat von Stanlay Hanks
...bei Torry gibtd die Teile massenhaft

Bei der JEDI VCL ist auch ne Komponente bei mit der man ID3 Tags und all so was auslesen kann.

MfG Florian :hi:

flomei 23. Mai 2003 15:18

Zitat:

Zitat von tommie-lie
Wenn man aus bitrate und Dateigröße die spiellänge berechnen will, muss man die beiden Tags (ID3v1 und ID3v2) und zusätzlich noch das Padding von ID3v2 beachten, ganz zu schweigen von den MPEG-Headern. Ist also alles andere als genau.

Und vor allem nicht einfach! :D

MfG Florian :hi:

tommie-lie 23. Mai 2003 15:38

ich habe nie gesagt, daß es einfach ist, aber es ist so die einzige Möglichkeit, die Spiellänge einer MP3-Datei korrekt zu bestimmen. Ich habe noch nie eine MP3-Datei gesehen, die eine Längenangabe im ID3-Tag hatte, weil es einfach nicht üblich ist. Und wem das Einarbeiten in die ganzen MPEG-Geschichten zu kompliziert ist, für den gibt's ja besagte Bibliotheken. Für einen MP3-Player wären diese zwar zweckentfremdet, aber trotzdem allemal besser als der TMediaPlayer, nur so als Info.

Stanlay Hanks 23. Mai 2003 15:42

Ich persönlich verwende den TMediaPlayer eh nur so selten wie möglich bis gar nicht- aus Protest...aber dass so ein Teil zum Auslesen auch bei den Idys dabei is, hab ich auch noch nicht gewusst.

flomei 23. Mai 2003 15:45

Zitat:

Zitat von tommie-lie
Längenangabe im ID3-Tag

:shock: :duck: ???

Zitat:

Zitat von tommie-lie
ich habe nie gesagt, daß es einfach ist

Ich habe das nie verneint!

Zitat:

Zitat von tommie-lie
Für einen MP3-Player wären diese zwar zweckentfremdet, aber trotzdem allemal besser als der TMediaPlayer

:P :lol:

MfG Florian :hi:

Scorpion3000 23. Jun 2004 13:37

Re: Spieldauer eines MP3s ermitteln?
 
Sorry Leute, aber der Quelltext ist leider nicht ganz richtig. Du musst noch vorher die Header Position feststellen.

Muetze1 23. Jun 2004 13:47

Re: Spieldauer eines MP3s ermitteln?
 
Moin!

Zitat:

Zitat von Scorpion3000
Sorry Leute, aber der Quelltext ist leider nicht ganz richtig. Du musst noch vorher die Header Position feststellen.

Mal ganz abgesehen davon, das der Code gnadenlos fehlschlägt wenn ein ID3v2 Tag mit drinne ist.

Ich kann ansonsten noch ein kleines Testprog anbieten was ich mal geproggt hat, was von Frame zu Frame springt in einem MP3 und das auch bei variabler Bitrate...

Zitat:

Zitat von Tommie-lie
Die tatsächliche Länge steht wie immer in den Dateiheadern, und zwar in denen des MPEG2.5-Streams.

Kannst du dazu mal bitte nähere Info's geben, weil ich weiss nur von der FrameSize und keinen besonderen Header für 2.5'er, somit weiss ich nicht, wo das stehen sollte...

MfG
Muetze1

Kernel32.DLL 23. Jun 2004 14:59

Re: Spieldauer eines MP3s ermitteln?
 
Zitat:

Ich kann ansonsten noch ein kleines Testprog anbieten was ich mal geproggt hat, was von Frame zu Frame springt in einem MP3 und das auch bei variabler Bitrate...
Kannst das mal posten?

Muetze1 23. Jun 2004 15:36

Re: Spieldauer eines MP3s ermitteln?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Moin!

Klar, im Anhang. Es wird keine Überprüfung vorgenommen von wegen dem ID3v1.x Tag am Ende, so dass es zu falchen Frame Info's kommt am Ende von dem MP3 File. Es ging halt nur um die Frames abzulaufen...

/EDIT: Die Grösse und Position könntest du einfachst mit den Info's meiner ID3 Lib rausbekommen, die auch die Grösse der Reindaten für den geschätzten Spielzeitwert berechnet/ermittelt.

MfG
Muetze1


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz