Entwickler-Ecke

Multimedia / Grafik - dynamische Playlisten für Musik Player


Jojo2004 - Fr 27.02.15 14:33
Titel: dynamische Playlisten für Musik Player
Hallo an alle,

erstmal muss ich zugeben das ich seit (aus Zeitgründen) rund 6 Jahren nichts mehr mit Delphi gemacht habe.
Zudem war ich gerade am Anfang und hatte noch nicht viel gelernt. Also bitte etwas Nachsicht mit mir.

Jetzt zum Thema.
Ich möchte gerne einen Musik Player von einem Bekannten weiter entwickeln. (Er kann mir leider nicht helfen)

Dort gibt es eine Musikliste (Class TMusicList) für sämtliche MP3 Dateien die aus einem Ordner ausgelesen werden.
Ebenfalls gibt es eine Playliste (Class TMusicList) aus der ich die MP3s dann öffne usw.

Diese Playliste möchte ich gerne zur Laufzeit erstellen und bearbeiten da ich oft mehr als nur eine Playliste benötige.
Wenn mehr als eine Playliste vorhanden ist sollen auch keine doppelten Titel eingefügt werden können egal in welcher der Titel sich befindet.

Ich dachte daran (da die Playliste auch angezeigt werden soll) mit PageControl zu arbeiten und in den Tabs eine Stringgrid zu erstellen wo die Daten dann rein kommen.
Evtl. mit playlist : array of TMusicList

Wie würdet Ihr denn vorgehen?

Hier noch etwas Infos


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
unit UnitMusicList;

type
   TMusicList = class
   private
         mlist : Tlist;
         filtered_list : TList;

usw.

unit UnitMain;

   private
         musiclist : TMusicList; //aus einem Ordner ausgelesene MP3s
         playlist  : TMusicList; //Liste von ausgewählte Titel die nach und nach gespielt werden sollen

procedure TFormMain.FormCreate(Sender: TObject);
begin
     . . . 
     musiclist := TMusicList.Create();
     . . .
     playlist := TMusicList.Create();


constructor TMusicList.Create();
begin
     . . .
     mlist := TList.Create;
     . . .

procedure TFormMain.FormDestroy(Sender: TObject);
begin
     playlist.Free;
     musiclist.clearList(true);
     musiclist.Destroy;
     . . .

destructor TMusicList.Destroy();
begin
     mlist.Free;
end;


Ich würde mich sehr über Tips, Vorschläge usw. freuen.

Vielen Dank

PS : arbeite mit Delphi 6 PE :oops:


Jojo2004 - Fr 27.02.15 18:05

ich glaube ich habe es.

Gibt es eine Möglichkeit aus einer procedure eine function mit Rückgabe true oder false aufzurufen?

Also ungefähr so

aus der procedure

rufe die function auf und wenn diese "true" zurück gibt mache irgendwas ansonsten was anderes.

Vielen Dank


WasWeißDennIch - Fr 27.02.15 18:05

Es wäre fair, wenn Du Crossposts [http://www.delphipraxis.net/184096-musik-player-mit-dynamischen-playlisten.html] künftig untereinander verlinken würdest.

Moderiert von user profile iconNarses: Beiträge zusammengefasst

user profile iconJojo2004 hat folgendes geschrieben Zum zitierten Posting springen:
Gibt es eine Möglichkeit aus einer procedure eine function mit Rückgabe true oder false aufzurufen?

Also ungefähr so

aus der procedure

rufe die function auf und wenn diese "true" zurück gibt mache irgendwas ansonsten was anderes.

Natürlich.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function BoolFunc: Boolean;
begin
  Result := ...;
end;

procedure MachWas;
begin
  if BoolFunc then
    TuDies
  else
    TuDas;
end;


Jojo2004 - Fr 27.02.15 18:08

Sorry, ich versuche es beim nächsten mal zu vermeiden oder daran zu denken.


Jojo2004 - Fr 27.02.15 22:02

Hallo WasWeißDennIch,

vielen Dank. Hat mir schon etwas weiter geholfen.

Da ich eine Array verwende habe ich noch eine for Schleife

Also


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
bo : boolean;


for i := 0 to (length(playlist)-1do
  if playlist[i].BoolFunc(mdata) then
    bo := true
  else
    bo := false;


Mein Ziel ist es den Musiktitel nur in die aktuelle Playlist zu schieben wenn dieser in keiner der gesamten Playlisten vorhanden ist.

Irgendwie habe ich aber einen großen Gedankenfehler darin.

Moderiert von user profile iconNarses: Beiträge zusammengefasst

OK hier mal mein Ergebnis

sollten dort Fehler sein wäre ich über eine Info sehr Dankbar.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
procedure TFormMain.SpeedButtonAddToPlaylistClick(Sender: TObject);
var
  i, y, k, x : integer;
  mdata : TMusicData;
  mr : TModalResult;
  bo : Boolean;
begin
  x := 0;
  . . . 

      for k := 0 to (length(playlist)-1do
        if playlist[k].checkaddMusicData(mdata) then
             x := x
           else
             x := x + 1;

        if (x = 0then // wenn in keiner der Playlisten der Musiktitel vorhanden
            playlist[TabControl1.TabIndex].addMusicData(mdata)  // bitte einfügen
        else
            begin
               if ((mr <> mrYesToAll) {and (mr <> mrNoToAll)}then
                    mr := MessageDlg(mdata.name + ' already in Playlist! Insert anyway?', mtConfirmation, [mbYes, mbNo], 0);      

               if ((mr = mrYes) ) then   // der Musiktitel soll trotzdem noch mal in die Playliste                             
                    playlist[TabControl1.TabIndex].addMusicData(mdata)
            end;

    end;
    refreshStringGridPlayList();
  end;
end;


hier die Prüfung

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function TMusicList.checkaddMusicData(mdata : TMusicData): boolean; 
begin
  Result := false;
  if (mlist.IndexOf(mdata) = -1then
      Result := true;
end;


Und hier das Einfügen in die aktuelle Playliste


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TMusicList.addMusicData(mdata : TMusicData);
begin
  if (mlist.IndexOf(mdata) = -1then
    mlist.Add(mdata)
end;


Danke nochmals für die Hilfe


WasWeißDennIch - Sa 28.02.15 09:57

Ich persönlich würde es ein wenig anders machen. Zunächst einmal tun die Funktionen nicht exakt das, was der Name aussagt, das solltest Du ändern, z.B.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function TMusicList.MusicDataAlreadyExists(mdata : TMusicData): boolean; 
begin
  Result := mlist.IndexOf(mdata) > -1;
end;

procedure TMusicList.addMusicData(mdata : TMusicData);
begin
  mlist.Add(mdata);
end;

Und diese komische x-Berechnung kann man auch ganz streichen und stattdessen lieber einen Boolean verwenden.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
procedure TFormMain.SpeedButtonAddToPlaylistClick(Sender: TObject);
var
  i, y, k : integer;
  mdata : TMusicData;
  mr : TModalResult;
  bo : Boolean;
  DataExists: Boolean;
begin
  . . . 
    DataExists := false;
    for k := Low(playlist) to High(playlist) do
      begin
        DataExists := playlist[k].MusicDataAlreadyExists(mdata);
        if DataExists then
          break;
      end;

      if not DataExists then // wenn in keiner der Playlisten der Musiktitel vorhanden
        playlist[TabControl1.TabIndex].addMusicData(mdata)  // bitte einfügen
      else
        begin
          //mr scheint etwas Globales zu sein, daher lasse ich das mal unangetastet
          if ((mr <> mrYesToAll) {and (mr <> mrNoToAll)}then
              mr := MessageDlg(mdata.name + ' already in Playlist! Insert anyway?', mtConfirmation, [mbYes, mbNo], 0);      
          
          if ((mr = mrYes) ) then   // der Musiktitel soll trotzdem noch mal in die Playliste                             
              playlist[TabControl1.TabIndex].addMusicData(mdata)
        end;
    end;
    refreshStringGridPlayList();
  end;
end;


Jojo2004 - Sa 28.02.15 17:42

Hallo WasWeißDennIch,

nochmals 1000 Dank. Die Tips haben mir sehr geholfen.
Da es im Moment noch ein Testprojekt ist hatte ich mir wegen Namensgebung für Funktionen, Objekten usw. noch keine Gedanken gemacht.

Hier mein Ergebnis womit bisher alles sehr gut funktioniert (auch mit Multiselect)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
procedure TFormMain.SpeedButtonAddToPlaylistClick(Sender: TObject);
var
  i, y, x : integer;
  mdata : TMusicData;
  mr : TModalResult;
  DataExist : Boolean;
begin
  if (musiclist.getItemCount > 0then
  begin
    mr := mrCancel;

    for i := StringGridInventory.Selection.Top to StringGridInventory.Selection.Bottom do
    begin
      mdata := musiclist.getMusicDataPK(StrToInt(StringGridInventory.Cells[ML_COL_PRIMARY, i]));

      x := 0;
      DataExist := false;
      for y := Low(playlist) to High(playlist) do 
        begin
          DataExist := playlist[y].MusicDataAlreadyExist(mdata);
          if DataExist then
             x := 1;
        end;
      case x of
      0: playlist[TabControl1.TabIndex].addMusicData(mdata);
      1begin
           if ((mr <> mrYesToAll) and (mr <> mrNoToAll)) then
                mr := MessageDlg(mdata.name + ' already in Playlist! Insert anyway?', mtConfirmation, [mbYes, mbNo, mbYesToAll, mbNoToAll], 0);      //

           if ((mr = mrYes) or (mr = mrYesToAll)) then
                playlist[TabControl1.TabIndex].addMusicData(mdata);
         end;
      end;  

    end
    refreshStringGridPlayList();
  end;
end;


Nochmals Danke.


Jojo2004 - Di 03.03.15 23:48

Nochmals vielen Dank an WasWeißDennIch.

Es funktioniert jetzt alles super.
Alle Funktionen sind intensiv getestet und haben bisher keine Probleme bereitet.