Avatar billede elv Nybegynder
28. september 2000 - 22:16 Der er 11 kommentarer og
2 løsninger

ID3-tag

Jeg er ved at lave et program, der skal kunne kigge og ændre i ID3-tag\'ene i mp3-filer. Jeg ved, at det står i bunden af filerne, men jeg kan ikke få styr på, hvilket system, der ligger bag. Kan nogen hjælpe?
Avatar billede snowball Novice
28. september 2000 - 22:18 #1
Lytter lige med !

Snowball
Avatar billede elv Nybegynder
28. september 2000 - 22:22 #2
Jo flere vi er sammen...
Avatar billede lrj Nybegynder
28. september 2000 - 22:27 #3
Jeg kan anbefale følgende artikel:

http://www.delphi3000.com/article.asp?id=1292
Avatar billede lrj Nybegynder
28. september 2000 - 22:28 #4
Eller http://anso.virtualave.net/delphi_stuff.htm - nederst på siden er der kode/komponent...
Avatar billede snowball Novice
28. september 2000 - 22:41 #5
Kanon. Det virker jo helt fint. Har du også noget om hvordan man ændre tag\'et ???

Snowball
Avatar billede snowball Novice
28. september 2000 - 22:49 #6
Eller også skal vi lige finde en der vil oversætte programmet fra C++ til Delphi ;O)

Snowball

P.S. Jeg er klar med nogle point til den person der kommer med noget kode som kan ændre i tag\'ene !!!
Avatar billede lrj Nybegynder
28. september 2000 - 23:01 #7
Hvad med denne så?

http://www.codefield.com/merlinsforge/mDF.html#414

Har ikke testet den, men dækker vist lige nøjagtigt :)
Avatar billede snowball Novice
28. september 2000 - 23:12 #8
hhhmmm...den ser godt nok lidt langhåret ud, men jeg må lige prøve mig frem lidt senere ;)

Snowball
Avatar billede lrj Nybegynder
28. september 2000 - 23:33 #9
Ret nemt:

Du definerer denne type:
  ID3Struct = record
    Signature: array[0..2] of Char; { Should be: \"TAG\" }
    Title,
    Artist,
    Album    : array[0..29] of Char;
    Year    : array[0..3] of Char;
    Comment  : array[0..29] of Char;
    Genre    : Byte;
  end;

Så laver du en genreliste (som stort set ingen bruger):
  ID3Genre: array[0..126] 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\'
  );

ID3OffsetFromEnd = 128;

    function ReadID3Tag(sFileName: string):ID3Struct;
  var
    fMP3: file of Byte;
    Tag : ID3Struct;
  begin
    try
      (* sFileName - (string) The full file name with path.
      *)
      AssignFile(fMP3, sFileName);
      Reset(fMP3);
      try
        Seek(fMP3, FileSize(fMP3) - ID3OffsetFromEnd);
        BlockRead(fMP3, Tag, SizeOf(Tag));
      finally
      end;
    finally
      CloseFile(fMP3);
    end;
        (*
        if fMP3.Signature <> \'TAG\' then begin
      ...
      { Doesn\'t have an ID3 tag }
    end else begin
      ...
      { Do something with the tag }
    end;
        *)
        result = Tag;
  end;


  function WriteID3Tag(id3NewTag: ID3Struct; sFileName: string);
  var
    fMP3: file of Byte;
    Tag : ID3Struct;
  begin
    try
      AssignFile(fMP3, sFileName);
      Reset(fMP3);
      try
        Seek(fMP3, FileSize(fMP3) - ID3OffsetFromEnd);
        BlockRead(fMP3, Tag, SizeOf(Tag));
        if fMP3.Signature = \'TAG\' then
          { Replace old tag }
          Seek(fMP3, FileSize(fMP3) - ID3OffsetFromEnd)
        else
          (* Append tag to file because it doesn\'t exist.
          * Cannot use Append() function. It\'s only for text files.
          *)
          Seek(fMP3, FileSize(fMP3));
        BlockWrite(fMP3, id3NewTag, SizeOf(id3NewTag));
      finally
      end;
    finally
      CloseFile(fMP3);
    end;
  end;

For at skrive en tag udfylder du en variabel af typen ID3Struct, giver filnavnet som parameter og kalder WriteID3Tag.

For at læse ID3-tag bruger du ReadID3Tag med et filnavn som parameter. Så får du (vistnok) en id3struct som resultat. Er der ingen id3-tag må du jo passe lidt på :)   
Avatar billede borrisholt Novice
29. september 2000 - 08:56 #10
LRJ > Når man citerer folk er det det mest høflige at huske at angive hvem man har citeret. Anyway Jacob Dybala (http://www.codefield.com/merlinsforge/mDF.html#414), er nok lige glad ....

Anyway så virker koden som skrevet står ikke ! Der er tæt på at virke ja, men virker gør den altså ikke.

Den her version virker :

unit Unit2;

interface
{$I-}
type
  TID3Struct = record
    Signature : array[0..2] of Char; { Should be: \"TAG\" }
    Title,
    Artist,
    Album    : array[0..29] of Char;
    Year      : array[0..3]  of Char;
    Comment  : array[0..29] of Char;
    Genre    : Byte;
  end;

var
ID3Genre: array[0..125] 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\'
  );

  function ReadID3Tag(sFileName: string):TID3Struct;
  procedure WriteID3Tag(id3NewTag: TID3Struct; sFileName: string);

implementation

const
  ID3OffsetFromEnd = 128;

  function ReadID3Tag(sFileName: string):TID3Struct;
  var
    fMP3: file of Byte;
    Tag : TID3Struct;
  begin
    try
      (* sFileName - (string) The full file name with path.
      *)
      AssignFile(fMP3, sFileName);
      Reset(fMP3);
      try
        Seek(fMP3, FileSize(fMP3) - ID3OffsetFromEnd);
        BlockRead(fMP3, Tag, SizeOf(Tag));
      finally
      end;
    finally
      CloseFile(fMP3);
    end;
        (*
        if fMP3.Signature <> \'TAG\' then begin
      ...
      { Doesn\'t have an ID3 tag }
    end else begin
      ...
      { Do something with the tag }
    end;
        *)
        result := Tag;
  end;
(* WriteID3Tag() function
  **
  ** Copyright (c) 2000 Jacob Dybala (m3Rlin)
  ** Freeware.
  **
  ** Created : January 7 2000
  ** Modified: January 7 2000
  ** Please leave this copyright notice.
  **
  ** Bug fix by Jens Borrisholt October 2000
  *)


  procedure WriteID3Tag(id3NewTag: TID3Struct; sFileName: string);
  var
    fMP3: file of Byte;
    Tag : TID3Struct;
  begin
    try
      AssignFile(fMP3, sFileName);
      Reset(fMP3);
      try
        Seek(fMP3, FileSize(fMP3) - ID3OffsetFromEnd);
        BlockRead(fMP3, Tag, SizeOf(Tag));
        if TAG.Signature = \'TAG\' then
          { Replace old tag }
          Seek(fMP3, FileSize(fMP3) - ID3OffsetFromEnd)
        else
          (* Append tag to file because it doesn\'t exist.
          * Cannot use Append() function. It\'s only for text files.
          *)
          Seek(fMP3, FileSize(fMP3));
        BlockWrite(fMP3, id3NewTag, SizeOf(id3NewTag));
      finally
      end;
    finally
      CloseFile(fMP3);
    end;
  end;
end.


Hvis du så skal teste koden så prøv det her :

Tag en for og to knaper og skriv noget kode analogt med det her :

procedure TForm1.Button1Click(Sender: TObject);
var
  ID3Struct : TID3Struct;
begin
  with ID3Struct do
  begin
    Signature := \'TAG\';
    Title := \'Read My Sign\';
    Artist := \'Bell Book and Candle\';
    Year  := \'1999\';
    Genre  := 0;
  end;

  WriteID3Tag(ID3Struct,\'02. Read My Sign.MP3\');

end;

procedure TForm1.Button2Click(Sender: TObject);
var
  ID3Struct : TID3Struct;
begin
  ID3Struct := ReadID3Tag(\'02. Read My Sign.MP3\');
  Caption := ID3Struct.Artist;
end;

Og dermed har jeg afsløret min facination for den tyske pige gruppe ....

Jens Borrisholt
Avatar billede lrj Nybegynder
29. september 2000 - 18:27 #11
Borrisholt - rolig nu. Jeg havde skrevet adressen i et tidligere svar - han synes det var uoverskueligt at bruge den, så jeg pastede den, rettede den lidt og kommenterede den. Jeg mener selv at jeg har kilden med, men okay.
Avatar billede elv Nybegynder
30. september 2000 - 10:03 #12
I får 30pts hver, da jeg desværre ikke kan se, hvad der er mest rimeligt. Håber i ikke er utilfredse...
Avatar billede lrj Nybegynder
30. september 2000 - 10:47 #13
Fin fin :)
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