Dunkel - Do 17.08.06 22:59
Titel: freeDB & komprimierte Audiodateien - DiscID generieren
Hey Folks,
ich möchte hier mal zu einer Kriesensitzung bzw. einem Brainstorming zum Thema freeDB und deren DiscID aufrufen!
freeDB ist eine feine Sache, keine Frage! Das "auslesen" der DiscID von AudioCDs funktioniert (selbstprogrammiert und/oder mit entsprechenden Komponenten) wunderbar.
Das ist auch nicht mein Problem.
Wie im Topic schon geschrieben, möchte ich die DiscID von komprimierten Audiodateien (mp3, ogg, flac, usw.), welche auf der Festplatte liegen, erstellen.
(Selbstverfreilich liegen alle Audiodateien der CDs [in komprimierter Form] in einem eigenen Ordner vor)
Wie man die DiscID erstellt steht hier:
http://home.arcor.de/hirnstrom/freecddb/overview.html#fn_aktuell
Und so habe ich es umgesetzt: (bitte nicht den Programmierstill anmeckern! Das ist schnell gecodet, ohne auf die "Etikette" zu achten)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60:
| procedure TF_Main.B_CDIDClick(Sender: TObject); function Quersumme(i : integer): integer; var p: pchar; begin result := 0; p := Pchar(IntToStr(i)); while (p^ <> #0) do begin result := result + strtoint(p^); Inc(p); end; end; var AudioT: TADBAudioTag; TPlayer: TADBPlayer;
counter: integer;
GetTime: integer;
Tracks: integer; Time: integer; SQS: integer; _Time: real; CDID: string; begin AudioT:= TADBAudioTag.Create(Self); TPlayer:= TADBPlayer.Create(Self, 1);
Time:=0; _Time:= 2;
SQS:=0; for counter:=0 to Listview1.Items.Count-1 do begin TPlayer.ActivePlayer.Open(Listview1.Items.Item[counter].SubItems[2]);
GetTime:= TPlayer.ActivePlayer.Length_Seconds;
_Time:= _Time + GetTime;
Time:= Time + round(GetTime); SQS:= SQS +Quersumme(ceil(_Time)); end;
Tracks:= Listview1.Items.Count; SQS:= (SQS mod 255);
CDID:= IntToHex(SQS, 2)+IntToHex(Time, 4)+IntToHex(Tracks, 2); E_CDID.Text:= CDID;
AudioT.Free; TPlayer.Free; end; |
(zur Information: TADBAudioTag & TADBPlayer sind Klassen welche u.A. im Stande sind die Spiellänge der Audiodateien zurückzugeben [was in diesem Falle genutz wird]; TADBAudioTag gibt einen Fließkommawert [sehr genau, aber anscheinend nicht genau genug; oder zu genau?!?], TADBPlayer einen Integer-Wert [mit Round() gerundet] zurück. In der TListview werden alle im Verzeichnis vorhandenen Audiodateien [inklusive des Dateinamens] angezeigt)
Mein Problem ist nur, dass die DiscID nicht stimmt. Grund dafür ist die Spiellänge der Audiodateien, welche vor allem bei der Berechnung des Offset-Werts SEHR entscheidend ist.
So, jetzt seit IHR an der Reihe! ;)
Moderiert von
matze: Code- durch Delphi-Tags ersetzt
Dunkel - Mo 13.11.06 21:40
Hey Ho!
Ich erkläre hiermit die Kriesensitzung für Beendet!
Und da ich niemanden dumm sterben lassen möchte folgt auch mein Lösungsweg für das obengenannte Problem:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65:
| function CreateDiscID(Verzeichnis: string; Extensions: string = '.mp3'): string; function Quersumme(i : integer): integer; var p: PChar; begin Result := 0; p := PChar(IntToStr(i)); while (p^ <> #0) do begin Result := Result + StrToInt(p^); Inc(p); end; end; var AudioT: TADBAudioTagAlt; counter: integer; GetTime: integer; Tracks: integer; Time: integer; SQS: integer; Offset: integer; OffSetS: string; Quer: integer; CDID: string; Search: TSearchTool; SearchEXT: string; FileCount: integer; begin Result:= '';
Search:= TSearchTool.Create; Search.SetFilter(Extensions); Search.Recurse:= False; Search.SearchFiles(Verzeichnis);
if Search.FilesCount= 0 then Exit;
AudioT:= TADBAudioTagAlt.Create(Owner);
Offset:= 150; for counter:=0 to Search.FilesCount-1 do begin if AudioT.ReadTag(Search.Files[counter])then begin Quer:= Quer + Quersumme(Time); GetTime:= round(AudioT.AudioTag.Duration_Sec); Time:= Time + GetTime; OffsetS:= OffsetS+ IntToStr(Offset)+' '; Offset:= Time *75; Inc(FileCount); end; end;
if FileCount> 0 then begin Tracks:= FileCount; SQS:= (Quer mod 255); CDID:= IntToHex(SQS, 2)+IntToHex(Time, 4)+IntToHex(Tracks, 2); CDID:= LowerCase(CDID)+' '+IntToStr(Tracks)+' '+OffsetS+IntToStr(Time); Result:= CDID; end; AudioT.Free; Search.Free; end; |
Dieser Function wird einfach das Verzeichnis in dem die MP3-Dateien (oder welches Audio-Format auch immer) liegen übergeben. Danach wird das Verzeichnis nach Dateien mit der entsprechenden Extension durchsucht, GetTime muß dann in der Schleife nur noch mit der Spielzeit der Datei in Sekunden gefüttert werden (das macht die Klasse TADBAudioTagAlt), et voila: die DiscID wird generiert und von der Function zurückgegeben.
Vielleicht hat ja irgendwer das gleiche Problem und freut sich über den (ich geb's ja zu, zusammengefrikelten) Code.