Witam napisałem sobie własną funkcję do wyciągania tagów ID3v2 z plików mp3, ale mam pewien problem z niektórymi plikami. Zdarza się że czasem źle odczytuje rozmiar tagu i bądź też ramki (głównie przy GEOB oraz APIC). Podczas robienia podpierałem się trochę istniejącymi skryptami a strukturę tagu mam ze strony
http://www.id3.org/. Poniżej przesyłam kod. Może gdzieś popełniłem błąd przy przetwarzaniu tagu.
// Funkcja wyciągająca nagłówek tagu
function id3v2header($file)
{
$stream=fopen($file,"r"); $header=fread($stream,10
);
$id3v2header['filename']=$file;
if(substr($header,0,3)!="ID3") {
$id3v2header['exist']=FALSE;
$id3v2header['size']=0;
return $id3v2header;
};
$id3v2header['exist']=TRUE;
$id3v2header['tagid']=substr($header,0
,3
); $id3v2header['version']=be2int($header[3]).".".be2int($header[4]);
$flags=be2bin($header[5]);
$id3v2header['flags']['full']=$flags;
$id3v2header['flags']['unsynchronisation']=substr($flags,0
,1
); $id3v2header['flags']['extended_header']=substr($flags,1
,1
); $id3v2header['flags']['experimental_indicator']=substr($flags,2
,1
); $id3v2header['flags']['footer_present']=substr($flags,3
,1
); $id3v2header['size']=unsynchsafe
(be2int
(substr($header,6
,4
)));
return $id3v2header;
};
// Funkcja wyciągająca cały tag
function id3v2tag($file, $tagsize)
{
if($tagsize==0)
{
$id3v2tag['exist']=FALSE;
return $id3v2tag;
};
$id3v2tag['exist']=TRUE;
$stream=fopen($file,"r"); $tag=fread($stream,$tagsize); $id3v2tag['fulltag']=substr($tag,10
); $allowedtag=file("inc/txtfiles/allowed_tag.txt"); $x=0;
$count['WXXX']=0;
$count['APIC']=0;
$count['UFID']=0;
$count['GEOB']=0;
$count['COMM']=0;
$count['TXXX']=0;
$count['POPM']=0;
$count['USLT']=0;
$count['AENC']=0;
$count['SYLT']=0;
$count['LINK']=0;
$count['RVA2']=0;
$count['USER']=0;
$count['COMR']=0;
$count['EQU2']=0;
$count['ENCR']=0;
$count['GRID']=0;
$count['PRIV']=0;
$count['SIGN']=0;
$listpos=0;
while ($x<($tagsize-10))
{
$frame=substr($id3v2tag['fulltag'],$x,4
); for($y=0;$y<4;++$y)
{
$fid[$y]=be2bin
(substr($frame,$y,1
)); };
$condition= ($fid[0]!=0x00 &&
((ord($frame[0])>=0x30 && ord($frame[0])<=0x39) || (ord($frame[0])>=0x41 && ord($frame[0])<=0x5A)) &&
$fid[1]!=0x00 &&
((ord($frame[1])>=0x30 && ord($frame[1])<=0x39) || (ord($frame[1])>=0x41 && ord($frame[1])<=0x5A)) &&
$fid[2]!=0x00 &&
((ord($frame[2])>=0x30 && ord($frame[2])<=0x39) || (ord($frame[2])>=0x41 && ord($frame[2])<=0x5A)) &&
$fid[3]!=0x00 &&
((ord($frame[3])>=0x30 && ord($frame[3])<=0x39) || (ord($frame[3])>=0x41 && ord($frame[3])<=0x5A)) &&
if($condition==true)
{
$id3v2tag['framelist']["$listpos"]['id']=$frame;
$id3v2tag['framelist']["$listpos"]['fullname']=framefullname($frame);
$condition=(
$frame=="WXXX" ||
$frame=="APIC" ||
$frame=="UFID" ||
$frame=="GEOB" ||
$frame=="COMM" ||
$frame=="TXXX" ||
$frame=="POPM" ||
$frame=="USLT" ||
$frame=="AENC" ||
$frame=="SYLT" ||
$frame=="LINK" ||
$frame=="RVA2" ||
$frame=="USER" ||
$frame=="COMR" ||
$frame=="EQU2" ||
$frame=="ENCR" ||
$frame=="GRID" ||
$frame=="PRIV" ||
$frame=="SIGN");
if($condition==true)
{
$id3v2tag['frames']["$frame"]["$count[$frame]"]['id']=$frame;
$x+=4;
$id3v2tag['frames']["$frame"]["$count[$frame]"]['fullname']=framefullname($frame);
$id3v2tag['frames']["$frame"]["$count[$frame]"]['size']=unsynchsafe
(be2int
(substr($id3v2tag['fulltag'],$x,4
))); if($frame=="APIC")
{
$id3v2tag['frames']["$frame"]["$count[$frame]"]['size']=2*$id3v2tag['frames']["$frame"]["$count[$frame]"]['size'];
};
$x+=4;
$id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_status_flag']['full']=be2bin
(substr($id3v2tag['fulltag'],$x,1
)); $id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_status_flag']['tag_alter_preservation']=substr($id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_status_flag']['full'],1
,1
); $id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_status_flag']['file_alter_preservation']=substr($id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_status_flag']['full'],2
,1
); $id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_status_flag']['read_only']=substr($id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_status_flag']['full'],3
,1
); $x++;
$id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['full']=be2bin
(substr($id3v2tag['fulltag'],$x,1
)); $id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['grouping_identity']=substr($id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['full'],1
,1
); $id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['compresion']=substr($id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['full'],4
,1
); $id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['encryption']=substr($id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['full'],5
,1
); $id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['unsynchronisation']=substr($id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['full'],6
,1
); $id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['data_length_indicator']=substr($id3v2tag['frames']["$frame"]["$count[$frame]"]['flags']['frame_format_flag']['full'],7
,1
); $x++;
$id3v2tag['frames']["$frame"]["$count[$frame]"]['data']=substr($id3v2tag['fulltag'],$x,$id3v2tag['frames']["$frame"]["$count[$frame]"]['size']); $id3v2tag['frames']["$frame"]["$count[$frame]"]['processed_data']=identifyframe($id3v2tag['frames']["$frame"]["$count[$frame]"]['id'],$id3v2tag['frames']["$frame"]["$count[$frame]"]['data']);
$id3v2tag['lastletters']=substr($id3v2tag['frames']["$frame"]["$count[$frame]"]['data'],-4
); $id3v2tag['lastletterspos']=strpos($id3v2tag['fulltag'],$id3v2tag['lastletters'])+10; $count[$frame]++;
}
else
{
$id3v2tag['frames']["$frame"]['id']=$frame;
$x+=4;
$id3v2tag['frames']["$frame"]['fullname']=framefullname($frame);
$id3v2tag['frames']["$frame"]['size']=unsynchsafe
(be2int
(substr($id3v2tag['fulltag'],$x,4
))); $x+=4;
$id3v2tag['frames']["$frame"]['flags']['frame_status_flag']['full']=be2bin
(substr($id3v2tag['fulltag'],$x,1
)); $x++;
$id3v2tag['frames']["$frame"]['flags']['frame_status_flag']['tag_alter_preservation']=substr($id3v2tag['frames']["$frame"]['flags']['frame_status_flag']['full'],1
,1
); $id3v2tag['frames']["$frame"]['flags']['frame_status_flag']['file_alter_preservation']=substr($id3v2tag['frames']["$frame"]['flags']['frame_status_flag']['full'],2
,1
); $id3v2tag['frames']["$frame"]['flags']['frame_status_flag']['read_only']=substr($id3v2tag['frames']["$frame"]['flags']['frame_status_flag']['full'],3
,1
);
$id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['full']=be2bin
(substr($id3v2tag['fulltag'],$x,1
)); $id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['grouping_identity']=substr($id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['full'],1
,1
); $id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['compresion']=substr($id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['full'],4
,1
); $id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['encryption']=substr($id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['full'],5
,1
); $id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['unsynchronisation']=substr($id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['full'],6
,1
); $id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['data_length_indicator']=substr($id3v2tag['frames']["$frame"]['flags']['frame_format_flag']['full'],7
,1
); $x++;
$id3v2tag['frames']["$frame"]['data']=substr($id3v2tag['fulltag'],$x,$id3v2tag['frames']["$frame"]['size']); $id3v2tag['frames']["$frame"]['processed_data']=identifyframe($id3v2tag['frames']["$frame"]['id'],$id3v2tag['frames']["$frame"]['data']);
if($id3v2tag['coding']=$id3v2tag['frames']["$frame"]['processed_data']['encoding'])
{}
else if($id3v2tag['coding']==null)
{$id3v2tag['coding']="UTF-8";}
else{};
$id3v2tag['lastletters']=substr($id3v2tag['frames']["$frame"]['data'],-4
); $id3v2tag['lastletterspos']=strpos($id3v2tag['fulltag'],$id3v2tag['lastletters'])+10; };
$listpos++;
}
else
{
$x++;
};
};
return $id3v2tag;
};
// Identyfikacja ramek
function framefullname($frame)
{
$file="inc/txtfiles/framefullname.txt";
$x=0;
while($x<$li)
{
$fullname=substr($list[$x],5
); $framefullname["$id"]=substr($fullname,0
,$lii); ++$x;
};
return $framefullname["$frame"];
};
// pełna nazwa ramki
function framefullname($frame)
{
$file="inc/txtfiles/framefullname.txt";
$x=0;
while($x<$li)
{
$fullname=substr($list[$x],5
); $framefullname["$id"]=substr($fullname,0
,$lii); ++$x;
};
return $framefullname["$frame"];
};
// identyfikacja kodowania ramki
function coding_table($type,$id3v2tagcoding)
{
switch($id3v2tagcoding)
{
case 0x00:
$info['coding']="ISO-8859-1";
$info['pagecoding']="ISO-8859-2";
$info['terminator']=chr(0);
break;
case 0x01:
$info['coding']="UTF-16";
$info['pagecoding']="UTF-8";
$info['terminator']=chr(0);
$info['terminator'].=chr(0);
break;
case 0x02:
$info['coding']="UTF-16BE";
$info['pagecoding']="UTF-8";
$info['terminator']=chr(0);
$info['terminator'].=chr(0);
break;
case 0x03:
$info['coding']="UTF-8";
$info['pagecoding']="UTF-8";
$info['terminator']=chr(0);
break;
default:
$info['coding']="UTF-8";
$info['pagecoding']="UTF-8";
$info['terminator']=chr(0);
break;
};
return $info["$type"];
};
// funkcja do wyciągania rozmiaru z synchsafe (znaleziona na internecie w C)
function unsynchsafe($in)
{
$out = 0;
$mask = 0x7F000000;
while ($mask)
{
$out >>= 1;
$out |= $in & $mask;
$mask >>= 8;
}
return $out;
}
// Z Big Endian na heksadecymalną liczbę
function binhex($bin)
{
return $hex;
};
// Z Big Endian na binarny zapis
function be2bin($byteword)
{
$binvalue = '';
$bytewordlen = strlen($byteword); for ($i=0;$i<$bytewordlen;$i++)
{
$binvalue .= str_pad(decbin(ord
($byteword{$i})), 8, '0', STR_PAD_LEFT
); }
return $binvalue;
};
// z Big Endian na ciąg znaków drukowanych
function be2str($word)
{
$string="";
for($y=0; $y<strlen($word);$y++)
{
$string.=chr
(bindec(be2bin
($word[$y]))); };
return $string;
};
// Z Big Endian na liczbę dziesiętną - zamienia cały ciąg znaków na liczbę dziesiętną (nie było mi potrzebne nic innego)
function be2int($be)
{
return $int;
};
// Identyfikacja niektórych bajtów na odpowiednie wartości wyciągane z pliku jak np. typ obrazka
function select_from_file_table($in, $name)
{
$file=file("inc/txtfiles/$name.txt"); //$in=hexdec($in);
$x=0;
while($x<$li)
{
$explode[$x]=explode(";;",$file[$x]); $x++;
};
$x=0;
while($x<$li)
{
$explode[$x][0
]=hexdec($explode[$x][0
]); $x++;
};
$x=0;
while($x<$li)
{
$out[$explode[$x][0
]]=substr($explode[$x][1
],0
,$o); $x++;
};
return $out["$in"];
}
jeszcze jedna funkcja ale nie mieści się w poście dlatego wrzucę linka do niej:
Identify frameProsiłbym moderatora o usunięcie tego mojego tematu.