所以,我的最终游戏是从我的音频文件中获取专辑封面。我正在使用taglib和c ++。我已经找到了有关如何提取嵌入图像数据的信息,但似乎Windows媒体播放器并没有嵌入图像本身。相反,它保存了一个名为AlbumArt_ {E3208100-4FAA-4030-BB9D-6DA5F9D93D18} _Large.jpg的jpg。很明显它使用guid,我相信它保存在PRIV标签中。我对你们的问题是我怎样才能达到目标?我认为这样的事情可能有用:
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 :(得分:0)
对于那些有类似问题的人,据我所知,taglib的PrivateFrame已经坏了。因此,我已经推出了自己的:
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;
}