Playlist für Musik-Player in Delphi / Liste der mehrere Datenelemente
Frage
Ich mag eine Playlist für meinen eigenen Musik-Player in Delphi / Pascal hat.
Ich dachte, dass es die beste Lösung wäre, eine TStringList mit dem Pfad der MP3-Datei zu haben, und - zusätzlich - ein TListBox mit dem Song-Namen. Die passenden Strings in beiden Listen müssen an der gleichen Position sein. Also, wenn der Benutzer wählt, Punkt 5 in TListBox Ich kann einfach nehmen Sie den Weg an Position 5 in dem TStringList.
Das funktioniert gut.
Aber jetzt brauche ich eine Wiedergabeliste mit zwei Spalten: „Künstler“ und „Songtitel“. Sie sollten die Playlist sortieren nach Künstlern (auf- und absteigend) sowie durch Songtitel (aufsteigend und absteigend) in der Lage sein, -. Alphabetisch, natürlich
Wie kann ich das tun? Mit zwei Objekte von TStringList - eins nach dem Künstler sortiert und eins nach dem Songtitel sortiert
?Lösung
Ich habe ein paar dieser „Listen“ im Laufe der Zeit getan, und am Ende habe ich immer gefunden ziemlich einfach, die Klassen zu machen, aber die Speicherung und das Lesen vor allem die Listen von der Festplatte bewährt hat „herausfordernd“, gelinde gesagt.
Die Herausforderung hat in Fällen gewesen waren Benutzer tatsächlich die Listen mit externen Editoren bearbeiten, wodurch die Listen fehleranfällig zu lesen.
Für ein allgemein akzeptiertes Playlist-Format (M3U) hat einen Blick auf http: // schworak. com / Programmierung / Musik / playlist_m3u.asp .
Ein VCL-Komponente mit Quelle, die mehrere Formate liest, ist bei Torry des gerufenen „Playlist v.0.5.1“ zur Verfügung. http://www.torry.net/quicksearchd. php? String = Playlist + v.0.5.1 & Title = Yes
Andere Tipps
Ich würde eine tsong Klasse tun, das mindestens die Künstler und Titel-Eigenschaften und ein TSongList Bereitstellung 1 oder mehr Sortierverfahren (kann generisch sein) unter Verwendung der richtige Art Field (s.
Sicherlich nicht beibehalten 2 separate Stringlisten, dass Sie zu verwalten haben, halten synchron und Umbildung beim Sortieren ...
Eine billige Art und Weise zu irgendwie, dass zu implementieren, könnte ein mit einem Datensatz im Speicher DataSet zu haben, enthält Künstler und Pfad in einem Raster angezeigt, dass Sie sortieren auf verschiedene Spalten.
Die aktuelle Zeile wird beide Informationen geben direkt an.
Eine einfache Lösung wäre, um Ihre Songliste / Song-Informationen als TCollection zu implementieren.
Durch Sammlungen verwenden, können Sie die VCL den Laden behandeln lassen und Speicher auf der Festplatte.
Zum Beispiel:
Bitte beachten Sie dies nicht funktionell abgeschlossen ist, werde ich euch überlassen, und da ich dies aus der Spitze von meinem Kopf schrieb könnte ich messed etwas nach oben. Es ist nur ein Beispiel für den Einstieg.
{...}
interface
Type
TSongCollectionItem = class(TCollectionItem)
public
constructor create(Owner:TCollection); override;
procedure assign(source : TPersistent); override;
published
property FileName : String read fFileName Write fFileName;
property Artist : string read fArtist write fArtist;
property Title : string read fTitle write fTitle;
{...}
property Album : string read fAlbum write fAlbum;
end;
TSongCollection = class(TOwnedCollection)
private
function GetItem(Index: Integer): TSongCollectionItem;
procedure SetItem(Index: Integer; Value: TSongCollectionItem);
public
constructor Create(AOwner: TPersistent);
function Add: TSongCollectionItem;
property Songs[Index: Integer]: TSongCollectionItem read GetItem write SetItem; default;
end;
procedure SaveSongList(Songs : TSongCollection; FileName:string; Binary:boolean);
procedure LoadSongList(Songs : TSongCollection; FileName:string; Binary:boolean);
{...}
implementation
{...}
type
TSongComponent = class(TComponent)
published
property SongList : TSongCollection read fsonglist write SetSongList;
end;
procedure SaveSongList(Songs : TSongCollection; FileName:string; Binary:boolean);
var
wFile : TFileStream;
wConvert : TMemoryStream;
wSongList : TSongComponent;
begin
RegisterClass(TSongComponent);
Try
wConvert := TMemoryStream.Create;
wFile := TFileStream.Create(filename, fmcreate);
wSongList := TSongComponent.create(nil);
try
wSongList.SongList.Assign(Songs);
if not Binary then
begin
wConvert.WriteComponent(wSongList);
wConvert.Position := 0;
ObjectBinaryToText(wConvert, wFile);
end
else
wFile.WriteComponent(wSongList);
finally
wConvert.Free;
wFile.Free;
wSongList.free;
end;
finally
Unregisterclass(TSongComponent);
end;
end;
procedure LoadSongList(Songs : TSongCollection; FileName:string; Binary:boolean);
var
wFile : TFileStream;
wConvert : TMemoryStream;
wSongList : TSongComponent;
begin
RegisterClass(TSongComponent);
Try
wConvert := TMemoryStream.Create;
wFile := TFileStream.Create(filename, fmOpenRead);
try
if not Binary then
begin
ObjectTextToBinary(wFile, wConvert);
wConvert.Position := 0;
wSongList := TSongComponent(wConvert.ReadComponent(Nil));
end
else
wSongList := TSongComponent(wFile.ReadComponent(Nil));
if assigned(Songs) and assigned(wSongList) then
Songs.Assign(wSongList.Songs);
if assigned(wSongList) then
wSongList.free;
finally
wConvert.Free;
wFile.Free;
end;
finally
Unregisterclass(TSongComponent);
end;
end;
Wenn Sie eine globale Objektstruktur nicht bauen wollen, können Sie verwenden durchweg TListView Struktur im Berichtsmodus. Sie haben dort eine Liste mit Unterpunkten. Sie können Spalte sortieren und zu csv oder was auch immer Format speichern. Sie können ganz einfach hinzufügen, Symbole etc .....
und Sie haben die richtigen Ereignisse auslösen.