Avatar billede hasan Nybegynder
14. maj 2004 - 14:37 Der er 14 kommentarer og
2 løsninger

ID3 tags

hvordan for man id3 tags i en listbox så det også er muligt at afspille sangene?

jeg bruger en ID3 komponent til at ændre alle stierne i min listbox til artist og sang titlen, men nu kommer mit problem jeg kan ikke afspille sangene fordi min play funktion afpiller listbox1.item.itemindex og den indeholder ikke stien mere så den kan ikke finde stien til sangen. hvad skal jeg gøre? er der en måde jeg kan fixe dette på??
Avatar billede hrc Mester
14. maj 2004 - 16:24 #1
// Du laver en klasse der indeholder de oplysninger du behøver, her en sti

type
  TPath = class
  private
    fPath : string;
  public
    constructor Create(const aPath : string);
    property Text : string read fPath;
  end;

implementation

constructor TPath.Create(const aPath : string);
begin
  inherited Create;
  fPath := aPath;
end;

// Fylder et listview med testdata

procedure TForm1.Button2Click(Sender: TObject);
var
  i : integer;
  Path : TPath;
begin
  ListBox1.Clear;
  for i := 0 to 99 do begin
    Path := TPath.Create(IntToStr(random(30000))); // Fyld med testdata
    ListBox1.AddItem(IntToStr(i),Path);
  end;
end;

// Når man klikker på et element sker dette

procedure TForm1.ListBox1Click(Sender: TObject);
var
  Path : TPath;
begin
  Path := nil;
  with (Sender as TListBox) do
    if ItemIndex >= 0 then
      Path := TPath(Items.Objects[ItemIndex]);

  Edit1.Text := Path.Text;
end;

// Når man har oprettet 100 instanser af TPath så skal der ryddes op ved afslutning.

procedure TForm1.FormCreate(Sender: TObject);
var
  i : integer;
begin
  for i := 0 to ListBox1.Count - 1 do
    ListBox1.Items.Objects[i].Free;

  ListBox1.Clear;
end;
Avatar billede hrc Mester
14. maj 2004 - 16:28 #2
Nu snakker jeg om listviews - mente naturligvis ListBox. Har lavet en lille testapplikation der har en TListBox, TEdit og en TButton på formen.

Jeg opretter instanser af TPath og da hver linie i TListBox.Items har plads til at man kan hægte et objekt på, så hægter jeg det på der. Det vigtige er, at man rydder op bagefter og med en TListBox kan det bedst gøres i OnDestroy.

Hvis du bruger et TListView, så har de TListItems man opretter faktisk en Data-property hvor man kunne placere TPath. Meget bekvemt har et TListView nemlig en OnDeletion hvor man helt automatisk kan fjerne hvad der har været tilknyttet det listitem man sletter. Mit råd: Brug ovenstående løsning og skift til et TListView (i report-mode)
Avatar billede hasan Nybegynder
14. maj 2004 - 23:19 #3
kan ikke få det til at virke

type
  TPath = class
  private
    fPath : string;
  public
    constructor Create(const aPath : string);
    property Text : string read fPath;
  end;

implementation

constructor TPath.Create(const aPath : string);
begin
  inherited Create;
  fPath := aPath;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i : integer;
  Path : TPath;
begin
  ListBox1.Clear;
For I := 0 to Listbox1.Items.Count-1 do
    Path := TPath.Create('playlist.txt');
    ListBox1.AddItem(IntToStr(i),Path);
  end;
end;

procedure TForm1.ListBox1Click(Sender: TObject);
var
  Path : TPath;
begin
  Path := nil;
  with (Sender as TListBox) do
    if ItemIndex >= 0 then
      Path := TPath(Items.Objects[ItemIndex]);

  Edit1.Text := Path.Text; //hvad bruges den til?
end;


procedure TForm1.FormDestroy(Sender: TObject);
var
  i : integer;
