PHP MP3 ID3

  • wphilipw
  • Student
  • Student
  • No Avatar
  • Inscription: Juin 29, 2006
  • Messages: 87
  • Loc: PA, US
  • Status: Offline

Message Mars 18th, 2008, 1:45 pm

Je travaille sur un lecteur MP3 Tag ID3, et pour l'instant elle ne lit que ID3v1 qui est ok, mais où suis-je avoir un problème avec la balise APIC (embedded image tag) pour une raison quelconque, je suis incapable d'obtenir une taille précise sur elle, et je ne peux pas savoir où est mon erreur, il fonctionne très bien à lire les autres balises dans le MP3, mais pas l'APIC, il s'arrête à mi-chemin par le biais de quelques images et comme 90% grâce à d'autres...Je ne suis pas vraiment, et je sais que les esprits sont multiples meilleure forme alors, donc, serait-on être assez de voir à travers cela et this-moi où est mon erreur? merci!
Code: [ Select ]
function shift7_8($num) {
$num_1 = bindec(str_pad(substr($num, 0, 4), 8, "0", STR_PAD_LEFT));
$num_2 = bindec(substr($num, 4, 8));
$num_3 = bindec(substr($num, 12, 8));
$num_4 = bindec(substr($num, 20, 8));
$num = $num_1 . $num_2 . $num_3 . $num_4;
unset($num_1, $num_2, $num_3, $num_4);
return $num;
}

