AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Mp3FileUtils
Thema durchsuchen
Ansicht
Themen-Optionen

Mp3FileUtils

Ein Thema von Gausi · begonnen am 15. Jun 2006 · letzter Beitrag vom 22. Jun 2013
Antwort Antwort
MW97

Registriert seit: 20. Nov 2010
Ort: Sachsen-Anhalt, Region Magdeburg
13 Beiträge
 
Delphi 7 Personal
 
#1

AW: Mp3FileUtils

  Alt 13. Aug 2011, 20:04
Hier ist mein Code:

Delphi-Quellcode:
  //Typendeklaration für Bibliothek
  type
    TLibrary=record
      Files :TStringList;//Damit ordne ich den Titelinfos die pfade zu
      Cols:Array[1..3] of TStringList;//Col[1] für Titel, Col[2] für Interpret, Col[3] für Spiellänge
      //...
  end;
  
  type
    TMainConfig=record
      Lib:TLibrary;
      //...
  end;
  
  //Typendeklaration für Titelinformationen
  type
    TAudioInf=record;
      Interpret: string;
      Titel : string;
      Pfad : string;
      Album : string;
      Jahr : string;
      Dauer : integer;
  end;

  //Unit mit Prozeduren zum Auslesen der Infos (aus dem Delphitreff)
  unit UAudioInf;

  interface

  uses
   UTypes;

  procedure GetAudioInfo(FileName: string);
  procedure GetMp3Info;
  procedure GetWmaInfo;
  procedure SetUnknown;
  function GetPlaylistTitel:string;

var
  AudioInf: TAudioInf;

implementation

uses
  SysUtils, Mp3FileUtils, ATL_WMAfile, Classes;


//Hauptprozedur für Titelinformationen
procedure GetAudioInfo(FileName: string);
begin
  AudioInf.Pfad := filename;
  if (AnsiLowerCase(ExtractFileExt(FileName)) = '.mp3') then
    GetMp3Info
  else
    if AnsiLowerCase(ExtractFileExt(FileName)) = '.wmathen
      GetWMAInfo
    else
      SetUnknown;
  if AudioInf.Interpret='then AudioInf.Interpret:='Unbekannter Interpret';
  if AudioInf.Album=''     then AudioInf.Album:='Unbekanntes Album';
  if AudioInf.Jahr=''      then AudioInf.Jahr:='unbekanntes Jahr';
end;

//Prozedur für Titelinformationen von MP3-Dateien
procedure GetMp3Info;
var
  MpegInfo: TMpegInfo;
  ID3v2Tag: TID3V2Tag;
  ID3v1tag: TID3v1Tag;
  Stream: TFileStream;
begin

  // Daten mit MP3FileUtils auslesen
  Mpeginfo:=TMpegInfo.Create;
  ID3v2Tag:=TID3V2Tag.Create;
  ID3v1tag:=TID3v1Tag.Create;
  Stream := TFileStream.Create(AudioInf.Pfad, fmOpenRead or fmShareDenyWrite);
  try
  id3v1tag.ReadFromStream(Stream);
  Stream.Seek(0, sobeginning);
  Id3v2tag.ReadFromStream(Stream);
  if Not id3v2Tag.exists then
    Stream.Seek(0, sobeginning)
  else
    Stream.Seek(id3v2tag.size, soFromBeginning);
  Mpeginfo.LoadFromStream(Stream);
  Stream.free;
  //Daten übertragen
  if mpeginfo.FirstHeaderPosition >- 1 then
  begin
    if id3v2tag.artist <> 'then
      AudioInf.Interpret := id3v2tag.artist
    else
      AudioInf.Interpret := id3v1tag.artist;
    if id3v2tag.Album <> 'then
      AudioInf.Album :=id3v2tag.Album
    else
      AudioInf.Album:=id3v1tag.Album;
    if id3v2tag.Year<> 'then
      AudioInf.Jahr:=id3v2tag.Year
    else
      AudioInf.Jahr:=id3v1tag.Year;
    if id3v2tag.title <> 'then
      AudioInf.Titel := id3v2tag.title
    else
      if id3v1tag.title <> 'then
        AudioInf.Titel := id3v1tag.title
      else
        AudioInf.Titel := ExtractFileName(AudioInf.Pfad);
    AudioInf.Dauer := mpeginfo.dauer;
  end else
    SetUnknown;
  finally
  MpegInfo.Free;
  Id3v2Tag.Free;
  Id3v1Tag.Free;
  end;
end;

//Prozedur für Titelinformationen von WMA-Dateien
procedure GetWmaInfo;
var
  wmaFile: TWMAfile;
begin
  if Not FileExists(AudioInf.Pfad) then
  begin
    SetUnknown;
    exit;
  end;
  try
  wmaFile := TWMAFile.create;
  if wmaFile.ReadFromFile(AudioInf.Pfad) then
  begin
    if wmaFile.Title <> 'then
      AudioInf.Titel := wmaFile.Title
    else
      AudioInf.Titel := ExtractFilename(AudioInf.Pfad);
      AudioInf.Interpret := wmaFile.Artist;
      AudioInf.Dauer := Round(wmaFile.Duration);
      AudioInf.Album :=wmaFile.Album;
      AudioInf.Jahr :=wmaFile.Year;
  end else
    SetUnknown;
  finally
  wmaFile.Free;
  end;
end;

//Prozedur für Titelinformationen von unbekannten Dateien
procedure SetUnknown;
begin
  AudioInf.Titel := ExtractFileName(AudioInf.Pfad);
  AudioInf.Interpret := '';
  AudioInf.Dauer := 0;
end;

//Prozedur für Titelinformationen nach %Interpret%-%Titel%
function GetPlaylistTitel:string;
begin
  if Trim(AudioInf.Interpret)='then
    result := AudioInf.Titel
  else
    result := AudioInf.Interpret + ' - ' + AudioInf.Titel;
end;
in meiner haupunit habe ich dann unter private ein TMainConfig-Objekt deklariert(ProConfig). Beim Programmstart werden die StringListen erstelt uns aus Dateien geladen.

Bei dieser Prozedur steigt dann der Speicherbedarf enorm an:
Delphi-Quellcode:
//Titelinformationen aktualisieren
procedure TForm1.LibRefreshInf(const Visualize: boolean);
var
  i, a, b: integer;
  Edited: boolean;
begin
  Edited:=false;
  if Visualize then
  begin
    Application.CreateForm(TFrmMakeUp, FrmMakeUp);
    FrmMakeUp.Show;
    FrmMakeUp.ChangesDone:=false;
  end;
  if ProConfig.Lib.Files.Count>0 then
  begin
    if Visualize then
    begin
      FrmMakeUp.ProgressBar1.Max:=ProConfig.Lib.Files.Count;
      FrmMakeUp.ProgressBar1.Position:=0;
    end;
    a:=0;
    for i:=ProConfig.Lib.Files.Count-1 downto 0 do
    begin
      if Visualize then
      begin
        inc(a);
        FrmMakeUp.ProgressBar1.Position:=a;
        FrmMakeUp.MainFile:=ProConfig.Lib.Files[i];
      end
      else
        Application.ProcessMessages;
      if FileExists(ProConfig.Lib.Files[i]) then
      begin
                  GetAudioInfo(ProConfig.Lib.Files[i]);
          if AudioInf.Titel<>ProConfig.Lib.Cols[1][i] then
          begin
            Edited:=true;
            ProConfig.Lib.Cols[1][i]:=AudioInf.Titel;
          end;
          if AudioInf.Interpret<>ProConfig.Lib.Cols[2][i] then
          begin
            Edited:=true;
            ProConfig.Lib.Cols[2][i]:=AudioInf.Interpret;
          end;
          if MsToMinuteSecond(AudioInf.Dauer*1000)<>ProConfig.Lib.Cols[3][i] then //MsToMinuteSecond wandelt
          begin //Sekunden in Minute:Sekunde um
            Edited:=true;
            ProConfig.Lib.Cols[3][i]:=MsToMinuteSecond(AudioInf.Dauer*1000);
          end;
          end;
      if not FileExists(ProConfig.Lib.Files[i]) then
      begin
        ProConfig.Lib.Files.Delete(i);
        for b:=1 to 3 do
          ProConfig.Lib.Cols[b].Delete(i);
      end;
    end;
  end;
  if Visualize then
  begin
    FrmMakeUp.ChangesDone:=true;
    FrmMakeUp.Close;
  end;
end;
Wenn ich der Prozedur true übergebe zeigt sie mir eine kleine form, die den status anzeigt, aber auch wenn ich das ganze im hintergrund machen lasse (false übergeben) steigt der bedarf.

EDIT:Ich habe gerade einen sehr eigenartigen Effekt festgestellt: Wenn ich in der Bibliothek meines Player 224 Elemente habe(Count der Stringlisten=224, Bedarf beim Start~1,8MB) dann steigt der Bedarf der Anwendung beim ausführen der Prozedur LibRefreshInf nicht. Wenn es aber 1014 Titel sind(Bedraf bei Start ~2,5 MB), dann steigt auf auf 182 MB. ???

Geändert von MW97 (13. Aug 2011 um 20:51 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

AW: Mp3FileUtils

  Alt 13. Aug 2011, 22:29
Also ich würde als erste dem Code ein Refactoring unterwerfen. So, wie ich das sehen kann, scheint alles in der Unit des Formulares zu stecken. Dazu kommen anscheinend noch globale Variablen und globale Datenstrukturen, weil du da noch einfache Prozeduren und Funktionen hast, die nicht Methoden deiner Klasse sind. Ich würde das erst mal alles sauber in eine oder eventuell sogar mehrere Klassen kapseln und so die GUI von der Datenverarbeitung trennen. Das hilft später bei der Erweiterung, der Überarbeitung und auch jetzt beim Finden von Fehlern und Speicherlecks. Eventuell verschwindet er ja schon beim Refactoring, wenn du wieder mehr Übersicht über deinen Code hast. Weil das ist doch nicht alles oder wird nicht alles bleiben oder?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
MW97

Registriert seit: 20. Nov 2010
Ort: Sachsen-Anhalt, Region Magdeburg
13 Beiträge
 
Delphi 7 Personal
 
#3

AW: Mp3FileUtils

  Alt 14. Aug 2011, 11:34
Nein, das ist nicht alles. Die Prozeduren zum Auslesen der Infos habe ich in eine eigene Klasse gepckt. Sie waren schon vorher in einer eigenen Unit. Aber es hat nichts geändert.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.545 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Mp3FileUtils

  Alt 14. Aug 2011, 11:37
Wird Action im OnClose von FrmMakeUp auf caFree gestellt?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
MW97

Registriert seit: 20. Nov 2010
Ort: Sachsen-Anhalt, Region Magdeburg
13 Beiträge
 
Delphi 7 Personal
 
#5

AW: Mp3FileUtils

  Alt 16. Aug 2011, 14:01
Ja, das ist so. Und er zeigt mir die Form ja auch nur an, wenn ich der Prozedur true übergebe. Wenn ich false übergebe, steigt der Speicherbedarf auch.

Geändert von MW97 (16. Aug 2011 um 14:03 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.545 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Mp3FileUtils

  Alt 16. Aug 2011, 14:02
Wird noch an anderer Stelle dynamisch Speicher angefordert?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
MW97

Registriert seit: 20. Nov 2010
Ort: Sachsen-Anhalt, Region Magdeburg
13 Beiträge
 
Delphi 7 Personal
 
#7

AW: Mp3FileUtils

  Alt 16. Aug 2011, 14:09
Ich habe in dem Programm einige andere kleine Formen, aber ich erstelle alle mit Application.CreateForm und bei OnClose ist Action überall auf caFree. Den record TAudioInf habe ich in eine Klasse umgeschrieben und die Prozeduren GetAudioInfo... dareingepackt. Ich habe dann in der Prozedur ein TAudioInf deklariert, es erstellt und gebe es mit try...finally und Free wieder frei.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz