All pastes #427710 Raw Edit

Miscellany

public text v1 · immutable
·published 2007-04-06 23:19 UTC
rendered paste body
(*
  Rotina para acessar código ID3 de arquivos Mp3
  Fonte: http://delphi.about.com
  Eduardo Rolim(Vndmtrx) - Knal #DelphiX - [BrasNet]
  www.vindemiatrix.x-br.com
*)

unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, MPlayer, ComCtrls, ExtCtrls;

  type
    TForm1 = class(TForm)
    mp3player: TMediaPlayer;
    mp3List: TListBox;
    btnOpenFolder: TBitBtn;
    GroupBox1: TGroupBox;
    edTitle: TEdit;
    edArtist: TEdit;
    edAlbum: TEdit;
    edYear: TEdit;
    edGenre: TEdit;
    edComment: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    txtFolder: TStaticText;
    Progress: TProgressBar;
    ProgresTimer: TTimer;
    procedure btnOpenFolderClick(Sender: TObject);
    procedure mp3ListClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ProgresTimerTimer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  var
    Form1: TForm1;

  type
    TID3Rec = packed record
    Tag : array[0..2] of Char;
    Title,
    Artist,
    Comment,
    Album : array[0..29] of Char;
    Year : array[0..3] of Char;
    Genre : Byte;
  end;

  const
    MaxID3Genre=147;
    ID3Genre: array[0..MaxID3Genre] of string = (
    'Blues', 'Classic Rock', 'Country', 'Dance', 'Disco', 'Funk', 'Grunge', 'Hip-Hop', 'Jazz', 'Metal', 'New Age', 'Oldies', 'Other', 'Pop', 'R&B',
    'Rap', 'Reggae', 'Rock', 'Techno', 'Industrial', 'Alternative', 'Ska',  'Death Metal', 'Pranks', 'Soundtrack', 'Euro-Techno', 'Ambient',
    'Trip-Hop', 'Vocal', 'Jazz+Funk', 'Fusion', 'Trance', 'Classical',   'Instrumental', 'Acid', 'House', 'Game', 'Sound Clip', 'Gospel',
    'Noise', 'AlternRock', 'Bass', 'Soul', 'Punk', 'Space', 'Meditative',   'Instrumental Pop', 'Instrumental Rock', 'Ethnic', 'Gothic',
    'Darkwave', 'Techno-Industrial', 'Electronic', 'Pop-Folk',  'Eurodance', 'Dream', 'Southern Rock', 'Comedy', 'Cult', 'Gangsta',
    'Top 40', 'Christian Rap', 'Pop/Funk', 'Jungle', 'Native American',    'Cabaret', 'New Wave', 'Psychadelic', 'Rave', 'Showtunes', 'Trailer',
    'Lo-Fi', 'Tribal', 'Acid Punk', 'Acid Jazz', 'Polka', 'Retro',  'Musical', 'Rock & Roll', 'Hard Rock', 'Folk', 'Folk-Rock',
    'National Folk', 'Swing', 'Fast Fusion', 'Bebob', 'Latin', 'Revival',  'Celtic', 'Bluegrass', 'Avantgarde', 'Gothic Rock', 'Progressive Rock',
    'Psychedelic Rock', 'Symphonic Rock', 'Slow Rock', 'Big Band',  'Chorus', 'Easy Listening', 'Acoustic', 'Humour', 'Speech', 'Chanson',
    'Opera', 'Chamber Music', 'Sonata', 'Symphony', 'Booty Bass', 'Primus',  'Porn Groove', 'Satire', 'Slow Jam', 'Club', 'Tango', 'Samba',
    'Folklore', 'Ballad', 'Power Ballad', 'Rhythmic Soul', 'Freestyle', 'Duet', 'Punk Rock', 'Drum Solo', 'Acapella', 'Euro-House', 'Dance Hall',
    'Goa', 'Drum & Bass', 'Club-House', 'Hardcore', 'Terror', 'Indie',  'BritPop', 'Negerpunk', 'Polsk Punk', 'Beat', 'Christian Gangsta Rap',
    'Heavy Metal', 'Black Metal', 'Crossover', 'Contemporary Christian', 'Christian Rock', 'Merengue', 'Salsa', 'Trash Metal', 'Anime', 'Jpop',
    'Synthpop' 
  );

  implementation

  uses ShellAPI, ShlObj; // needed for the BrowseForFolder function

  {$R *.DFM}

  procedure FillID3TagInformation(mp3File:string; Title,Artist,Album,Year,Genre,Comment:TEdit);
  var //fMP3: file of Byte;
    ID3 : TID3Rec;
    fmp3: TFileStream;
  begin
    fmp3:=TFileStream.Create(mp3File, fmOpenRead);
  try
    fmp3.position:=fmp3.size-128;
    fmp3.Read(ID3,SizeOf(ID3));
  finally
    fmp3.free;
  end;

  { or the non Stream approach - as in ChangeID3Tag procedure
  try
    AssignFile(fMP3, mp3File);
    Reset(fMP3);
    try
      Seek(fMP3, FileSize(fMP3) - 128);
      BlockRead(fMP3, ID3, SizeOf(ID3));
    finally
    end;
  finally
    CloseFile(fMP3);
  end;
 }

  if ID3.Tag <> 'TAG' then begin
  Title.Text:='Wrong or no ID3 tag information';
  Artist.Text:='Wrong or no ID3 tag information';
  Album.Text:='Wrong or no ID3 tag information';
  Year.Text:='Wrong or no ID3 tag information';
  Genre.Text:='Wrong or no ID3 tag information';
  Comment.Text:='Wrong or no ID3 tag information';
  end else begin
  Title.Text:=ID3.Title;
  Artist.Text:=ID3.Artist;
  Album.Text:=ID3.Album;
  Year.Text:=ID3.Year;
  if ID3.Genre in [0..MaxID3Genre] then
  Genre.Text:=ID3Genre[ID3.Genre]
  else
    Genre.Text:=IntToStr(ID3.Genre);
  Comment.Text:=ID3.Comment
  end;
  end;

  procedure ChangeID3Tag(NewID3: TID3Rec; mp3FileName: string);
  var
    fMP3: file of Byte;
    OldID3 : TID3Rec;
  begin
  try
    AssignFile(fMP3, mp3FileName);
    Reset(fMP3);
    try
      Seek(fMP3, FileSize(fMP3) - 128);
      BlockRead(fMP3, OldID3, SizeOf(OldID3));
      if OldID3.Tag = 'TAG' then
        { Replace old tag }
        Seek(fMP3, FileSize(fMP3) - 128)
      else
      { Append tag to file because it doesn't exist }
        Seek(fMP3, FileSize(fMP3));
      BlockWrite(fMP3, NewID3, SizeOf(NewID3));
    finally
    end;
    finally
      CloseFile(fMP3);
    end;
  end;

  procedure FillMP3FileList(Folder: string; sl: TStrings);
  var Rec : TSearchRec;
  begin
    sl.Clear;
    if SysUtils.FindFirst(Folder + '*.mp3', faAnyFile, Rec) = 0 then
    try
      repeat
      sl.Add(Rec.Name);
      until SysUtils.FindNext(Rec) <> 0;
    finally
      SysUtils.FindClose(Rec);
    end;
  end;

  function BrowseDialog(const Title: string; const Flag: integer): string;
  var
    lpItemID : PItemIDList;
    BrowseInfo : TBrowseInfo;
    DisplayName : array[0..MAX_PATH] of char;
    TempPath : array[0..MAX_PATH] of char;
  begin
    Result:='';
    FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);
    with BrowseInfo do begin
      hwndOwner := Application.Handle;
      pszDisplayName := @DisplayName;
      lpszTitle := PChar(Title);
      ulFlags := Flag;
    end;
    lpItemID := SHBrowseForFolder(BrowseInfo);
    if lpItemId <> nil then begin
      SHGetPathFromIDList(lpItemID, TempPath);
      Result := IncludeTrailingBackslash(TempPath);
      GlobalFreePtr(lpItemID);
    end;
  end;

  procedure TForm1.btnOpenFolderClick(Sender: TObject);
  var mp3Folder : string;
  begin
    mp3Folder := BrowseDialog('Choose a folder with mp3 files', BIF_RETURNONLYFSDIRS);
    if mp3Folder = '' then Exit;
    txtFolder.Caption := mp3Folder;
    FillMP3FileList(mp3Folder, mp3List.Items);
  end;

  procedure TForm1.mp3ListClick(Sender: TObject);
  var mp3File: string;
  begin
    if mp3List.Items.Count=0 then exit;
    mp3File := Concat(txtFolder.Caption, mp3List.Items.Strings[mp3List.ItemIndex]);
    if not FileExists(mp3File) then begin
      ShowMessage('MP3 file '+#13#10+ mp3File +#13#10+'does not exist!');
      exit;
    end;
 
    FillID3TagInformation(mp3File, edTitle, edArtist, edAlbum, edYear, edGenre, edComment);
    Progress.Max:=0;
    mp3player.Close;
    mp3player.FileName:=mp3File;
    mp3player.Open;
    Progress.Max := mp3player.Length;
  end;

  procedure TForm1.FormCreate(Sender: TObject);
  begin
    txtFolder.Caption := ExtractFilePath(Application.ExeName);
    FillMP3FileList(txtFolder.Caption, mp3List.Items);
    Progress.Max:=0;
  end;

  procedure TForm1.ProgresTimerTimer(Sender: TObject);
  begin
    if Progress.Max<>0 then
    Progress.Position := mp3player.Position;
  end;
  end.