Как прочитать ID3-Tag'и из MP3-файла при помощи Delphi?

Источник: delphi

На самом деле, как это не кажется, прочитать ID3-теги из MP3-файла при помощи Delphi совсем не сложно и, более того, для этого не требуется никаких специальных компонентов. TMediaPlayer здесь также бессилен. Все ID3-теги хранятся в последних 128-ми байтах MP3-файла. Часть из них записана не в том виде, в каком мы привыкли их читать в Winamp или в другом проигрывателе... Итак, перейдём сразу к коду...


  Byte 1-3 = ID 'TAG' 
  Byte 4-33 = Titel / Title 
  Byte 34-63 = Artist 
  Byte 64-93 = Album 
  Byte 94-97 = Jahr / Year 
  Byte 98-127 = Kommentar / Comment 
  Byte 128 = Genre 
}

Это - общая схема хранения информации в MP3-файле, которую мы будем читать. Вся эта информация отделяется от "музыкальной" части файла символами 'TAG' . После них и начинается служебная информация: название композиции, исполнитель, альбом, год исполнения, комментарий, жанр. Будет гораздо проще работать с ID3-тегами, объявив для них отдельный тип: 

type
 
  TID3Tag = record
 
    ID: string
[3]; 
    Titel: string
[30]; 
    Artist: string
[30]; 
    Album: string
[30]; 
    Year: string
[4]; 
    Comment: string
[30]; 
    Genre: Byte; 
  end

Итак, мы объявили тип TID3Tag и теперь можем его использовать. Как видно из кода, этот класс содержит несколько строковых полей, в каждом из которых и будет записан соответствующий ID3-тег.

Теперь следует поговорить о теге, отвечащем за жанр композиции. Дело в том, что в файле хранится лишь номер жанра, а не название самого жанра, поэтому получать его название придётся вручную. Сначала объявим массив, содержащий названия всех возможных жанров. Всего их 147:

const 
 Genres : array
[0..146of 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'
    'Alternative Rock'
,'Bass','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 US','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'
,'Rhytmic 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'
,'Heavy Metal','Black Metal','Crossover','Contemporary C'
    'Christian Rock'
,'Merengue','Salsa','Thrash Metal','Anime','JPop','SynthPop'); 

Наконец, процедура, читающая все теги из MP3-файла... Пропишем её в разделе implementation:


var
 
  Form1: TForm1; 

implementation
 

{$R *.dfm}
 

function
 readID3Tag(FileName: string): TID3Tag; 
var
 
  FS: TFileStream; 
  Buffer: array
 [1..128of Char; 
begin
 
  FS := TFileStream.Create(FileName, fmOpenRead or
 fmShareDenyWrite); 
  try
 
    FS.Seek(-128
, soFromEnd); 
    FS.Read
(Buffer, 128); 
    with
 Result do 
    begin
 
      ID := Copy(Buffer, 1
3); 
      Titel := Copy(Buffer, 4
30); 
      Artist := Copy(Buffer, 34
30); 
      Album := Copy(Buffer, 64
30); 
      Year := Copy(Buffer, 94
4); 
      Comment := Copy(Buffer, 98
30); 
      Genre := Ord(Buffer[128
]); 
    end

  finally
 
    FS.Free; 
  end

end

Данная функция возвратит нам всё содержимое ID3-тегов MP3-файла, указанного в FileName. Теперь дело за малым - написать обработчик открытия файла и чтения содержимого всех тегов из выбранного файла:

procedure
 TfrmMain.Button1Click(Sender: TObject); 
begin
 
  if
 OpenDialog1.Execute then 
  begin
 
    with
 readID3Tag(OpenDialog1.FileName) do 
    begin
 
      LlbID.Caption := 'ID: '
 + ID; 
      LlbTitel.Caption := 'Titel: '
 + Titel; 
      LlbArtist.Caption := 'Artist: '
 + Artist; 
      LlbAlbum.Caption := 'Album: '
 + Album; 
      LlbYear.Caption := 'Year: '
 + Year; 
      LlbComment.Caption := 'Comment: '
 + Comment; 
      if
 (Genre >= 0and (Genre <=146then 
       LlbGenre.Caption := 'Genre: '
 + Genres[Genre] 
      else
 
       LlbGenre.Caption := 'N/A'

    end

  end

end

Ну вот и всё... Добавьте соответствующие компоненты на форму и испробуйте работоспособность кода. В архиве с данной статьёй есть данная демо-программа.

Кроме ID3 тегов (полное имя которых звучит как ID3v1), существуют ID3v2-теги. Они содержат большее количество информации: все ID3v1 теги, а также информацию об авторских правах, настоящем исполнителе, адресе в интернете, композиторе и другой информации. Однако, эти теги не получили широкого распространения, поэтому они в данной статье не рассматриваются. Принцип их чтения тот же, что и у ID3v1 тегов.


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=22002