2011-10-26 7 views
0

Итак, моя конечная игра получает обложку альбома из моих аудиофайлов. Я использую taglib и C++. Я нашел информацию о том, как извлекать данные встроенного изображения, но кажется, что Windows Media Player не внедряет сам образ. вместо этого он сохраняет jpg под названием что-то вроде AlbumArt_ {E3208100-4FAA-4030-BB9D-6DA5F9D93D18} _Large.jpg. очевидно, что он использует guid, который, по моему мнению, сохраняет в теге PRIV. мой вопрос к вам, как я могу добраться до него? Я думал, что-то вроде этого может работать:Извлечение GUID из файла MP3 с помощью TagLib

ID3v2::PrivateFrame* privFrame = static_cast<ID3v2::PrivateFrame*>(*privIter); 
    if(privFrame != NULL) 
    { 
     std::string owner = privFrame->owner().toCString(); 
     if (owner == "WM/WMCollectionID" || owner == "WM/WMCollectionGroupID") 
     { 
      const char* data = privFrame->render().data(); 
      GUID guid; 
      memcpy(&guid.Data1, data, sizeof(long)); 
     } 
    } 

но данные, похоже, ничего полезного. есть идеи?

+0

так, я не получаю никаких ударов на это, и я не найти какие-либо хорошие ресурсы в Интернете, поэтому я рассматриваю чтение данных вручную с good'ol fstream. кто-нибудь знает какие-либо ресурсы для этого? мне нужно будет сначала проверить, что файл содержит теги id3v2, а затем читать каждый, пока я не найду тот, который я ищу. подробности о спецификации, а также любые извлеченные уроки будут очень полезными. – mike

+0

aaargh, почему так сложно снимать альбом? впечатление, которое я получаю, - это большинство приложений, которые просто вставляют изображение внутри аудиофайла, за исключением wmp. это точная оценка? mike

ответ

0

для тех, у кого схожие проблемы, насколько я могу сказать, PrivateFrame taglib нарушен. Таким образом, я свернул мой собственный:

bool MetadataReader::getAlbumGUID(const char* filename, GUID &guid) 
{ 
    const int HEADER_LENGTH = 10; 
    const int TAG_INDICATOR_LENGTH = 3; 
    const string TAG_TYPE = "ID3"; 
    const int TAG_MAJOR = 3; 
    const int TAG_MINOR = 0; 
    const int HEADER_SIZE_BEGIN = 6; 
    const int HEADER_SIZE_END = 9; 
    const int EXTENDED_HEADER_POS = 5; 
    const int EXTENDED_HEADER_SIZE_LENGTH = 4; 
    const int FRAME_HEADER_LENGTH = 10; 
    const int FRAME_ID_LENGTH = 4; 
    const string FRAME_MEDIA_PLAYER_OWNER1 = "WM/WMCollectionID"; 
    const string FRAME_MEDIA_PLAYER_OWNER2 = "WM/WMCollectionGroupID"; 
    const string FRAME_MEDIA_PLAYER_ID = "PRIV"; 
    const int FRAME_SIZE_BEGIN = 4; 
    const int FRAME_SIZE_END = 7; 


    bool retValue = false; 
    try 
    { 
     // read in file 
     ifstream infile(filename, ios::binary); 

     infile.seekg(0, ios::beg); 

     char header[HEADER_LENGTH]; 
     infile.read(header, HEADER_LENGTH); 

     string tagType(TAG_INDICATOR_LENGTH, '0'); 
     for (int i = 0; i < TAG_INDICATOR_LENGTH; i++) 
     { 
      tagType[i] = header[i]; 
     } 
     int majorVersion = (int)header[TAG_INDICATOR_LENGTH]; 
     int minorVersion = (int)header[TAG_INDICATOR_LENGTH + 1]; 
     if (tagType == TAG_TYPE && majorVersion == TAG_MAJOR && minorVersion == TAG_MINOR) 
     { 
      // get extended header bit 
      bool extHeader = (header[EXTENDED_HEADER_POS] & 0x0010000); 

      // get size of extended header 
      int extHeaderSize = 0; 
      if (extHeader) 
      { 
       char extHeaderData[EXTENDED_HEADER_SIZE_LENGTH]; 
       infile.seekg(HEADER_LENGTH, ios::beg); 
       infile.read(extHeaderData, EXTENDED_HEADER_SIZE_LENGTH); 
       for (int i = 0; i <= EXTENDED_HEADER_SIZE_LENGTH; i++) 
       { 
        extHeaderSize = extHeaderSize << 8; 
        extHeaderSize |= (unsigned char)extHeaderData[i]; 
       } 
       extHeaderSize += EXTENDED_HEADER_SIZE_LENGTH; 

      } 
      // get size of tag. 
      // 4 bytes with the most significant bit ignored 
      int tagSize = 0; 
      for (int i = HEADER_SIZE_BEGIN; i <= HEADER_SIZE_END; i++) 
      { 
       tagSize = tagSize << 7; 
       tagSize |= (header[i] & 0x7f); 
      } 
      // tagSize includes extended header 
      tagSize += HEADER_LENGTH; 

      // read tags 
      int currPos = HEADER_LENGTH + extHeaderSize; 
      while (currPos < tagSize) 
      { 
       infile.seekg(currPos, ios::beg); 

       char frameHeader[FRAME_HEADER_LENGTH]; 
       infile.read(frameHeader, FRAME_HEADER_LENGTH); 

       // frame id 
       string frameType(FRAME_ID_LENGTH, '0'); 
       for (int i = 0; i < FRAME_ID_LENGTH; i++) 
       { 
        frameType[i] = frameHeader[i]; 
       } 
       // frame length 
       int frameLength = 0; 
       for (int i = FRAME_SIZE_BEGIN; i <= FRAME_SIZE_END; i++) 
       { 
        frameLength = frameLength << 8; 
        frameLength |= (unsigned char)frameHeader[i]; 
       } 
       if (frameType == FRAME_MEDIA_PLAYER_ID) 
       { 
        char* frameData = new char[frameLength]; 
        infile.read(frameData, frameLength); 
        string owner = frameData; 
        if (owner == FRAME_MEDIA_PLAYER_OWNER1 || owner == FRAME_MEDIA_PLAYER_OWNER2) 
        { 
         memcpy(&guid, frameData + owner.length() + 1, sizeof(GUID)); 
         retValue = true; 
        } 
        delete[] frameData; 
       } 

       currPos += FRAME_HEADER_LENGTH + frameLength; 
      } 
      infile.close(); 
     } 
    } 
    catch (...) 
    { 
     retValue = false; 
    } 

    return retValue; 
} 
+0

Исправление: проверка владельца «WM/WMCollectionGroupID» может вызвать проблемы с несколькими CD-альбомами. я просто удалил его, и он, похоже, работает нормально – mike