AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Mp3FileUtils

Mp3FileUtils

Ein Thema von Gausi · begonnen am 15. Jun 2006 · letzter Beitrag vom 22. Jun 2013
Antwort Antwort
Seite 4 von 5   « Erste     234 5   
SearchBot

Registriert seit: 27. Jun 2004
Ort: N-W vom Bodensee
328 Beiträge
 
Delphi 12 Athens
 
#1

Re: Mp3FileUtils

  Alt 8. Mai 2009, 16:53
Zitat von Satty67:
anpassen an Delphi5 (und wohl auch 3/4) geht, man muss halt etwas Handarbeit investieren.
Ja, hab ich gemacht; siehe DL oben, da sind die Units drin (v0.4) - ich musste einiges um diese beiden Dummys erweitern, aber dann hat es auf Anhieb geklappt!

@Gausi...
Ooouh - ich bin sooooo blöööd.
Ich habe zwar aus den Utils die Zeit für das Mp3 ermittelt und in einer Variablen abgelegt, aber in einer anderen Procedure nicht aus dieser Variable verwendet, sondern die Tracklength vom Mediaplayer - - und der hat es immer falsch erkannt (ist auch blöd, wenn ich meine Variable auch TrackLength nenne, wenn die vom Mediaplayer genauso heißt, ich Depp)!

Alle Aufregung umsonst - sorry sorry sorry sorry sorry sorry sorry sorry sorry sorry sorry sorry sorry sorry und nochmal sorry.
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
905 Beiträge
 
Delphi 12 Athens
 
#2

Re: Mp3FileUtils

  Alt 16. Aug 2009, 14:37
Der VBRI-Header ist zwar noch nicht drin, trotzdem der Hinweis auf eine neue Version.

Unter Delphi 2009 gab es Probleme mit dem ID3v1-Tag, der durch ein Char-AnsiChar-Dingens weder gelöscht noch überschrieben werden konnte. Beim Speichern wurde dadurch immer wieder ein neuer Tag (also 128 Bytes) an die Datei angehängt. Das hat die Datei zwar nicht beschädigt, was ihre Abspielbarkeit betrifft, ist aber dennoch äußerst unschön.
Being smart will count for nothing if you don't make the world better. You have to use your smarts to count for something, to serve life, not death.
  Mit Zitat antworten Zitat
Z4ppy

Registriert seit: 25. Apr 2008
269 Beiträge
 
Delphi 7 Enterprise
 
#3

AW: Mp3FileUtils

  Alt 16. Jan 2011, 02:07
Ich habe folgendes festgestellt:
Die Dauer, die TMpegInfo zurückgibt, stimmt mit der Angabe im Explorer überein, nicht aber mit der in Winamp und iTunes.
Die Angaben sind zum Teil ziemlich weit auseinander: bei Iron Maiden - Remember Tomorrow zeigen mir beispielsweise TMpegInfo und Explorer 5:48 an, bei Winamp und iTunes ist der Song nur 5:28 lang
Weisst du, woran das liegen könnte? Sind die Dateien eventuell fehlerhaft?

MfG Z4ppy

€dit: Interessant ist übrigens: über die SendMessage API von Winamp bekommt man wieder den höheren Wert, intern zeigt Winamp aber den niedrigeren an

