/*!
*分析M4a文件标签
*第一个参数为文件指针,第二个参数为存储信息的结构体
*/
// add in 2016.11 lxh
BOOL AudioTagParser:: ParseM4aTag(HANDLE hFile, MP3_INFO *pMp3Info){
unsigned char headsize[4] = {0};
unsigned char tagsize[4] = {0};
unsigned char lensize[4] = {0};
unsigned char flag[3] = {0}; //flag[0]--album flag[1]---art flag[2]----end
DWORD bytesRead;
DWORD RealBytes =0;
BOOL ret;
unsigned char cBuf[4] = {0};
unsigned char* pRealBuf = NULL;
ret = ReadFile(hFile, &headsize, sizeof(tagsize), &bytesRead, NULL);//读取头结构的大小
if(!ret || bytesRead != sizeof(cBuf)){
return false;
}
ret = ReadFile(hFile, &cBuf, sizeof(cBuf), &bytesRead, NULL);
if(!ret ||bytesRead != sizeof(cBuf)){
return false;
}
if ( cBuf[0] != \'f\' //固定格式
|| cBuf[1] != \'t\'
|| cBuf[2] != \'y\'
|| cBuf[3] != \'p\'
){
return false;
}
SetFilePointer(hFile, count4_metadata_len((unsigned char*)headsize)-8, 0, FILE_CURRENT);
memset(cBuf, 0, sizeof(cBuf));
while(ReadFile(hFile, &tagsize, sizeof(tagsize), &bytesRead, NULL) &&
ReadFile(hFile, &cBuf, sizeof(cBuf), &bytesRead, NULL)
){
if(bytesRead != sizeof(tagsize)){
break;
}
if ( (cBuf[0]==\'m\' && cBuf[1]==\'o\' && cBuf[2]==\'o\' && cBuf[3]==\'v\') // moov
|| (cBuf[0]==\'t\' && cBuf[1]==\'r\' && cBuf[2]==\'a\' && cBuf[3]==\'k\') // trak
|| (cBuf[0]==\'m\' && cBuf[1]==\'d\' && cBuf[2]==\'i\' && cBuf[3]==\'a\') // mdia
|| (cBuf[0]==\'m\' && cBuf[1]==\'i\' && cBuf[2]==\'n\' && cBuf[3]==\'f\') // minf
|| (cBuf[0]==\'s\' && cBuf[1]==\'t\' && cBuf[2]==\'b\' && cBuf[3]==\'l\') // stbl
|| (cBuf[0]==\'u\' && cBuf[1]==\'d\' && cBuf[2]==\'t\' && cBuf[3]==\'a\') // udta
|| (cBuf[0]==\'i\' && cBuf[1]==\'l\' && cBuf[2]==\'s\' && cBuf[3]==\'t\') // ilst,TAG信息都在这个ATOM之下
){
continue;
}
else if ((cBuf[0]==\'m\' && cBuf[1]==\'e\' && cBuf[2]==\'t\' && cBuf[3]==\'a\')){
SetFilePointer(hFile, 4, 0, FILE_CURRENT);
continue;
}
else if (cBuf[0] == 0xA9){
if (cBuf[1]==\'a\' && cBuf[2]==\'l\' && cBuf[3]==\'b\'){ // 专辑
flag[0] = true;
}
else if (cBuf[1]==\'A\' && cBuf[2]==\'R\' && cBuf[3]==\'T\'){// 艺术家
flag[1] = true;
//SetFilePointer(hFile, count4_metadata_len((unsigned char*)tagsize)-8, 0, FILE_CURRENT);
}
else if (cBuf[1]==\'n\' && cBuf[2]==\'a\' && cBuf[3]==\'m\'){// 名称
SetFilePointer(hFile, count4_metadata_len((unsigned char*)tagsize)-8, 0, FILE_CURRENT);
continue;
}
else if (cBuf[1]==\'d\' && cBuf[2]==\'a\' && cBuf[3]==\'y\'){// 日期
SetFilePointer(hFile, count4_metadata_len((unsigned char*)tagsize)-8, 0, FILE_CURRENT);
continue;
}
if(flag[0] || flag[1]){
if ( ReadFile(hFile, &lensize, sizeof(lensize), &bytesRead, NULL)
&& ReadFile(hFile, &cBuf, sizeof(cBuf), &bytesRead, NULL)
){
if(bytesRead != sizeof(cBuf)){
break;
}
RealBytes = count4_metadata_len((unsigned char*)lensize)- 16;
if( (count4_metadata_len((unsigned char*)lensize)+8) == count4_metadata_len((unsigned char*)tagsize)
&& cBuf[0] == \'d\' && cBuf[1] == \'a\' && cBuf[2] == \'t\' && cBuf[3] == \'a\'
&& RealBytes > 0
){
SetFilePointer(hFile, 8, 0, FILE_CURRENT);
pRealBuf = new unsigned char[RealBytes+1];
if (pRealBuf == NULL){
break;
}
memset(pRealBuf, 0, RealBytes+1);
if(ReadFile(hFile, pRealBuf, RealBytes, &bytesRead, NULL)){
if(bytesRead != RealBytes){
break;
}
if(flag[0]){//获取到了所需要的信息
MultiByteToWideChar(CP_UTF8, 0, (char *)pRealBuf, min(RealBytes, MAX_ID3_SIZE-1), pMp3Info->szAlbum, min(RealBytes, MAX_ID3_SIZE-1));
pMp3Info->szAlbum[MAX_ID3_SIZE-1]=0;
flag[2]++;
flag[0] = 0;
}
if(flag[1]){//获取到了所需要的信息
MultiByteToWideChar(CP_UTF8, 0, (char *)pRealBuf, min(RealBytes, MAX_ID3_SIZE-1), pMp3Info->szArtist, min(RealBytes, MAX_ID3_SIZE-1));
pMp3Info->szArtist[MAX_ID3_SIZE-1]=0;
flag[2]++;
flag[1] = 0;
}
delete[] pRealBuf;
pRealBuf = NULL;
RealBytes = 0;
}
else{
delete[] pRealBuf;
pRealBuf = NULL;
RealBytes = 0;
break;
}
}
}
if(flag[2] == 2){ //gain the info of need end
return true ;
}
}
}
else{
SetFilePointer(hFile, count4_metadata_len((unsigned char*)tagsize)-8, 0, FILE_CURRENT);
}
}
return false;
}