Lista de reproducción para el reproductor de música en Delphi / Lista de múltiples elementos de datos
Pregunta
Me gustaría tener una lista de reproducción para mi propio reproductor de música en Delphi / Pascal.
pensé que sería la mejor solución para tener un TStringList con la ruta del archivo de MP3 y - además - un TListBox con los nombres de las canciones. Las cadenas a juego en ambas listas deben estar en la misma posición. Por lo que si el usuario elige el tema 5 en TListBox que sólo puede tomar el camino en la posición 5 en el TStringList.
Esto funciona bien.
Pero ahora necesito una lista de reproducción con dos columnas: "artista" y "título de la canción". Usted debe ser capaz de ordenar la lista por el artista (ascendente y descendente), así como por el título de la canción (ascendente y descendente) -. Alfabéticamente, por supuesto
¿Cómo podría hacer esto? Tener dos objetos de TStringList -? Uno entre artista y uno ordenados por título de la canción
Solución
He hecho algunas de estas "listas" con el tiempo y al final siempre he encontrado que las clases más fácil, pero el almacenamiento y sobre todo la lectura de las listas de discos ha demostrado "un reto" para decir lo menos.
El reto ha sido en los casos fueron en realidad los usuarios manipulan las listas con editores externos, con lo que la lectura del error propensos listas.
En un formato de lista de reproducción universalmente aceptada (M3U) echar un vistazo a http: // schworak. com / programación / música / playlist_m3u.asp .
Un componente VCL con la fuente que lee múltiples formatos está disponible en el llamado "v.0.5.1 la Lista de Reproducción" de Torry. http://www.torry.net/quicksearchd. php? String = PlayList + v.0.5.1 y Título = Sí
Otros consejos
Me gustaría hacer una clase de Tsong que contiene, al menos, el artista y el título propiedades, y una TSongList proporcionar 1 o más métodos de clasificación (puede ser genérico) usando el tipo adecuado Field (s.
Desde luego, no se mantiene 2 stringlists separadas que hay que gestionar, mantener en sincronía y reorganizar al ordenar ...
Una forma barata de aplicar un poco de eso, podría ser tener un conjunto de datos en la memoria con un registro que contiene artista y la ruta que se muestra en una cuadrícula que puede ordenar en diferentes columnas.
La fila actual dará ambas informaciones directamente.
Una solución sencilla sería la implementación de la lista de canciones de información / canción como TCollection.
Mediante el uso de las colecciones puede dejar que el VCL manejar la carga y guardarlo en el disco.
Por ejemplo:
Tenga en cuenta que esto no es funcionalmente completo, voy a dejar que depende de ti, y que no escribo esto desde la parte superior de la cabeza que podría tener algo en mal estado. Es solo un ejemplo para que pueda empezar.
{...}
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;
Si no desea construir una estructura de objeto global, siempre puedes usar la estructura TListView en el modo de informe. Que tiene allí una lista, con subelementos. Se puede ordenar por la columna, y guardar en formato CSV o lo que sea. usted puede agregar fácilmente los iconos, etc .....
y usted tiene los acontecimientos derecho de ejecutar.