Geändert von Z4ppy (16. Jan 2011 um 03:05 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
905 Beiträge
 
Delphi 12 Athens
 
#4

AW: Mp3FileUtils

  Alt 16. Jan 2011, 09:23
Es gibt immer wieder mal solche Fälle, wo meine Unit (oder auch mal andere Programme) falsche Werte liefern. Das kann unterschiedliche Ursachen haben: Eine wäre die falsche Erkennung von "variable Bitrate", z.B. durch defekte Xing-Header oder die VBRI-Header, die ich bisher nur in meiner lokalen Version erkennen kann.

Spontan würde ich hier auf einen sehr großen ID3v2-Tag tippen, aber da kann ich mich auch irren. Schick mir so eine Datei am besten mal per Mail, dann kann ich mir die mal genauer angucken.

Adresse ist mail<Ät>gausi<Punkt>de
Being smart will count for nothing if you don't make the world better. You have to use your smarts to count for something, to serve life, not death.
  Mit Zitat antworten Zitat
DelTurbo

Registriert seit: 12. Dez 2009
Ort: Eifel
1.245 Beiträge
 
Delphi 2007 Architect
 
#5

AW: Mp3FileUtils

  Alt 30. Jun 2011, 13:17
Hi,
leider habe ich ein Problem mit den Demos. Ich nutze Demo_ID3v2_Level2.exe um ein Bild anzuhängen. In der "orginal" Demo-Exe klappt es auch.

Bei dem Demo-Sourcecode der dabei ist, klappt es nicht. Es klappt nur wenn vorher schon ein Bild enthalten war. Möchte man ein mp3 um ein Bild erweitern, dann klappt es nur mit der "orginal" Demo_ID3v2_Level2.exe.

Wäre toll wenn mir einer helfen würde.

Danke im voraus

EDIT: Ich habe ein bissl getraced. GetPictureFrameIndex da kommt er mit -1 zurück weil kein Bild da ist. Er legt es dann aber nicht an. Sind die DemoSource andere als die exe-files??

Edit2:
Der fehler ist hier.
Delphi-Quellcode:
// ------------------------------------------
// set pictures
// ------------------------------------------
procedure TID3v2Tag.SetPicture(MimeTyp: AnsiString; PicType: Byte; Description: UnicodeString; stream: TStream);
var IDX: Integer;
    NewFrame: TID3v2Frame;
    idStr: AnsiString;
    oldMime: AnsiString;
    oldDescription: UnicodeString;
    oldType: Byte;
    oldStream: TMemoryStream;
begin
    idStr := GetFrameIDString(IDv2_PICTURE);
    IDX := GetPictureFrameIndex({PicType,} Description);
    if IDX <> -1 then
    begin
        if Stream = NIL then
          Frames.Delete(IDX)
        else
        begin
            if (Description = '*') or (MimeTyp = '*') or (Stream.size = 0) then
            begin
                oldStream := TMemoryStream.Create;
                (Frames[IDX] as TID3v2Frame).GetPicture(oldMime, oldType, oldDescription, oldStream);
                if (Description = '*') then
                  Description := oldDescription;
                if (MimeTyp = '*') then
                  MimeTyp := oldMime;
                if Stream.Size = 0 then
                  oldStream.SaveToStream(Stream);
                oldStream.Free;
            end;
            (Frames[IDX] as TID3v2Frame).SetPicture(MimeTyp, PicType, Description, Stream)
        end;

    end else
    begin
        if (Stream <> NIL) and (Stream.Size > 0)then
        begin
            NewFrame := TID3v2Frame.Create(idStr, TID3v2FrameVersions(FVersion.Major));
            NewFrame.AlwaysWriteUnicode := fAlwaysWriteUnicode;
            newFrame.CharCode := fCharCode;
            NewFrame.AutoCorrectCodepage := fAutoCorrectCodepage;
            Frames.Add(newFrame);
            if (Description = '*') then
                Description := '';
            if (MimeTyp = '*') then
                  MimeTyp := 'image/jpeg';
            newFrame.SetPicture(MimeTyp, PicType, Description, stream)
        end;
    end;
end;
Er merkt das kein Bild da ist, legt es an (NewFrame) und "schmeisst" es weg. Trotzdem frage ich mich warum es bei den demo-exe-files geht. Dürfte ja nicht...
Alle meine Rechtschreibfehler sind Urheberrechtlich geschützt!!

Geändert von DelTurbo (30. Jun 2011 um 14:47 Uhr)
  Mit Zitat antworten Zitat
DelTurbo

Registriert seit: 12. Dez 2009
Ort: Eifel
1.245 Beiträge
 
Delphi 2007 Architect
 
#6

AW: Mp3FileUtils

  Alt 30. Jun 2011, 16:30
Sorry, ich steh nun TOTAL aufm schlauch. Sobald er TID3v2Tag.SetPicture macht, speichert er garkeine infos. Kommentier ich diese eine zeile aus, nimmt er wenigtens die anderen einträge.

Nun bin ich total verwirrt...

UPS... Sorry für den "spam". Ich wollte eigentlich editieren..
Alle meine Rechtschreibfehler sind Urheberrechtlich geschützt!!
  Mit Zitat antworten Zitat
Benutzerbild von wicht
wicht

Registriert seit: 15. Jan 2006
Ort: Das schöne Enger nahe Bielefeld
809 Beiträge
 
Delphi XE Professional
 
#7

AW: Mp3FileUtils

  Alt 13. Aug 2011, 09:39
DeddyH könnte da gut recht haben, danach hört es sich an. Benutzt du evtl. FastMM mit den Einstellungen zum Debuggen auf aktiv? Solche Effekte bekomme ich damit nämlich zustande, auch wenn ich alles Freigebe. Hast du es mal mit ReportMemoryLeaksOnShutdown probiert? Damit würdest du eventuelle Leaks vermutlich schnell finden.
http://streamwriter.org

"I make hits. Not the public. I tell the DJ’s what to play. Understand?"
  Mit Zitat antworten Zitat
MW97

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

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
 
#9

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
 
#10

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
Antwort Antwort
Seite 4 von 5   « Erste     234 5   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 02:34 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz