Pergunta

Eu gostaria de ter uma lista de reprodução para meu próprio tocador de música em Delphi / Pascal.

Eu pensei que seria a melhor solução ter uma lista de tstring com o caminho do arquivo MP3 e - adicionalmente - um TlistBox com os nomes das músicas. As cordas correspondentes nas duas listas devem estar na mesma posição. Portanto, se o usuário escolher o item 5 no TlistBox, eu poderá seguir o caminho na posição 5 na lista TString.

Isso funciona bem.

Mas agora eu preciso de uma lista de reprodução com duas colunas: "Artist" e "Song Title". Você deve ser capaz de classificar a lista de reprodução do artista (ascendente e descendente), bem como pelo título da música (ascendente e descendente) - alfabeticamente, é claro.

Como eu poderia fazer isso? Tendo dois objetos da tstringlist - um classificado por artista e um classificado pelo título da música?

Foi útil?

Solução

Eu fiz algumas dessas "listas" ao longo do tempo e, no final, sempre achei facilitadas as aulas, mas armazenando e principalmente a leitura das listas do disco provou "desafiador" para dizer o mínimo.

O desafio foi nos casos onde os usuários realmente manipulam as listas com editores externos, tornando a leitura da lista propensa a erros.

Para um formato de lista de reprodução universalmente aceito (M3U), dê uma olhada http://schworak.com/programming/music/playlist_m3u.asp.

Um componente VCL com fonte que lê vários formatos está disponível na Torry, chamada "Playlist v.0.5.1". http://www.torry.net/quicksearchd.php?string=playList+v.0.5.1&title=yes

Outras dicas

Eu faria uma classe Tsong contendo pelo menos as propriedades do artista e do título, e uma tsonglist fornecendo 1 ou mais métodos de classificação (pode ser genérico) usando o campo de classificação adequado (s.
Certamente não mantendo 2 listas de strings separadas que você precisa gerenciar, mantenha -se sincronizado e remodelando ao classificar ...

Uma maneira barata de implementar isso pode ser ter um conjunto de dados na memória com um registro contendo artista e caminho exibido em uma grade que você pode classificar em diferentes colunas.
A linha atual fornecerá as duas informações diretamente.

Uma solução simples seria implementar sua lista de músicas/informações de músicas como uma tcollection.

Usando coleções, você pode deixar o VCL lidar com o carregamento e a economia no disco.

Por exemplo:

Observe que isso não está funcionalmente completo, deixarei isso para você e, desde que escrevi isso do topo da minha cabeça, eu poderia ter bagunçado algo. É apenas um exemplo para você começar.

{...}
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;

Se você não deseja criar uma estrutura global de objetos, pode sempre usar a estrutura do TLISTView no modo de relatório. Você tem uma lista, com subitems. Você pode classificar por coluna e salvar no CSV ou qualquer formato. você pode facilmente adicionar ícones etc .....

E você tem os eventos certos para acionar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top