function id3_read($file) {
// BEGIN ID3 READ

// OPEN MP3 FILE
$mp3 = fopen($file, "r");

// ID3 HEADER READ

// READ THE "ALWAYS PRESENT "ID3"
$id3['base'] = fread($mp3, 3);
// GET THE HEX ID3 VERSION AND CONVERT IT
$id3['version'] = "";
for ($x = 0; $x < 2; $x++) {
$id3['version'] .= str_pad(dechex(ord(fread($mp3, 1))), 2, "0", STR_PAD_LEFT);
}
$id3['version'] = str_split($id3['version']);
if ($id3['version'][0] == "0") { $id3['version'][0] = ""; }
if ($id3['version'][2] == "0") { $id3['version'][2] = ""; }
$id3['version'] = "2." . $id3['version'][0] . $id3['version'][1] . "." . $id3['version'][2] . $id3['version'][3];
// GET THE ID3 BINARY FLAGS - STANDARDS STORED IN FIRST 4 BITES
for ($x = 0; $x < 1; $x++) {
$id3['flags'] = str_pad(decbin(ord(fread($mp3, 1))), 8, "0", STR_PAD_LEFT);
}
$id3['flags'] = str_split($id3['flags']);
// GET THE 4 ID3 SIZE BYTES AND CONVERT THEM TO 8 BIT NUMBERS.
$id3['size'] = "";
for ($x = 0; $x < 4; $x++) {
$id3['size'] .= str_pad(decbin(ord(fread($mp3, 1))), 8, "0", STR_PAD_LEFT);
}
$id3['size'] = shift7_8($id3['size']);

// IF THERE IS AN EXTENDED HEADER, SKIP IT
if ($id3_['flags'][1] == 1) {
// GET THE 4 ID3 EXT HEADER SIZE BYTES AND CONVERT THEM TO 8 BIT NUMBERS.
$id3_exthead_size = "";
for ($x = 0; $x < 4; $x++) {
$id3_exthead_size .= str_pad(decbin(ord(fread($mp3, 1))), 7, "0", STR_PAD_LEFT);
}
$id3_exthead_size = shift7_8($id3_exthead_size);
// SKIP THE EXT HEADER
$tmp = fread($mp3, ($id3_exthead_size - 4));
unset($tmp, $id3_exthead_size);
}

// READ FRAME HEADERS AND LOAD FRAMES INTO ARRAY
$v = 0;
$r = 0;
while ($v < $id3['size']) {
// GET FRAME ID
$id3['frames'][$r]['id'] = "";
for ($x = 0; $x < 4; $x++) {
$id3['frames'][$r]['id'] .= chr(hexdec(str_pad(dechex(ord(fread($mp3, 1))), 2, "0", STR_PAD_LEFT)));
}
if (!preg_match('/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/', $id3['frames'][$r]['id']) || $id3['frames'][$r]['id'] == "") {
unset ($id3['frames'][$r]);
break;
break;
}
// GET THE 4 FRAME SIZE BYTES AND CONVERT THEM TO 8 BIT NUMBERS.
$id3['frames'][$r]['size'] = "";
for ($x = 0; $x < 4; $x++) {
$id3['frames'][$r]['size'] .= str_pad(decbin(ord(fread($mp3, 1))), 7, "0", STR_PAD_LEFT);
}
$id3['frames'][$r]['size'] = shift7_8($id3['frames'][$r]['size']);
echo $id3['frames'][$r]['size'];
// GET THE 2 FRAME FLAG BYTES
$id3['frames'][$r]['flags'] = "";
for ($x = 0; $x < 2; $x++) {
$id3['frames'][$r]['flags'] .= str_pad(dechex(ord(fread($mp3, 1))), 2, "0", STR_PAD_LEFT);
}
// SKIP A BYTE - (TEXT ENCODING)...
$temp = fread($mp3, 1);
unset($temp);
// IF NOT APIC, THEN GET THE FRAME CONTENT
if ($id3['frames'][$r]['id'] != "APIC") {
$id3['frames'][$r]['content'] = fread($mp3, ($id3['frames'][$r]['size'] - 1));
} else {
$tmp = fread($mp3, 1);
while (str_pad(dechex(ord($tmp)), 2, "0", STR_PAD_LEFT) != "00") {
$id3['frames'][$r]['mime'] .= $tmp;
$id3['frames'][$r]['size'] = $id3['frames'][$r]['size'] - 1;
$tmp = fread($mp3, 1);
}
echo $id3['frames'][$r]['size'];
$id3['frames'][$r]['picture_type'] = fread($mp3, 1);
$id3['frames'][$r]['size'] = $id3['frames'][$r]['size'] - 2;
$tmp = fread($mp3, 1);
while (str_pad(dechex(ord($tmp)), 2, "0", STR_PAD_LEFT) != "00") {
$id3['frames'][$r]['description'] .= $tmp;
$id3['frames'][$r]['size'] = $id3['frames'][$r]['size'] - 1;
$tmp = fread($mp3, 1);
}
unset ($tmp);
$id3['frames'][$r]['size'] = $id3['frames'][$r]['size'] - 1;
$id3['frames'][$r]['content'] = fread($mp3, ($id3['frames'][$r]['size']));
}
// INCREMENT FRAME NUMBER AND START OVER
$v = $v + 10 + $id3['frames'][$r]['size'];
$r++;
}
// END ID3 READ

// CLOSE MP3 FILE & RETURN VALUES
fclose($mp3);
return $id3;
}
  1. function shift7_8($num) {
  2. $num_1 = bindec(str_pad(substr($num, 0, 4), 8, "0", STR_PAD_LEFT));
  3. $num_2 = bindec(substr($num, 4, 8));
  4. $num_3 = bindec(substr($num, 12, 8));
  5. $num_4 = bindec(substr($num, 20, 8));
  6. $num = $num_1 . $num_2 . $num_3 . $num_4;
  7. unset($num_1, $num_2, $num_3, $num_4);
  8. return $num;
  9. }
  10. function id3_read($file) {
  11. // BEGIN ID3 READ
  12. // OPEN MP3 FILE
  13. $mp3 = fopen($file, "r");
  14. // ID3 HEADER READ
  15. // READ THE "ALWAYS PRESENT "ID3"
  16. $id3['base'] = fread($mp3, 3);
  17. // GET THE HEX ID3 VERSION AND CONVERT IT
  18. $id3['version'] = "";
  19. for ($x = 0; $x < 2; $x++) {
  20. $id3['version'] .= str_pad(dechex(ord(fread($mp3, 1))), 2, "0", STR_PAD_LEFT);
  21. }
  22. $id3['version'] = str_split($id3['version']);
  23. if ($id3['version'][0] == "0") { $id3['version'][0] = ""; }
  24. if ($id3['version'][2] == "0") { $id3['version'][2] = ""; }
  25. $id3['version'] = "2." . $id3['version'][0] . $id3['version'][1] . "." . $id3['version'][2] . $id3['version'][3];
  26. // GET THE ID3 BINARY FLAGS - STANDARDS STORED IN FIRST 4 BITES
  27. for ($x = 0; $x < 1; $x++) {
  28. $id3['flags'] = str_pad(decbin(ord(fread($mp3, 1))), 8, "0", STR_PAD_LEFT);
  29. }
  30. $id3['flags'] = str_split($id3['flags']);
  31. // GET THE 4 ID3 SIZE BYTES AND CONVERT THEM TO 8 BIT NUMBERS.
  32. $id3['size'] = "";
  33. for ($x = 0; $x < 4; $x++) {
  34. $id3['size'] .= str_pad(decbin(ord(fread($mp3, 1))), 8, "0", STR_PAD_LEFT);
  35. }
  36. $id3['size'] = shift7_8($id3['size']);
  37. // IF THERE IS AN EXTENDED HEADER, SKIP IT
  38. if ($id3_['flags'][1] == 1) {
  39. // GET THE 4 ID3 EXT HEADER SIZE BYTES AND CONVERT THEM TO 8 BIT NUMBERS.
  40. $id3_exthead_size = "";
  41. for ($x = 0; $x < 4; $x++) {
  42. $id3_exthead_size .= str_pad(decbin(ord(fread($mp3, 1))), 7, "0", STR_PAD_LEFT);
  43. }
  44. $id3_exthead_size = shift7_8($id3_exthead_size);
  45. // SKIP THE EXT HEADER
  46. $tmp = fread($mp3, ($id3_exthead_size - 4));
  47. unset($tmp, $id3_exthead_size);
  48. }
  49. // READ FRAME HEADERS AND LOAD FRAMES INTO ARRAY
  50. $v = 0;
  51. $r = 0;
  52. while ($v < $id3['size']) {
  53. // GET FRAME ID
  54. $id3['frames'][$r]['id'] = "";
  55. for ($x = 0; $x < 4; $x++) {
  56. $id3['frames'][$r]['id'] .= chr(hexdec(str_pad(dechex(ord(fread($mp3, 1))), 2, "0", STR_PAD_LEFT)));
  57. }
  58. if (!preg_match('/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/', $id3['frames'][$r]['id']) || $id3['frames'][$r]['id'] == "") {
  59. unset ($id3['frames'][$r]);
  60. break;
  61. break;
  62. }
  63. // GET THE 4 FRAME SIZE BYTES AND CONVERT THEM TO 8 BIT NUMBERS.
  64. $id3['frames'][$r]['size'] = "";
  65. for ($x = 0; $x < 4; $x++) {
  66. $id3['frames'][$r]['size'] .= str_pad(decbin(ord(fread($mp3, 1))), 7, "0", STR_PAD_LEFT);
  67. }
  68. $id3['frames'][$r]['size'] = shift7_8($id3['frames'][$r]['size']);
  69. echo $id3['frames'][$r]['size'];
  70. // GET THE 2 FRAME FLAG BYTES
  71. $id3['frames'][$r]['flags'] = "";
  72. for ($x = 0; $x < 2; $x++) {
  73. $id3['frames'][$r]['flags'] .= str_pad(dechex(ord(fread($mp3, 1))), 2, "0", STR_PAD_LEFT);
  74. }
  75. // SKIP A BYTE - (TEXT ENCODING)...
  76. $temp = fread($mp3, 1);
  77. unset($temp);
  78. // IF NOT APIC, THEN GET THE FRAME CONTENT
  79. if ($id3['frames'][$r]['id'] != "APIC") {
  80. $id3['frames'][$r]['content'] = fread($mp3, ($id3['frames'][$r]['size'] - 1));
  81. } else {
  82. $tmp = fread($mp3, 1);
  83. while (str_pad(dechex(ord($tmp)), 2, "0", STR_PAD_LEFT) != "00") {
  84. $id3['frames'][$r]['mime'] .= $tmp;
  85. $id3['frames'][$r]['size'] = $id3['frames'][$r]['size'] - 1;
  86. $tmp = fread($mp3, 1);
  87. }
  88. echo $id3['frames'][$r]['size'];
  89. $id3['frames'][$r]['picture_type'] = fread($mp3, 1);
  90. $id3['frames'][$r]['size'] = $id3['frames'][$r]['size'] - 2;
  91. $tmp = fread($mp3, 1);
  92. while (str_pad(dechex(ord($tmp)), 2, "0", STR_PAD_LEFT) != "00") {
  93. $id3['frames'][$r]['description'] .= $tmp;
  94. $id3['frames'][$r]['size'] = $id3['frames'][$r]['size'] - 1;
  95. $tmp = fread($mp3, 1);
  96. }
  97. unset ($tmp);
  98. $id3['frames'][$r]['size'] = $id3['frames'][$r]['size'] - 1;
  99. $id3['frames'][$r]['content'] = fread($mp3, ($id3['frames'][$r]['size']));
  100. }
  101. // INCREMENT FRAME NUMBER AND START OVER
  102. $v = $v + 10 + $id3['frames'][$r]['size'];
  103. $r++;
  104. }
  105. // END ID3 READ
  106. // CLOSE MP3 FILE & RETURN VALUES
  107. fclose($mp3);
  108. return $id3;
  109. }

