Hi All, I am new to the list ,I am working on ID3 tags decoding. I want to parse ID3v2.4 tag but facing lots of problems as basic idea of ID3v2.4 is not very much clear. Regarding SEEK Frame can anyone highlight how it works. What I know is that it gives the minimum offset of the next tag from the end of the current tag. This minimum offset is in synchsafe integers of four bytes does that mean that every 8th bit of the byte will be zero as was the case for size of tag and total bits will be 28 instead of 32. Please clear this out. Also I need sample tag of ID3v2.4 and ID3v2.2 or it would be great if someone provide me the link where it is available. regards, Rahul --------------------------------------------- http://mail.indiainfo.com India's first ISO certified portal Check world time at http://time.indiainfo.com
Hi,
The id3lib project has some experimental ID3v2.4.0 tags on http://id3lib.sourceforge.net/id3/develop.html. There is also the informal standard document that describes the structure and frames.
regards / Martin
Hi All, I am new to the list ,I am working on ID3 tags decoding. I want to parse ID3v2.4 tag but facing lots of problems as basic idea of ID3v2.4 is not very much clear. Regarding SEEK Frame can anyone highlight how it works. What I know is that it gives the minimum offset of the next tag from the end of the current tag. This minimum offset is in synchsafe integers of four bytes does that mean that every 8th bit of the byte will be zero as was the case for size of tag and total bits will be 28 instead of 32. Please clear this out. Also I need sample tag of ID3v2.4 and ID3v2.2 or it would be great if someone provide me the link where it is available. regards, Rahul
http://mail.indiainfo.com India's first ISO certified portal Check world time at http://time.indiainfo.com
Hello -
I hate to generate traffic that might be FAQs on such a quiet list, but I can't seem to find my answers in any of the places I know about. I've got two separate questions which I will place in two messages after I make this contribution.
I'm trying to update id3v2.4 tags using libid3tag. I implemented Sam Clegg's modifications until I found the part where he hadn't modified the id3_file_update function, so I wrote one and am enclosing it for your consumption and comment. Instead of using Sam's id3_file_open function, I added an argument to id3_file_update for the new file name. Please adapt as you see fit.
I added a field to the id3_file struct: struct id3_file { ... fpos_t id3v2End; // MDM };
Then in search_tags I added the line:
fgetpos(file->iofile, &file->id3v2End);
After all the tags were located (before the comment that reads "look for a tag at the end of the file (before any ID3v1 tag").
Then I replaced the id3_file_update function. No flames please about the style. Goto is not a bad word in my dictionary if used judiciously. :-) Again, adapt as you see fit.
/* * NAME: file->update() * DESCRIPTION: rewrite tag(s) to a file */ int id3_file_update(struct id3_file *file, const char *newFileName) { id3_length_t size; FILE *f = NULL; fpos_t savePos, fileSize; char *contents = NULL;
if (file->mode != ID3_FILE_MODE_READWRITE) goto Err0;
/* ** Scoop in the whole file */ if (fgetpos(file->iofile, &savePos) == -1) goto Err0;
if (fseek (file->iofile, 0, SEEK_END) == -1) goto Err0;
if (fgetpos(file->iofile, &fileSize) == -1) goto Err0;
if (fseek (file->iofile, 0, SEEK_SET) == -1) goto Err0;
if ((contents = (char *) malloc (fileSize)) == NULL) goto Err0;
if (fread (contents, 1, fileSize, file->iofile) != fileSize) goto Err0;
if (fsetpos (file->iofile, &savePos) == -1) goto Err0;
/* ** Open the new file */ if ((f = fopen (newFileName, "w")) == NULL) goto Err0;
/* ** Now render the v2 tag */ file->primary->options &= ~ID3_TAG_OPTION_ID3V1; file->primary->options &= ~ID3_TAG_OPTION_CRC; // Prevent extended header
if ((size = id3_tag_render(file->primary, 0)) > 0) { unsigned char *id3v2 = NULL;
if ((id3v2 = malloc(size)) == 0) goto Err0;
if ((size = id3_tag_render(file->primary, id3v2)) != 0) fwrite (id3v2, size, 1, f);
free(id3v2); }
/* ** Now write the remainder of the file */ { char *writeBuf; fpos_t writeSize;
writeBuf = contents + file->id3v2End; writeSize = fileSize - file->id3v2End; if (file->options | ID3_FILE_OPTION_ID3V1) writeSize -= 128;
fwrite (writeBuf, writeSize, 1, f); }
/* ** Now render the v1 tag */ if (file->options | ID3_FILE_OPTION_ID3V1) { file->primary->options |= ID3_TAG_OPTION_ID3V1;
if ((size = id3_tag_render(file->primary, 0)) > 0) { unsigned char *id3v1 = NULL;
if ((id3v1 = malloc(size)) == 0) return -1;
if ((size = id3_tag_render(file->primary, id3v1)) != 0) fwrite (id3v1, size, 1, f);
free(id3v1); } }
fclose(f); free (contents); return 0;
Err0: if (f) fclose (f); if (contents) free (contents); return -1; }