begin
  for i := 0 to ListBox1.Count - 1 do
    ListBox1.Items.Objects[i].Free;

  ListBox1.Clear;
end;
Avatar billede hrc Mester
15. maj 2004 - 00:14 #4
Edit1.Text := Path.Text;

var bare for at illustrere hvordan man brugte de data som TPath indeholdt. Via Node har vi fundet pointeren (det hedder det ikke i objektorienteret regi, men det er altså hvad det er (kaldes en "instans" i stedet for)) til TPath-objektet og så kopierer jeg stieen over i en TEdit.

At jeg bruger propertynavnet Text for TPath er ikke et tilfælde. Vil gerne bruge samme navne som de der findes i Delphi.

Det er alt der er i programmet; det er kun et lille let eksempel som kræver, at du ved lidt om hvordan man arbejder med klasser og objekter.
Avatar billede hasan Nybegynder
15. maj 2004 - 10:54 #5
jeg ved intet om klasser og objekter. jeg kunne vel ikke få dig til at lave et eksempel til mig, hvor den loader en *.txt fil ind i path og når man så dubble kliker skal den spille stien til den item.
Avatar billede hrc Mester
15. maj 2004 - 22:59 #6
Nu bliver jeg lidt forvirret (naturligvis bare en grad mere end normalen). Du skriver om txt-filer i et katalog. Ovenfor snakker du om ID3-tags, underforstået at vi har med MPx filer at gøre.
Skal jeg ignorere det og køre videre med at du vil have et progam der scanner et katalog for *.txt filer, smider dem ind i en listbox (eller andet), og sender stieen til et eller andet, hvis man klikker på en linie?

Hvad mener du med at "spille stien til den item"? Hvilke "item"?

Jeg vil gerne lave et eksempel til dig - lyder ikke så svært at jeg er afskrækket, men kravsspecifikationen ;-) er ikke helt forstået.
Avatar billede hasan Nybegynder
16. maj 2004 - 11:24 #7
Min playlist er en *.txt fil som bliver loadet ind i en listbox. som du kan se er der en løkke der ændre alle stierne til mp3 filerne til id3 tagget. men da min mp3 player afspiller itemindex, og min listbox indeholder id3 tag istedet for stien så kan den ikke finde mp3 filen. håber du forstår hvad jeg mener.

procedure TForm1.FormCreate(Sender: TObject);
Var
  INI: TINIFile;
  LastPlayed : String;
  I : Integer;
begin
ini := Tinifile.create(extractfilepath(application.exename)+'settings.ini');

LastPlayed := INI.ReadString('settings', 'LastPlayed', 'Ikke fundet') + '.txt';

Listbox1.Items.LoadFromFile(LastPlayed);

  INI.Free;

For I := 0 to Listbox1.Items.Count-1 do
begin
id3.FileName := listbox1.Items.Strings[I]; //id3 er en komponet jeg bruger
id3.Active := true;
listbox1.Items.Strings[I] := id3.Artist + ' - ' + id3.Title;
id3.Active := false;
end;

end;

function TForm1.PlaySong : string;
var
mp3File : string;
begin

mp3File := listbox1.Items.Strings[listbox1.ItemIndex];
Progress.MaxValue := 0;
Mediaplayer1.close;
mediaplayer1.FileName := mp3File;
mediaplayer1.open;
mediaplayer1.play;
Progress.MaxValue := mediaplayer1.Length;
end;

procedure TForm1.ListBox1DblClick(Sender: TObject);
begin
playsong;
end;
Avatar billede hasan Nybegynder
17. maj 2004 - 16:31 #8
var det noget du kunne hjælpe mig med?
Avatar billede hrc Mester
17. maj 2004 - 17:24 #9
Jo da. Skal lige hjem fra arbejde først. Bliver en gang i aften.
Avatar billede hrc Mester
18. maj 2004 - 09:44 #10
Jeg har et program med en listbox (lbPlayList), en mediaplayer (mpPlayer) og en progressbar (pbStatus). Fandt en ID3 komponent som ikke helt ligner din, men det er tæt nok til at du sikkert kan tilrette det.