Merci encore à tous et tout ce qui jetez un œil à ceci.
  • Anonymous
  • Bot
  • No Avatar
  • Inscription: 25 Feb 2008
  • Messages: ?
  • Loc: Ozzuland
  • Status: Online

Message Mars 18th, 2008, 1:45 pm

  • wphilipw
  • Student
  • Student
  • No Avatar
  • Inscription: Juin 29, 2006
  • Messages: 87
  • Loc: PA, US
  • Status: Offline

Message Mars 20th, 2008, 3:01 pm

btw, résolu!
  • phreak2day
  • Born
  • Born
  • No Avatar
  • Inscription: Sep 06, 2010
  • Messages: 1
  • Status: Offline

Message Septembre 7th, 2010, 4:29 am

Salut à tous! J'ai le même problème et Ive été claquer la tête contre le mur pour plus de 2 mois et je n'ai pas trouvé une solution. Pourriez-vous me dire, si vous vous rappelez, ce que vous avez fait pour résoudre le problème? Je continue à s'enliser lecture le cadre APIC, vous voulez l'éviter complètement, mais je n'arrive pas à le sauter pendant le processus de lecture. Ce programme que je vous écris est pour un examen que j'ai et que j'ai besoin de terminer dans les prochains jours ASAP et je serais donc très reconnaissant pour toute aide que vous pouvez donner.



