/*!
*分析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;
}