// Caller must delete [] dst after use. static void field_text(char** dst, ID3_Frame* frame) { iconv_t cd = iconv_open("UTF8","UTF16BE"); const int bufsize = 1000; char buf[bufsize]; if (NULL != frame) { ID3_Field* field = frame->GetField(ID3FN_TEXT); if (NULL != field) { switch(field->GetEncoding()){ case ID3TE_UTF16: case ID3TE_UTF16BE: // Convert to UTF-8 before returning the data to Go. if ( cd != (iconv_t) -1 ) { char* in = (char*) field->GetRawUnicodeText(); size_t insize = field->Size(); char* bufptr = buf; size_t bufbytes = bufsize; size_t rc = 0; // Initialize iconv state if( iconv(cd, NULL, NULL, &bufptr, &bufbytes) == (size_t) -1 ){ *dst = empty_string(); break; } if ( (rc = iconv(cd, &in, &insize, &bufptr, &bufbytes)) != (size_t) -1 ) { *bufptr = '\0'; *dst = new char[bufsize-bufbytes+1]; memcpy(*dst, buf, bufsize-bufbytes); (*dst)[bufsize-bufbytes] = '\0'; } else { *dst = empty_string(); } } else { *dst = empty_string(); } break; default: // Ascii *dst = new char[field->Size()+1]; (*dst)[0] = '\0'; size_t len = field->Get(*dst, field->Size()+1); (*dst)[field->Size()] = '\0'; } } } iconv_close(cd); }
ID3_Frame *ID3_TagImpl::Find(ID3_FrameID id, ID3_FieldID fldID, WString data) const { ID3_Frame *frame = NULL; // reset the cursor if it isn't set if (_frames.end() == _cursor) { _cursor = _frames.begin(); } for (int iCount = 0; iCount < 2 && frame == NULL; iCount++) { // We want to cycle through the list to find the matching frame. We // should begin from the cursor, search each successive frame, wrapping // if necessary. The enclosing loop and the assignment statments below // ensure that we first begin at the cursor and search to the end of the // list and, if unsuccessful, start from the beginning of the list and // search to the cursor. const_iterator begin = (0 == iCount ? _cursor : _frames.begin()), end = (0 == iCount ? _frames.end() : _cursor); // search from the cursor to the end for (const_iterator cur = begin; cur != end; ++cur) { if ((*cur != NULL) && ((*cur)->GetID() == id) && (*cur)->Contains(fldID)) { ID3_Field* fld = (*cur)->GetField(fldID); if (NULL == fld) { continue; } WString text = toWString(fld->GetRawUnicodeText(), fld->Size()); if (text == data) { // We've found a valid frame. Set cursor to be the next element frame = *cur; _cursor = ++cur; break; } } } } return frame; }
void MP3TagReader::ImportTags(MatroskaTagInfo *target) { #ifdef USING_ID3LIB // use an std::auto_ptr here to handle object cleanup automatically ID3_Tag::Iterator *iter = m_Tag.CreateIterator(); ID3_Frame *myFrame = NULL; while (NULL != (myFrame = iter->GetNext())) { // do something with myFrame //myFrame; ID3_Field *textField = myFrame->GetField(ID3FN_TEXTENC); ID3_Field *intField = myFrame->GetField(ID3FN_COUNTER); if (myFrame->GetID() == ID3FID_PLAYCOUNTER) { target->Tag_PlayCounter = intField->Get(); } else if (myFrame->GetID() == ID3FID_POPULARIMETER) { target->Tag_Popularimeter = intField->Get(); } else if (myFrame->GetID() == ID3FID_ALBUM) { MatroskaTagMultiTitleItem *newTagItem = new MatroskaTagMultiTitleItem(); newTagItem->Type = KaxTagMultiTitleType_AlbumMovieShowTitle; newTagItem->Name = textField->GetRawUnicodeText(); target->AddMultiTitleItem(newTagItem); } else if (myFrame->GetID() == ID3FID_BPM) { target->Tag_BPM = intField->Get(); } else if (myFrame->GetID() == ID3FID_COMPOSER) { MatroskaTagMultiEntityItem *newTagItem = new MatroskaTagMultiEntityItem(); newTagItem->Type = KaxTagMultiEntitiesType_Composer; newTagItem->Name = textField->GetRawUnicodeText(); target->AddMultiEntityItem(newTagItem); } else if (myFrame->GetID() == ID3FID_PLAYLISTDELAY) { target->Tag_PlaylistDelay = intField->Get(); } else if (myFrame->GetID() == ID3FID_ENCODEDBY) { MatroskaTagMultiEntityItem *newTagItem = new MatroskaTagMultiEntityItem(); newTagItem->Type = KaxTagMultiEntitiesType_EncodedBy; newTagItem->Name = textField->GetRawUnicodeText(); target->AddMultiEntityItem(newTagItem); } else if (myFrame->GetID() == ID3FID_LYRICIST) { MatroskaTagMultiEntityItem *newTagItem = new MatroskaTagMultiEntityItem(); newTagItem->Type = KaxTagMultiEntitiesType_LyricistTextWriter; newTagItem->Name = textField->GetRawUnicodeText(); target->AddMultiEntityItem(newTagItem); } else if (myFrame->GetID() == ID3FID_TITLE) { MatroskaTagMultiTitleItem *newTagItem = new MatroskaTagMultiTitleItem(); newTagItem->Type = KaxTagMultiTitleType_TrackTitle; newTagItem->Name = textField->GetRawUnicodeText(); target->AddMultiTitleItem(newTagItem); } else if (myFrame->GetID() == ID3FID_SUBTITLE) { MatroskaTagMultiTitleItem *newTagItem = new MatroskaTagMultiTitleItem(); newTagItem->Type = KaxTagMultiTitleType_TrackTitle; newTagItem->SubTitle = textField->GetRawUnicodeText(); target->AddMultiTitleItem(newTagItem); } } delete iter; #endif };
void play_debug_meta(char* filename){ ID3_Tag tag(filename); ID3_Tag::Iterator* iter = tag.CreateIterator(); ID3_Frame* frame = NULL; char buf[1000]; // Iconv conversion descriptor: UTF-16 -> UTF-8 iconv_t cd = iconv_open("UTF8","UTF16BE"); while (NULL != (frame = iter->GetNext())) { char* val = NULL; field_text(&val, frame); printf("Frame: type %d %s %s:\n", frame->GetID(), frame->GetTextID(), frame->GetDescription()); ID3_Frame::Iterator* fieldIter = frame->CreateIterator(); ID3_Field* field = NULL; while (NULL != (field = fieldIter->GetNext())) { printf(" Field: type "); ID3_FieldType type = field->GetType(); switch(type) { case ID3FTY_NONE: printf("none"); break; case ID3FTY_INTEGER: printf("int"); break; case ID3FTY_BINARY: printf("binary"); break; case ID3FTY_TEXTSTRING: field->Get(buf, 1000); printf("text with %d items, encoding ", field->GetNumTextItems()); switch(field->GetEncoding()){ case ID3TE_UTF16: printf("UTF-16"); if ( cd != (iconv_t) -1 ) { char* in = (char*) field->GetRawUnicodeText(); size_t insize = field->Size(); char* bufptr = buf; size_t bufsize = 1000; size_t rc = 0; // Initialize iconv state if( iconv(cd, NULL, NULL, &bufptr, &bufsize) == (size_t) -1 ){ printf("iconv init Failed\n"); } if ( (rc = iconv(cd, &in, &insize, &bufptr, &bufsize)) != (size_t) -1 ) { *bufptr = '\0'; printf(": '%s' (%d chars)\n", buf, rc); } else { printf("<conversion using iconv failed>"); perror("iconv"); } } break; case ID3TE_UTF16BE: printf("UTF-16BE"); printf(": '%s'", buf); break; case ID3TE_UTF8: printf("UTF-8"); printf(": '%s'", buf); break; case ID3TE_NONE: printf("none"); printf(": '%s'", buf); break; case ID3TE_ISO8859_1: printf("ISO-8859-1/ASCII"); printf(": '%s'", buf); break; } break; } printf("\n"); } delete fieldIter; delete [] val; } delete iter; iconv_close(cd); }