unit FMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, MPlayer, ComCtrls, ID3;

type
(*
  TMyID3 er en containerklasse der indeholder en TID3-komponent foruden den property
  vi mangler: FileName. Dens constructor og destructor sørger for at tingene oprettes
  og frigives korrekt. ID3-komponenten jeg fandt, har ingen Active-property. I
  stedet har den bare en ReadID3 procedure som man kalder med filnavnet.
*)
  TMyID3 = class
  private
    fFileName: string;
    fID3 : TID3;
  public
    constructor Create(const aFileName : string);
    destructor Destroy; override;
    property ID3 : TID3 read fID3;
    property FileName : string read fFileName;
    function AsString : string;
  end;

  TfrmMain = class(TForm)
    lbPlayList: TListBox;
    mpPlayer: TMediaPlayer;
    pbStatus: TProgressBar;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure lbPlayListDblClick(Sender: TObject);
  private
  public
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

uses
  IniFiles;

{ TMyID3 }

// Laver en "læsbar" præsentation af data
function TMyID3.AsString: string;
begin
  result := fID3.Artist + ' - ' + fID3.Title;
end;

// Opretter lokal fID3-komponent og indlæser data - antages at filen altid findes!
constructor TMyID3.Create(const aFileName: string);
begin
  inherited Create;
  fFileName := aFileName;
  fID3 := TID3.Create(nil);
  fID3.ReadID3(fFileName); // Indlæser data
end;

destructor TMyID3.Destroy;
begin
  try
    fID3.Free;
  finally
    inherited;
  end; // try
end;

{ TfrmMain }

procedure TfrmMain.FormCreate(Sender: TObject);
var
  i : Integer;
  MyID3 : TMyID3;
  LastPlayed : string;
  IniFileName : string;
  FileList : TStringList;
begin
  IniFileName := ExtractFilePath(Application.ExeName)+'Settings.ini';
  if not FileExists(IniFileName) then
    exit;

  with TIniFile.Create(IniFileName) do
    try
      LastPlayed := ReadString('SETTINGS', 'LastPlayed', 'na') + '.txt';
    finally
      Free;
    end; // try

  FileList := TStringList.Create;
  try
    FileList.LoadFromFile(LastPlayed);
    for i := 0 to FileList.Count - 1 do begin
      if not FileExists(FileList[i]) then
        Continue; // Skipper loop og prøver den næste

      // Opret data-objekt og indlæs data fra fil
      MyID3 := TMyID3.Create(FileList[i]);

      // Her oprettes elementet i listboxen og gemmer MyID3-objektet sammen med det
      lbPlayList.AddItem(MyID3.AsString, MyID3);
    end; // for
  finally
    FileList.Free;
  end; // try
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
var
  i : integer;
begin
  // Frigiver alle de oprettede MyID3 objektinstanser der ligger i listbox'en
  for i := 0 to lbPlayList.Count - 1 do
    TMyID3(lbPlayList.Items.Objects[i]).Free;
  lbPlayList.Clear;
end;

procedure TfrmMain.lbPlayListDblClick(Sender: TObject);
var
  // For læsbarhed af eksemplet, laves denne instans-pointer. Der oprettes intet
  // objekt, der peges kun på det som vi lavede i OnCreate
  MyID3 : TMyID3; // Instans-pointeren!
begin
  pbStatus.Min := 0;
  mpPlayer.Close;
  try
    // Henter det tilknyttede objekt frem igen
    with lbPlayList do
      MyID3 := TMyID3(Items.Objects[ItemIndex]);

    mpPlayer.FileName := MyID3.FileName;
  finally
    pbStatus.Max := mpPlayer.Length;
    mpPlayer.Open;
    mpPlayer.Play;
  end; // try
end;

end.

P.S. Ligesom der findes Objects[], så har TTreeViews TTreeNode og TListViews TLIstItem en .Data property hvorpå man også kan hægte objekter eller datastrukturer på.

P.P.S. Du er velkommen til at skrive email-adresse hvis du gerne vil have programmet tilsendt.
Avatar billede hasan Nybegynder
18. maj 2004 - 10:23 #11
vil prøve det når jeg kommer hjem

men du må gerne mail det til mig: w00t@ofir.dk
Avatar billede hasan Nybegynder
18. maj 2004 - 20:16 #12
den exe fil du sendte til mig virker ik' den ændre stien til id3 tagget, men når jeg dbl klikker så får jeg en no MCI device open eller cloce, men et eller anndet i den stil.

jeg kan ik finde rund i den kode, men det er bare fordi jeg er nybegynder. men hvis du gad give mig et eksemple på hvordan man loader en txt fil ind i tstringlist eller en object eller hvad det er, og derefter når man dbl klikker på min listbox så for man en messagebox med stien på den item du har klikket på. så burde jeg kunne få det sidte til at virke selv.
Avatar billede hrc Mester
18. maj 2004 - 21:58 #13
Ahem. Det er det jeg har:

procedure TfrmMain.FormCreate(Sender: TObject);
var
  i : Integer;
  MyID3 : TMyID3;
  LastPlayed : string;
  IniFileName : string;
  FileList : TStringList;
begin
  IniFileName := ExtractFilePath(Application.ExeName)+'Settings.ini';
  if not FileExists(IniFileName) then
    exit;

  // Læs hvilken fil vi vil have fat i
  with TIniFile.Create(IniFileName) do
    try
      LastPlayed := ReadString('SETTINGS', 'LastPlayed', 'na') + '.txt';
    finally
      Free;
    end; // try

  // Opret en streng-liste hvori vi gemmer txt-filen
  FileList := TStringList.Create;
  try
    FileList.LoadFromFile(LastPlayed);

    // Gennemløb listen og opret objekter løbende
    for i := 0 to FileList.Count - 1 do begin

      // Hvis ikke den findes, så skip og prøv den næste
      if not FileExists(FileList[i]) then
        Continue;

      // Opret data-objekt og indlæs data fra fil
      MyID3 := TMyID3.Create(FileList[i]);

      // Her oprettes elementet i listboxen og gemmer MyID3-objektet sammen med det
      lbPlayList.AddItem(MyID3.AsString, MyID3);
    end; // for
  finally
    FileList.Free;
  end; // try
end;

Øverst i listningen har jeg kreeret en TMyID3-klasse og det er den jeg banker ind sammen med listitem-elementet. Har tidligere haft store problemer med at sende exe-filer til andre - og ved ikke hvorfor - hvis det er tilfældet ved dig (tror mere det er en indstilling i mediaplayeren jeg ikke har fået sat), så må du prøve at oversætte programmet selv. Der er ikke mange fejlmuligheder med ovenstående kode.
Avatar billede hasan Nybegynder
21. maj 2004 - 13:52 #14
nu er jeg næsten færdig :)

playlist.txt bliver loadet ind i FileList, og jeg har sat det hele ind i functioner. og min id3 løkke og play function er også i en function (vær for sig).

så jeg har 3 functioner

load playlist ind i FileList
ID3 løkke
Play funktionen

min play function afspiller itemindex, men jeg vil gerne vide hvordan jeg kan exporter en Integer fra en function til an anden function


hvis du forstår havd jeg mener
Avatar billede hasan Nybegynder
21. maj 2004 - 14:01 #15
det er ikke en integer men en string, min fejl
Avatar billede hrc Mester
21. maj 2004 - 19:43 #16
Jeg er ikke helt med. Snakker vi om følgende:

function GetName : string;
begin
  result := 'Pelle Voigt';
end;

function GetPolitician : string;
begin
  result := GetName; // Henter værdien fra den anden funktion
end;

Det er ikke på det niveau, vel? Kan du ikke prøve at pensle det lidt mere ud?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester