Delphi.int.ru — Портал программистов

Вход Регистрация | Забыли пароль?

События

Сегодня:
Вопросы0    Ответы0    Мини-форумы0


Последние:
Вопрос26.08, 21:10 / #6673
Ответ02.08, 00:42 / #6619
Новости30 апреля 2012


Сейчас онлайн:
На сайте — 17
На IRC-канале — 3

Ссылки

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

На самом деле, как это не кажется, прочитать ID3-теги из MP3-файла совсем не сложно и, более того, для этого не требуется никаких специальных компонентов. 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..146] 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',  
    '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..128] of 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 >= 0) AND (Genre <=146) then  
       LlbGenre.Caption := 'Genre: ' + Genres[Genre]  
      else  
       LlbGenre.Caption := 'N/A';  
    end;  
  end;  
end;

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

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

Статья добавлена: 17 февраля 2005

Следующая статья: Написание инсталлятора на Delphi »

Рейтинг статьи: 3.75 Голосов: 16 Ваша оценка:

Зарегистрируйтесь/авторизируйтесь,
чтобы оценивать статьи.


Статьи, похожие по тематике

 

Для вставки ссылки на данную статью на другом сайте используйте следующий HTML-код:

Ссылка для форумов (BBCode):

Быстрая вставка ссылки на статью в сообщениях на сайте:
{{a:1}} (буква a — латинская) — только адрес статьи (URL);
{{статья:1}} — полноценная HTML-ссылка на статью (текст ссылки — название статьи).

Поделитесь ссылкой в социальных сетях:


Комментарии читателей к данной статье

bugmenot
Репутация: +24

bugmenot (30 июня 2011, 23:38):

Цитата:

Статья тоже не нова

Это отнюдь не делает её "старой-доброй". Что и вылезло в соответствующем вопросе вчера.

Цитата:

посмотрите на её номер и на дату публикации

Не вижу ни даты [ре]публикации, ни ссылки на оригинального автора.

Цитата:

кто-то возьмётся написать про ID3v2, будет хорошо

нет никакого смысла, стандарт уже написан без нас - http://www.id3.org/
Ерёмин А.А.
Репутация: +40

Ерёмин А.А. (30 июня 2011, 22:11):

Цитата (bugmenot):

Теги ID3v1 устарели более 10 лет назад.

Статья тоже не нова, посмотрите на её номер и на дату публикации.

Если кто-то возьмётся написать про ID3v2, будет хорошо. Хотя эти вещи сейчас делаются проще — в том же JediVCL есть компоненты для этого.
bugmenot
Репутация: +24

bugmenot (30 июня 2011, 13:29):

Теги ID3v1 устарели более 10 лет назад.
firstvirus
Репутация: +1

firstvirus (10 мая 2011, 15:42):

Отличная функция, но одно НО. Не знаю о чем Вы думали при написании... Titel... Правильно будет Title. Но это мелочи. у меня переменная temp.TID3Tag; пришлось написать такое Label2.Caption:=Label1.Caption+'\'+temp.Artist+'\'+temp.Album;
Попробуйте посмотреть на значение Метки2 и Вы будете неожиданно удивлены! :) а по делу мне помог небольшой быдло код:
for i:=1 to 30 do
begin
buf:=copy(Titel,i,1);
if buf<>#0 then buf2:=buf2+buf else break;
end;

Оставлять комментарии к статьям могут только зарегистрированные пользователи.