Hi,
ich bin - wegen einigen nervigen Problemen - erst jetzt bei den Playlisten-Ladeprozeduren meines neuen Players angekommen. Der alte Player konnte mit einigen Abwandlungen von M3U nicht umgehen. Das liegt aber auch daran, dass M3U nicht wirklich festgelegt ist. Es gibt das simple und das erweiterte Format, welches total einfach auseinanderzuhalten ist, ansonsten gibt es jedoch üble Unterschiede in den Playlisten. Kann mir jemand sagen, welche Dialkete es gibt und was ich zu beachten habe ? Denn in vielen Fällen wird einfach mal etwas weggelassen, zum Beispiel das #EXTINF:. Wenn man nun das #EXTINF: weglässt, stellt sich die Frage, ob dann jede zweite Zeile eine #EXTINF
hne-#EXTINF:-Zeile wäre, oder ob es dann noch Leerzeilen dazwischen geben darf. Wie könnte man überhaupt Exceptions usw. vermeiden oder falsches laden, weil was in der Datei nicht stimmt ? Der folgende Code funktioniert gar nicht mal schlecht, aber nur unvollständig. Abgesehen davon bleibt die Frage mit dem #EXTINF: noch offen. Hier eine Playlist (von Wikipedia kopiert, ich benutze selbst keine M3U-Playlisten):
Zitat:
#EXTM3U
#EXTINF:221,Queen - Bohemian Rhapsody
Titel 1.mp3
#EXTINF:473,Dire Straits - Walk Of Life
Pop\Meine Auswahl\Titel 2.mp3
#EXTINF:264,asd – Bolero
C:\Dokumente und Einstellungen\All Users\Dokumente\Eigene Musik\Titel irgendeinenummer.mp3
Queen - Bohemian Rhapsody und Dire Straits - Walk Of Life werden korrekt ausgelesen. Beim letzten ist es seltsam: Ich gebe einfach mal nach jedem Schleifendurchlauf eine Nachricht wie folgt aus: ShowMessage('||'+Arr[High(Arr)].Artist+'||'+Arr[High(Arr)].Titel+'||'+Arr[High(Arr)].Dauer+'||'); Überall kommt was, nur beim asd - Bolero erscheint eine komplett leere Nachricht. Habt ihr eine Idee warum ?
Hier der bisherige Code, ich denke er muss noch verbessert werden, hat aber schon einen halbwegs brauchbaren Ansatz:
Delphi-Quellcode:
for i := 1 to Pred(sl.Count) do // in der StringList befindet sich die rohe Datei.
begin
SetLength(Arr, Succ(Length(Arr))); // Arr ist ein Array of TTagInfo. Dort werden alle Tags reingespeichert.
p1 := Pos('#EXTINF:', sl[i]); // Die Position von #EXTINF: wird später noch gebraucht, daher speicher ich sie in p1.
if (sl[i] <> '') and (p1 < 1) then // Wenn kein #EXTINF: vorhanden ist, jedoch die Zeile nicht leer ist, gehe ich davon aus, dass es sich um die Zeile mit dem Dateinamen handelt.
begin
Arr[High(Arr)].Dateiname := sl[i]; // Dateiname in langer Form zuweisen.
Arr[High(Arr)].kDateiname := ExtractFileName(sl[i]); // Und noch in kurzer Form.
end else
begin
p2 := Pos(',', sl[i]); // Da später noch Position von , benötigt, speichere ich sie in p2.
p3 := Pos('-', sl[i]); // Da später noch Position von - benötigt, speichere ich sie in p3.
if (p1 > 0) and (p2 > p1) then // p1 muss vorhanden sein und das , (p2) muss sich hinter p1 befinden.
Arr[High(Arr)].Dauer := SecToOut(StrToInt(Copy(sl[i], p1+8, p2-(p1+8)))); // So lässt sich die Dauer bestimmen. Was die 8 betrifft, muss man einfach nachrechnen, es geht auf. SecOut konvertiert Sekunden in das [hh:mm:ss]-Format.
if p3 > p2 then // Der - (p3) muss hinter dem , (p2) sein.
begin
Arr[High(Arr)].Artist := Copy(sl[i], Succ(p2), Pred(p3)-Succ(p2)); // Copyrei.
Arr[High(Arr)].Titel := Copy(sl[i], Succ(p3), Length(sl[i])); // Hier ebenfalls.
end else
Arr[High(Arr)].Artist := Copy(sl[i], Succ(p2), Length(sl[i])); // Falls es kein - (p3) gibt, wird einfach alles hinter dem , (p2) in Artist geschrieben.
end;
end;
Das Array (Arr) wird später nochmal auseinandergenommen. Es wird bevor es in meine eigene Listbox kommt nochmal geschaut, ob Artist und Titel zugewiesen, ob Tags vorhanden usw. sind. Das sieht so aus:
Delphi-Quellcode:
lb.Clear;
lb.BeginUpdate;
for i := 0 to Pred(Length(Arr)) do
if (Trim(Arr[i].Artist) = '') and (Trim(Arr[i].Titel) = '') then // Da Artist und Titel nicht vorhanden, wird der Dateiname und die Dauer angegeben.
lb.Add(Arr[i].kDateiname + ' [' + Arr[i].Dauer + ']')
else
if (Trim(Arr[i].Artist) <> '') and (Trim(Arr[i].Titel) = '') then // Da der Titel nicht vorhanden ist, wurde alles ab dem , (p2) übernommen, Arr[i].Titel muss logischerweise nicht ausgegeben werden.
lb.Add(Arr[i].Artist + ' [' + Arr[i].Dauer + ']')
else // Wenn alles in Ordnung ist, wie gewöhnlich ausgeben.
lb.Add(Arr[i].Artist + ' - ' + Arr[i].Titel + ' [' + Arr[i].Dauer + ']');
lb.EndUpdate;
lb.Draw;