Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mp3 ID3 tags, confusing APIC frame structure

I'm working on a JavaScript (frontend side) ID3 tags reader for Mp3 files. I managed to parse text frames. Now, the APIC frame doesn't make sense to me.

According to official specification, each frame starts with this:

Frame ID      $xx xx xx xx  (four characters)
Size      4 * %0xxxxxxx
Flags         $xx xx

And this is the APIC frame structure:

<Header for 'Attached picture', ID: "APIC">
Text encoding   $xx
MIME type       <text string> $00
Picture type    $xx
Description     <text string according to encoding> $00 (00)
Picture data    <binary data>

I attached screenshots of 2 songs opened with Sublime Text in UTF-8 encoding. So, I'd expect to see MIME type right after the 7th byte (frame size + flags + APIC text encoding) after the "APIC" word. Works for the 1st file, but on the 2nd there are 2 more bytes before the actual MIME type. I have other files where the MIME type is prefixed with few weird bytes (not necessarily 2 bytes). The picture type byte seems more straightforward, although it is followed by a 0x00 byte (documentation doesn't say anything about it being followed by $00) and the actual value is sometimes missing. And I'm not sure where the description part actually stops and the picture data begins.

File 1

File 2

like image 923
Alexander Avatar asked Oct 24 '25 12:10

Alexander


1 Answers

In case anyone finds this from google, the actual answer is that you have to watch out for the two flag bytes at the end of the frame header. Some flags indicate an extended header.

I don’t understand the notation in your screenshots, but personally I have a file that goes:

41 50 49 43  //APIC
00 08 5A 04  //Frame Size
00 03        //Flags: Unsynchronisation | Data Length Indicator.
00 02 19 F5  //4 bytes data length
00           //1 byte text encoding (ISO-8859-1)
69 6D 61 67  //image/jpeg
65 2F 6A 70  // ”
65 67        // ”

The resulting extension length is in the ID3v2.4 spec (4.1.2). The Data Length Indicator in my example always appends 4 bytes. The order of the extension bytes is apparently the same as the flag bits.

So TL;DR: frame headers can be longer than 10 bytes (as can the tag header).

like image 152
BenderBoy Avatar answered Oct 27 '25 02:10

BenderBoy