(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Чтение ID3 тегов и другой информации из mp3 файлов средствами php

Все ID3 теги (ID3 tag) хранятся в последних 128-ми байтах mp3 файла. Это означает, что их можно читать без специальных компонентов. Распределение информации следующее: 

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

Для определения тегов достаточно отформатировать распаковку из бинарной строки в соответствии с выше приведенной последовательностью:

01$f fopen('test.mp3''rb');
02rewind($f);
03fseek($f, -128, SEEK_END);
04$tmp fread($f,128);
05if ($tmp[125] == Chr(0) and $tmp[126] != Chr(0)) {
06// ID3 v1.1
07$format 'a3TAG/a30NAME/a30ARTISTS/a30ALBUM/a4YEAR/a28COMMENT/x1/C1TRACK/C1GENRENO';
08else {
09// ID3 v1
10$format 'a3TAG/a30NAME/a30ARTISTS/a30ALBUM/a4YEAR/a30COMMENT/C1GENRENO';
11}
12 
13$id3tag = unpack($format$tmp);

Результат работы скрипта:
Array ( [TAG] => TAG [NAME] => test [ARTISTS] => oz [ALBUM] => [YEAR] => 2007 [COMMENT] => [GENRENO] => 0 ) 

Иногда бывает необходимо кроме ID3 tag 'ов узнать и другую инфу об mp3 файле (частоту, bitrate, длительность и др.), я взял за основу библиотекуhttp://pear.php.net/package/MP3_ID и написал следующую функцию, которая позволяет это сделать. Я не буду ее комментировать, потому что здесь мало программирования, а в основном знание структуры mp3 файла, кто захочет - разберется.

001function readframe($file) {
002if (! ($f fopen($file'rb')) ) die("Unable to open " $file);
003$res['filesize'] = filesize($file);
004do {
005while (fread($f,1) != Chr(255)) { // Find the first frame       
006if (feof($f))  die"No mpeg frame found") ;
007}
008fseek($fftell($f) - 1); // back up one byte
009 
010$frameoffset ftell($f);
011 
012$r fread($f, 4);
013 
014$bits = sprintf("%'08b%'08b%'08b%'08b", ord($r{0}), ord($r{1}), ord($r{2}), ord($r{3}));
015}
016while (!$bits[8] and !$bits[9] and !$bits[10]); // 1st 8 bits true from the while   
017 
018// Detect VBR header
019if ($bits[11] == 0) {
020if (($bits[24] == 1) && ($bits[25] == 1)) {
021$vbroffset = 9; // MPEG 2.5 Mono
022else {
023$vbroffset = 17; // MPEG 2.5 Stereo
024}
025else if ($bits[12] == 0) {
026if (($bits[24] == 1) && ($bits[25] == 1)) {
027$vbroffset = 9; // MPEG 2 Mono
028else {
029$vbroffset = 17; // MPEG 2 Stereo
030}
031else {
032if (($bits[24] == 1) && ($bits[25] == 1)) {
033$vbroffset = 17; // MPEG 1 Mono
034else {
035$vbroffset = 32; // MPEG 1 Stereo
036}
037}
038 
039fseek($fftell($f) + $vbroffset);
040$r fread($f, 4);
041 
042switch ($r) {
043case 'Xing':
044$res['encoding_type'] = 'VBR';
045case 'VBRI':
046default:
047if ($vbroffset != 32) {
048// VBRI Header is fixed after 32 bytes, so maybe we are looking at the wrong place.
049fseek($fftell($f) + 32 - $vbroffset);
050$r fread($f, 4);
051 
052if ($r != 'VBRI') {
053$res['encoding_type'] = 'CBR';
054break;
055}
056else {
057$res['encoding_type'] = 'CBR';
058break;
059}
060 
061$res['encoding_type'] = 'VBR';
062}
063 
064fclose($f);
065 
066if ($bits[11] == 0) {
067$res['mpeg_ver'] = "2.5";
068$bitrates array(
069'1' => array(0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0),
070'2' => array(0,  8, 16, 24, 32, 40, 48,  56,  64,  80,  96, 112, 128, 144, 160, 0),
071'3' => array(0,  8, 16, 24, 32, 40, 48,  56,  64,  80,  96, 112, 128, 144, 160, 0),
072);
073else if ($bits[12] == 0) {
074$res['mpeg_ver'] = "2";
075$bitrates array(
076'1' => array(0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0),
077'2' => array(0,  8, 16, 24, 32, 40, 48,  56,  64,  80,  96, 112, 128, 144, 160, 0),
078'3' => array(0,  8, 16, 24, 32, 40, 48,  56,  64,  80,  96, 112, 128, 144, 160, 0),
079);
080else {
081$res['mpeg_ver'] = "1";
082$bitrates array(
083'1' => array(0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0),
084'2' => array(0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384, 0),
085'3' => array(0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 0),
086);
087}
088 
089$layer array(
090array(0,3),
091array(2,1),
092);
093$res['layer'] = $layer[$bits[13]][$bits[14]];
094 
095if ($bits[15] == 0) {
096// It's backwards, if the bit is not set then it is protected.
097$res['crc'] = true;
098}
099 
100$bitrate = 0;
101if ($bits[16] == 1) $bitrate += 8;
102if ($bits[17] == 1) $bitrate += 4;
103if ($bits[18] == 1) $bitrate += 2;
104if ($bits[19] == 1) $bitrate += 1;
105$res['bitrate'] = $bitrates[$res['layer']][$bitrate];
106 
107$frequency array(
108'1' => array(
109'0' => array(44100, 48000),
110'1' => array(32000, 0),
111),
112'2' => array(
113'0' => array(22050, 24000),
114'1' => array(16000, 0),
115),
116'2.5' => array(
117'0' => array(11025, 12000),
118'1' => array(8000, 0),
119),
120);
121$res['frequency'] = $frequency[$res['mpeg_ver']][$bits[20]][$bits[21]];
122 
123$mode array(
124array('Stereo''Joint Stereo'),
125array('Dual Channel''Mono'),
126);
127$res['mode'] = $mode[$bits[24]][$bits[25]];
128 
129$samplesperframe array(
130'1' => array(
131'1' => 384,
132'2' => 1152,
133'3' => 1152
134),
135'2' => array(
136'1' => 384,
137'2' => 1152,
138'3' => 576
139),
140'2.5' => array(
141'1' => 384,
142'2' => 1152,
143'3' => 576
144),
145);
146$res['samples_per_frame'] = $samplesperframe[$res['mpeg_ver']][$res['layer']];
147 
148if ($res['encoding_type'] != 'VBR') {
149if ($res['bitrate'] == 0) {
150$s = -1;
151else {
152$s = ((8*filesize($file))/1000) / $res['bitrate'];
153}
154$res['length'] = sprintf('%02d:%02d',floor($s/60),floor($s-(floor($s/60)*60)));
155$res['lengthh'] = sprintf('%02d:%02d:%02d',floor($s/3600),floor($s/60),floor($s-(floor($s/60)*60)));
156$res['lengths'] = (int)$s;
157 
158$res['samples'] = ceil($res['lengths'] * $res['frequency']);
159if(0 != $res['samples_per_frame']) {
160$res['frames'] = ceil($res['samples'] / $res['samples_per_frame']);
161else {
162$res['frames'] = 0;
163}
164$res['musicsize'] = ceil($res['lengths'] * $res['bitrate'] * 1000 / 8);
165else {
166$res['samples'] = $res['samples_per_frame'] * $res['frames'];
167$s $res['samples'] / $res['frequency'];
168 
169$res['length'] = sprintf('%02d:%02d',floor($s/60),floor($s-(floor($s/60)*60)));
170$res['lengthh'] = sprintf('%02d:%02d:%02d',floor($s/3600),floor($s/60),floor($s-(floor($s/60)*60)));
171$res['lengths'] = (int)$s;
172 
173$res['bitrate'] = (int)(($res['musicsize'] / $s) * 8 / 1000);
174}
175 
176return $res;
177}

Результат работы скрипта:

Array ( 
	[filesize] => 1369759 
	[encoding_type] => CBR 
	[mpeg_ver] => 1 
	[layer] => 3 
	[bitrate] => 192 
	[frequency] => 44100 
	[mode] => Stereo 
	[samples_per_frame] => 1152 
	[length] => 00:57 
	[lengthh] => 00:00:57 
	[lengths] => 57 
	[samples] => 2513700 
	[frames] => 2183 
	[musicsize] => 1368000 
) 


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 29.06.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Enterprise Connectors (1 Year term)
Quest Software. TOAD for Oracle Edition
ABBYY Lingvo x6 Многоязычная Профессиональная версия, электронный ключ
VMware Workstation 14 Pro for Linux and Windows, ESD
СУБД Линтер Бастион. Серверная лицензия. 5 клиентских подключений
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование в AutoCAD
СУБД Oracle "с нуля"
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
Новые материалы
3D и виртуальная реальность. Все о Macromedia Flash MX.
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100