EDIT:

Résolu! Au moins, il semble être. :P
OK, alors pour quelqu'un d'autre qui pourrait avoir ce problème à l'avenir (comment sauter la lecture de la trame APIC), c'est ce que je faisais et comment je l'ai résolu.

Qu'est-ce que je faisais:
Sur le site officiel (ID3 <dot> org), qui est AWFUL , Dit que «La taille tag ID3v2 est codé avec quatre octets où le bit le plus significannot (bit 7) est fixée à zéro dans chaque octet, soit un total de 28 bits. Les bits à zéro sont ignorés...". J'ai pris cette logique et il appyed lors de la lecture de la taille de balise et toutes les tailles. Pour le mettre dans le code que je faisais ceci:
<C #> Extrait
sizeOfTheTag int = Wich taille <le est read> ;
readerPosition int;
octet tagByteArray [] = new byte [sizeOfTheTag];
/ /...
/ / Lorsque le cadre APIC ID se trouve (ce qui était en fonction, mais tout se résume à ceci):
framesize = ((tagByteArray [readerPosition] <<21) | (tagByteArray [readerPosition + 1] <<14) | (tagByteArray readerPosition [+ 2] <<7) | (tagByteArray [readerPosition + 3]));
+ = ReaderPosition framesize; / / (TRY) à sauter le cadre APIC
/ / Échec!

Comment je l'ai résolu:
J'ai passé des heures et des heures à essayer de trouver où le problème était si j'ai commencé à lire un fichier MP3 en vue de sortilège avec Notepad + + et en comparant ses positions cadre avec la taille que j'ai eu la lecture de la manière ci-dessus. Puis j'ai tourné la vue de binaires et tryed à faire une transformation manuelle de la taille du cadre APIC. Faire les choses de la manière ci-dessus (comme le site officiel États-Unis) ressemble à ceci:
/ / Un exemple, la taille est lue sous forme binaire comme ceci:
00000000 | 00000011 | 00111001 | 01000011
/ / Puis nous ignorons tout premier bit et obtenez ceci:
_0000000 | _0000011 | _0111001 | _1000011
/ / Et puis tout est «serrées» et nous obtenons:
____0000 | 00000000 | 11011100 | 11000011
/ / Une fois convertie en un nombre décimal, on obtient:
56515

C'est offcourse, était trop petite et la position lecteur gardé tomber dans le cadre de l'APIC. Alors, j'ai essayé d'obtenir la taille d'image par ne pas ignorer le premier bit, comme ceci:
/ / La taille même exemple est lue sous forme binaire comme ceci:
00000000 | 00000011 | 00111001 | 01000011
/ / Quand nous n'avons pas ignorer tous les premier bit nous obtenons ceci:
00000000 | 00000011 | 00111001 | 01000011
/ / Et quand tout est «serrées» et nous obtenons:
00000000 | 00000011 | 00111001 | 01000011
/ / Et ensuite convertie en un nombre décimal, on obtient:
211267

Voilà une GRANDE différence! Et maintenant je peux lire facilement la taille du cadre APIC et l'ignorer, pour l'instant. Peut être plus tard Ill essayer de lire / modifier. gif "alt = =":)" titre" Smile "> Ainsi, le nouveau code pour la lecture de la taille est:
<C #> Extrait
framesize = ((tagByteArray [readerPosition] <<24) | (tagByteArray [readerPosition + 1] <<16) | (tagByteArray [readerPosition + 2] <<8) | (tagByteArray [readerPosition + 3]));
Tout le reste est restée la même.

J'espère que cela aidera tout le monde qui reçoit ce problème afin que vous n'avez pas à perdre autant de temps que j'ai. La seule chose que je ne sais pas pourquoi cela n'a pas procédé à la lecture de toutes les tailles d'image d'autres. Mais qui s'en soucie quand ça marche, non? ;)



Si je tombe sur des problèmes mauvais ajouter un commentaire. ;)

Afficher de l'information

  • Total des messages de ce sujet: 3 messages
  • Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 137 invités
  • Vous ne pouvez pas poster de nouveaux sujets
  • Vous ne pouvez pas répondre aux sujets
  • Vous ne pouvez pas éditer vos messages
  • Vous ne pouvez pas supprimer vos messages
  • Vous ne pouvez pas joindre des fichiers
 
 

© 2011 Unmelted, LLC. Ozzu® est une marque déposée de Unmelted, LLC