WMA格式文件中的TAG信息格式及解析类
2010-05-15 01:33
411 查看
需要WMA格式的TAG信息,整理了一下,在这里与大家分享一下。
首先介绍下WMA文件头的结构,如下图
/*************************************************************************
// 分为文件头和各个帧数据(文件头前16个字节WMA格式是固定的,8个字节的大小是高位存在后面,以后遇到大小都是高位存在后面)
+--------------------------------------------------------------+
| Header (30 bytes) HeadFlag:16; HeadSize:8; Unknow:6 |
+--------------------------------------------------------------+
| Frames (1....n) |
+--------------------------------------------------------------+
// 所有的TAG信息存放在标准帧和扩展帧中,其他帧可以不予考虑,标准帧以及扩展帧的16个字节标识头都是固定的
// 所有的信息都是UNICODE编码
// 标准帧结构
+--------------------------------------------------------------+
| Header (24 bytes) HeadFlag:16; HeadSize:8; |
+--------------------------------------------------------------+
| 标题信息大小(2 bytes) |
+--------------------------------------------------------------+
| 艺术家信息大小(2 bytes) |
+--------------------------------------------------------------+
| 版权信息大小(2 bytes) |
+--------------------------------------------------------------+
| 备注信息大小(2 bytes) |
+--------------------------------------------------------------+
| 未知信息大小(2 bytes) |
+--------------------------------------------------------------+
| 标题信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 艺术家信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 版权信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 备注信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 未知信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
// 扩展帧结构
+--------------------------------------------------------------+
| Header (24 bytes) HeadFlag:16; HeadSize:8; |
+--------------------------------------------------------------+
| 扩展信息个数EXNO(2 bytes) |
+--------------------------------------------------------------+
| EXINFO (1....EXNO) |
+--------------------------------------------------------------+
// 每个扩展信息EXINFO结构
+--------------------------------------------------------------+
| EXINFO NAME Size (2 bytes) 扩展信息名字大小 |
+--------------------------------------------------------------+
| 扩展信息名称 |
+--------------------------------------------------------------+
| 标志FLAG (2 bytes) |
+--------------------------------------------------------------+
| 值的大小 (2 bytes) |
+--------------------------------------------------------------+
| 实际的值 (若是图片格式参考ID3V2.3) |
+--------------------------------------------------------------+
当扩展信息名字为WMFSDKVersion时,这个值表示的是这个WMA文件的版本;
当扩展信息名字为WM/AlbumTitle时,这个值代表的就是专辑名;
当扩展信息名字为WM/Genre时,这个值代表的就是流派;
下面再来看看那个标志Flag,这个基本上是为没什么用的(通常值为0),
对WM/TrackNumber和WM/Track这两个扩展信息名字有用,
当Flag为3的时候后面的值(也就是曲目信息)是以4个字节的整数的形式表示,
当Flag为0的时候,曲目信息是以普通的字符串形式表示的。
// 查看http://msdn.microsoft.com/en-us/library/ms867702.aspx
=================================================================
贴出实现类头文件:
贴出实现文件:
贴出上面实现中用到存储图片的类头文件:
贴出图片存储类实现文件:
首先介绍下WMA文件头的结构,如下图
/*************************************************************************
// 分为文件头和各个帧数据(文件头前16个字节WMA格式是固定的,8个字节的大小是高位存在后面,以后遇到大小都是高位存在后面)
+--------------------------------------------------------------+
| Header (30 bytes) HeadFlag:16; HeadSize:8; Unknow:6 |
+--------------------------------------------------------------+
| Frames (1....n) |
+--------------------------------------------------------------+
// 所有的TAG信息存放在标准帧和扩展帧中,其他帧可以不予考虑,标准帧以及扩展帧的16个字节标识头都是固定的
// 所有的信息都是UNICODE编码
// 标准帧结构
+--------------------------------------------------------------+
| Header (24 bytes) HeadFlag:16; HeadSize:8; |
+--------------------------------------------------------------+
| 标题信息大小(2 bytes) |
+--------------------------------------------------------------+
| 艺术家信息大小(2 bytes) |
+--------------------------------------------------------------+
| 版权信息大小(2 bytes) |
+--------------------------------------------------------------+
| 备注信息大小(2 bytes) |
+--------------------------------------------------------------+
| 未知信息大小(2 bytes) |
+--------------------------------------------------------------+
| 标题信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 艺术家信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 版权信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 备注信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 未知信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
// 扩展帧结构
+--------------------------------------------------------------+
| Header (24 bytes) HeadFlag:16; HeadSize:8; |
+--------------------------------------------------------------+
| 扩展信息个数EXNO(2 bytes) |
+--------------------------------------------------------------+
| EXINFO (1....EXNO) |
+--------------------------------------------------------------+
// 每个扩展信息EXINFO结构
+--------------------------------------------------------------+
| EXINFO NAME Size (2 bytes) 扩展信息名字大小 |
+--------------------------------------------------------------+
| 扩展信息名称 |
+--------------------------------------------------------------+
| 标志FLAG (2 bytes) |
+--------------------------------------------------------------+
| 值的大小 (2 bytes) |
+--------------------------------------------------------------+
| 实际的值 (若是图片格式参考ID3V2.3) |
+--------------------------------------------------------------+
当扩展信息名字为WMFSDKVersion时,这个值表示的是这个WMA文件的版本;
当扩展信息名字为WM/AlbumTitle时,这个值代表的就是专辑名;
当扩展信息名字为WM/Genre时,这个值代表的就是流派;
下面再来看看那个标志Flag,这个基本上是为没什么用的(通常值为0),
对WM/TrackNumber和WM/Track这两个扩展信息名字有用,
当Flag为3的时候后面的值(也就是曲目信息)是以4个字节的整数的形式表示,
当Flag为0的时候,曲目信息是以普通的字符串形式表示的。
// 查看http://msdn.microsoft.com/en-us/library/ms867702.aspx
=================================================================
贴出实现类头文件:
/******************************************************************** created: 2010/05/14 created: 14:5:2010 9:12 filename: f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyWMATag.h file path: f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG file base: CMyWMATag file ext: h author: zhangwf purpose: 解析WMA格式信息类,提取其中的TAG信息 *********************************************************************/ #ifndef _CMY_WMA_TAG_H_ #define _CMY_WMA_TAG_H_ ////////////////////////////////////////////////////////////////////////// #include "CMyPicInfo.h" #include <string> #include <vector> using namespace std; ////////////////////////////////////////////////////////////////////////// /************************************************************************* // 分为文件头和各个帧数据 +--------------------------------------------------------------+ | Header (30 bytes) HeadFlag:16; HeadSize:8; Unknow:6 | +--------------------------------------------------------------+ | Frames (1....n) | +--------------------------------------------------------------+ // 所有的TAG信息存放在标准帧和扩展帧中,其他帧可以不予考虑 // 所有的信息都是UNICODE编码 // 标准帧结构 +--------------------------------------------------------------+ | Header (24 bytes) HeadFlag:16; HeadSize:8; | +--------------------------------------------------------------+ | 标题信息大小(2 bytes) | +--------------------------------------------------------------+ | 艺术家信息大小(2 bytes) | +--------------------------------------------------------------+ | 版权信息大小(2 bytes) | +--------------------------------------------------------------+ | 备注信息大小(2 bytes) | +--------------------------------------------------------------+ | 未知信息大小(2 bytes) | +--------------------------------------------------------------+ | 标题信息内容(0x00 0x00结束) | +--------------------------------------------------------------+ | 艺术家信息内容(0x00 0x00结束) | +--------------------------------------------------------------+ | 版权信息内容(0x00 0x00结束) | +--------------------------------------------------------------+ | 备注信息内容(0x00 0x00结束) | +--------------------------------------------------------------+ | 未知信息内容(0x00 0x00结束) | +--------------------------------------------------------------+ // 扩展帧结构 +--------------------------------------------------------------+ | Header (24 bytes) HeadFlag:16; HeadSize:8; | +--------------------------------------------------------------+ | 扩展信息个数EXNO(2 bytes) | +--------------------------------------------------------------+ | EXINFO (1....EXNO) | +--------------------------------------------------------------+ // 每个扩展信息EXINFO结构 +--------------------------------------------------------------+ | EXINFO NAME Size (2 bytes) 扩展信息名字大小 | +--------------------------------------------------------------+ | 扩展信息名称 | +--------------------------------------------------------------+ | 标志FLAG (2 bytes) | +--------------------------------------------------------------+ | 值的大小 (2 bytes) | +--------------------------------------------------------------+ | 实际的值 (图片格式参考ID3V2.3) | +--------------------------------------------------------------+ 当扩展信息名字为WMFSDKVersion时,这个值表示的是这个WMA文件的版本; 当扩展信息名字为WM/AlbumTitle时,这个值代表的就是专辑名; 当扩展信息名字为WM/Genre时,这个值代表的就是流派; 下面再来看看那个标志Flag,这个基本上是为没什么用的(通常值为0), 对WM/TrackNumber和WM/Track这两个扩展信息名字有用, 当Flag为3的时候后面的值(也就是曲目信息)是以4个字节的整数的形式表示, 当Flag为0的时候,曲目信息是以普通的字符串形式表示的。 // 查看http://msdn.microsoft.com/en-us/library/ms867702.aspx Author Copyright Description Rating Title WM/AlbumArtist WM/AlbumCoverURL WM/AlbumTitle WM/AudioFileURL WM/AudioSourceURL WM/AuthorURL WM/BeatsPerMinute WM/Category WM/Composer WM/Conductor WM/ContentDistributor WM/ContentGroupDescription WM/Director WM/DVDID WM/EncodedBy WM/EncodingSettings WM/EncodingTime WM/Genre WM/GenreID WM/InitialKey WM/ISRC WM/Language WM/Lyrics WM/Lyrics_Synchronised WM/MCDI WM/MediaClassPrimaryID WM/MediaClassSecondaryID WM/MediaCredits WM/MediaIsDelay WM/MediaIsFinale WM/MediaIsLive WM/MediaIsPremiere WM/MediaIsRepeat WM/MediaIsSAP WM/MediaIsSubtitled WM/MediaIsStereo WM/MediaNetworkAffiliation WM/MediaOriginalBroadcastDateTime WM/MediaOriginalChannel WM/MediaStationCallSign WM/MediaStationName WM/ModifiedBy WM/Mood WM/OriginalAlbumTitle WM/OriginalArtist WM/OriginalFilename WM/OriginalLyricist WM/OriginalReleaseTime WM/OriginalReleaseYear WM/ParentalRating WM/ParentalRatingReason WM/PartOfSet WM/Period WM/Picture WM/Producer WM/PromotionURL WM/Provider WM/ProviderCopyright WM/ProviderRating WM/ProviderStyle WM/Publisher WM/RadioStationName WM/RadioStationOwner WM/SharedUserRating WM/SubTitle WM/SubTitleDescription WM/Text WM/ToolName WM/ToolVersion WM/Track WM/TrackNumber WM/UniqueFileIdentifier WM/UserWebURL WM/WMCollectionGroupID WM/WMCollectionID WM/WMContentID WM/Writer WM/Year WMFSDKVersion WMFSDKNeeded IsVBR *************************************************************************/ ////////////////////////////////////////////////////////////////////////// // 定义帧类型 enum WMA_FRAMESTYLE_T { WMA_FRAMESTYLE_STANDARD, // 标准帧 WMA_FRAMESTYLE_EXTEND, // 扩展帧 WMA_FRAMESTYLE_UNKNOWN, // 未知帧 }; // 定义帧标识类型ID enum WMA_FRAMEID_T { // 基础类型标准帧中的内容 WMA_FRAMEID_AUTHOR = 0, WMA_FRAMEID_COPYRIGHT, WMA_FRAMEID_DESCRIPTION, WMA_FRAMEID_RATING, WMA_FRAMEID_TITLE, // 其他类型按字母排序 WMA_FRAMEID_ALBUMARTIST, WMA_FRAMEID_ALBUMCOVERURL, WMA_FRAMEID_ALBUMTITLE, WMA_FRAMEID_AUDIOFILEURL, WMA_FRAMEID_AUDIOSOURCEURL, WMA_FRAMEID_AUTHORURL, WMA_FRAMEID_BPMT, // WM/BeatsPerMinute WMA_FRAMEID_CATEGORY, WMA_FRAMEID_COMPOSER, WMA_FRAMEID_CONDUCTOR, WMA_FRAMEID_CONTENTDISTRIBUTOR, WMA_FRAMEID_CGDPN, // WM/ContentGroupDescription WMA_FRAMEID_DIRECTOR, WMA_FRAMEID_DVDID, WMA_FRAMEID_ENCODEDBY, WMA_FRAMEID_ENCODINGSETTINGS, WMA_FRAMEID_ENCODINGTIME, WMA_FRAMEID_GENRE, WMA_FRAMEID_GENREID, WMA_FRAMEID_INITIALKEY, WMA_FRAMEID_ISRC, WMA_FRAMEID_LANGUAGE, WMA_FRAMEID_LYRICS, WMA_FRAMEID_LYRICSSYNC, // WM/Lyrics_Synchronised WMA_FRAMEID_MCDI, WMA_FRAMEID_MCPID, // WM/MediaClassPrimaryID WMA_FRAMEID_MCSID, // WM/MediaClassSecondaryID WMA_FRAMEID_MDACREDITS, // WM/MediaCredits WMA_FRAMEID_MDAISDELAY, // WM/MediaIsDelay WMA_FRAMEID_MDAISFINALE, // WM/MediaIsFinale WMA_FRAMEID_MDAISLIVE, // WM/MediaIsLive WMA_FRAMEID_MDAISPREMIERE, // WM/MediaIsPremiere WMA_FRAMEID_MDAISREPEAT, // WM/MediaIsRepeat WMA_FRAMEID_MDAISSAP, // WM/MediaIsSAP WMA_FRAMEID_MDAISSUBTITLED, // WM/MediaIsSubtitled WMA_FRAMEID_MDAISSTEREO, // WM/MediaIsStereo WMA_FRAMEID_MDANETWORKAFFILIATION, // WM/MediaNetworkAffiliation WMA_FRAMEID_MDAORIGINALBDT, // WM/MediaOriginalBroadcastDateTime WMA_FRAMEID_MDAORIGINALCHANNEL, // WM/MediaOriginalChannel WMA_FRAMEID_MDASTATIONCALLSIGN, // WM/MediaStationCallSign WMA_FRAMEID_MDASTATIONNAME, // WM/MediaStationName WMA_FRAMEID_MODIFIEDBY, WMA_FRAMEID_MOOD, WMA_FRAMEID_ORIGALBUMTITLE, // WM/OriginalAlbumTitle WMA_FRAMEID_ORIGARTIST, // WM/OriginalArtist WMA_FRAMEID_ORIGFILENAME, // WM/OriginalFilename WMA_FRAMEID_ORIGLYRICIST, // WM/OriginalLyricist WMA_FRAMEID_ORIGRELEASETIME, // WM/OriginalReleaseTime WMA_FRAMEID_ORIGRELEASEYEAR, // WM/OriginalReleaseYear WMA_FRAMEID_PARENTALRATING, WMA_FRAMEID_PARENTALRATINGREASON, // WM/ParentalRatingReason WMA_FRAMEID_PARTOFSET, WMA_FRAMEID_PERIOD, WMA_FRAMEID_PICTURE, WMA_FRAMEID_PRODUCER, WMA_FRAMEID_PROMOTIONURL, WMA_FRAMEID_PROVIDER, WMA_FRAMEID_PROVIDERCPYRIGHT, WMA_FRAMEID_PROVIDERRATING, WMA_FRAMEID_PROVIDERSTYLE, WMA_FRAMEID_PUBLISHER, WMA_FRAMEID_RADIOSTATIONNAME, WMA_FRAMEID_RADIOSTATIONOWNER, WMA_FRAMEID_SHAREUSERRATING, WMA_FRAMEID_SUBTITLE, WMA_FRAMEID_SUBTITLEDESCRIPTION, WMA_FRAMEID_TEXT, WMA_FRAMEID_TOOLNAME, WMA_FRAMEID_TOOLVERSION, WMA_FRAMEID_TRACK, WMA_FRAMEID_TRACKNUMBER, WMA_FRAMEID_UNIQUEFILEIDENTIFIER, WMA_FRAMEID_USERWEBURL, WMA_FRAMEID_WMCOLLECTIONGROUPID, WMA_FRAMEID_WMCOLLECTIONID, WMA_FRAMEID_CONTENTID, WMA_FRAMEID_WRITER, WMA_FRAMEID_YEAR, WMA_FRAMEID_SDKVERSION, // WMFSDKVersion WMA_FRAMEID_SDKNEEDED, // WMFSDKNeeded WMA_FRAMEID_ISVBR, // IsVBR //////////////////////////////////////////////////////////////////// WMA_FRAMEID_UNKNOWN, // 未知 }; ////////////////////////////////////////////////////////////////////////// // 定义WMA文件头标识 typedef struct _WMA_HEADFLAG_INFO_ { unsigned char WmaFlag[16]; // 固定的16个字节内容表示是否WMA文件 }WMAHEADFLAG; // 定义WMA文件头常量标识 const WMAHEADFLAG WMA_HEAD_FLAGCONST = {0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}; // 定义WMA文件头大小 typedef struct _WMA_HEADSIZE_INFO_ { unsigned char Size[8]; // 8个字节表示大小(由后向前存储数据) }WMAHEADSIZE; // 定义WMA文件头结构 typedef struct _WMA_HEADINFO_ { WMAHEADFLAG HeadFlag; // WMA文件标识 WMAHEADSIZE HeadSize; // WMA文件头大小 unsigned char Unknown[6]; // 6个字节具体代表什么不清楚(有的说是帧的数量) }WMAHEADINFO; // 定义帧头标识 typedef struct _WMA_FRAMEHEADFLAG_INFO_ { unsigned char Flag[16]; // 固定的16个字节表示帧类型 }WMAFRAMEHEADFLAG; // 定义WMA标准帧及扩展帧常量标识 const WMAFRAMEHEADFLAG WMA_FRAMEHEAD_STANDARD = {0x33, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}; const WMAFRAMEHEADFLAG WMA_FRAMEHEAD_EXTEND = {0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50}; // 定义帧大小 typedef struct _WMA_FRAMEHEADSIZE_INFO_ { unsigned char Size[8]; // 8个字节表示帧大小(由后向前存储数据) }WMAFRAMEHEADSIZE; // 定义帧头结构 typedef struct _WMA_FRAMEHEAD_INFO_ { WMAFRAMEHEADFLAG FrameFlag; WMAFRAMEHEADSIZE FrameSize; }WMAFRAMEHEADINFO; // 定义解析值的类型 enum WMA_ATTRSTYLE_T { WMA_ATTRSTYLE_TXT = 0, // 字符串属性 WMA_ATTRSTYLE_VAL, // 值属性 }; // 定义属性解析内容结构 typedef struct _WMA_ATTR_INFO_ { WMA_FRAMEID_T ID; // ID表示解析的类型 WMA_ATTRSTYLE_T AttrStyle; // 值的类型 wstring StrContent; // 解析的TXT内容 unsigned long ValContent; // 解析的值内容 }WMAATTRINFO; // 定义属性解析内容动态数组存放解析的内容 typedef vector<WMAATTRINFO> CWMAAttrArray; // 定义图片解析内容结构 typedef struct _WMA_PICITEMINFO_ { wstring MimeType; // "image/png" or "image/jpeg" char PicType; // 说明如下 wstring Description; // 图片描述 CMYPICINFO PicData; // 图片数据 }WMAPICITEMINFO; // 定义PIC属性解析内容动态数组存放解析的内容(可能含有多张图片) typedef vector<WMAPICITEMINFO> CWMAPicArray; ////////////////////////////////////////////////////////////////////////// class CMyWMATag { public: // 构造函数 CMyWMATag(); // 析构函数 ~CMyWMATag(); public: // 接口函数 // 解析WMA文件,成功后调用下面接口获取信息 bool AnalyzeWMAFile(const char *filePathName); bool AnalyzeWMAFile(const wchar_t *filePathName); bool AnalyzeWMAFile(const wstring &filePathName); // 是否解析成功 bool BeSuccess(); // 取得头大小 unsigned long GetHeadSize(); ////////////////////////////////////////////////////////////////////////// // 取得Txt属性内容接口 bool GetTxtItemContent(WMA_FRAMEID_T frameID, wstring &itemContent); bool GetTxtItemContent(WMA_FRAMEID_T frameID, string &itemContent); ////////////////////////////////////////////////////////////////////////// // 取得图片属性内容接口 // 取得第一张图片 bool GetFirstPic(CMYPICINFO &picInfo); // 保存第一张图片 bool SaveFirstPicToFile(const char *filePathName); bool SaveFirstPicToFile(const wchar_t *filePathName); // 取得第一张图片的地址及大小 const unsigned char* GetFirstPicAddr(unsigned long *pPicSize=NULL); // 取得第一行图片的大小 unsigned long GetFirstPicSize(); // 取得图片数量 unsigned long GetPicCounts(); // 取得第n张图片 bool GetPic(unsigned long picIndex, CMYPICINFO &picInfo); // 取得第n张图片的地址 const unsigned char* GetPicAddr(unsigned long picIndex, unsigned long *pPicSize=NULL); // 保存第n张图片 bool SavePicToFile(unsigned long picIndex, const char *filePathName); bool SavePicToFile(unsigned long picIndex, const wchar_t *filePathName); private: // 私有函数 // 根据文件头结构判断是否WMA文件 bool BeWMAFile(const WMAHEADFLAG &headFlag); // 清除信息 void ClearDataInfo(); // 计算头大小 unsigned long GetHeadSize(const WMAHEADSIZE &headSize); // 得到帧类型 WMA_FRAMESTYLE_T GetFrameStyle(const WMAFRAMEHEADFLAG &frameFlag); // 判断两个帧头标识是否相等 bool BeSameFrameFlag(const WMAFRAMEHEADFLAG &firstFlag, const WMAFRAMEHEADFLAG &secondFlag); // 得到帧的大小 unsigned long GetFrameSize(const WMAFRAMEHEADSIZE &frameSize); // 计算由2个字节拼接成的整数大小 unsigned long CalUInt16Val(const unsigned char *pByteBuf, int bufSize); // 计算由4个字节拼接成的整数大小 unsigned long CalUInt32Val(const unsigned char *pByteBuf, int bufSize); // 解析得到的帧数据 unsigned long ParseFrameData(const unsigned char *pFrameData, unsigned long bufLength); // 得到帧头信息 bool GetFrameHeadInfo(const unsigned char *pFrameData, unsigned long bufLength, WMAFRAMEHEADINFO &frameHead); // 解析标准帧数据 bool ParseStandardFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray); // 解析扩展帧数据 bool ParseExtendFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray, CWMAPicArray &WMAPicArray); // 得到string wstring GetWString(const unsigned char* pUCharBuf, unsigned long charsNums); // wstring转换为string string TransFromWString(const wstring &wstrVal); // 取得扩展帧属性ID WMA_FRAMEID_T GetExFrameID(const wstring &exName); // 取得字符串根据0x00,0x00 unsigned long GetWstringByWChars(const unsigned char* pPicDataBuf, unsigned long bufSize, wstring &strVal); private: // 成员变量 WMAHEADINFO m_HeadInfo; // 存放头信息 bool m_bAnalyzeSuccess; // 保存解析是否成功 CWMAAttrArray m_WMAAttrArray; // 存放解析到的TAG信息 CWMAPicArray m_WMAPicArray; // 存放解析的图片信息 }; ////////////////////////////////////////////////////////////////////////// #endif
贴出实现文件:
/******************************************************************** created: 2010/05/14 created: 14:5:2010 9:12 filename: f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyWMATag.cpp file path: f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG file base: CMyWMATag file ext: cpp author: zhangwf purpose: 解析WMA格式信息类,提取其中的TAG信息 *********************************************************************/ ////////////////////////////////////////////////////////////////////////// #include <Windows.h> #include "CMyWMATag.h" ////////////////////////////////////////////////////////////////////////// // 构造函数 CMyWMATag::CMyWMATag() { // 初始化成员变量 ClearDataInfo(); } // 析构函数 CMyWMATag::~CMyWMATag() { } ////////////////////////////////////////////////////////////////////////// // 接口函数 // 解析WMA文件,成功后调用下面接口获取信息 bool CMyWMATag::AnalyzeWMAFile(const char *filePathName) { // 清除上次信息 ClearDataInfo(); // 参数有效性 if (filePathName == NULL) { return false; } // 打开文件 FILE *pWMAFile = fopen(filePathName, "rb"); if (pWMAFile == NULL) { return false; } // 读取WMA头结构 memset(&m_HeadInfo, 0, sizeof(m_HeadInfo)); if (fread(&m_HeadInfo, sizeof(m_HeadInfo), 1, pWMAFile) != 1) { fclose(pWMAFile); return false; } // 判断是否WMA文件 m_bAnalyzeSuccess = BeWMAFile(m_HeadInfo.HeadFlag); if (!m_bAnalyzeSuccess) { memset(&m_HeadInfo, 0, sizeof(m_HeadInfo)); fclose(pWMAFile); return false; } // 计算要读取帧数据的字节数 unsigned long lFrameDataSize = GetHeadSize(m_HeadInfo.HeadSize) - sizeof(WMAHEADINFO); // 为帧数据分配空间 unsigned char *pFrameData = new unsigned char[lFrameDataSize]; if (pFrameData == NULL) { fclose(pWMAFile); m_bAnalyzeSuccess = false; return false; } // 读取帧数据 memset(pFrameData, 0, lFrameDataSize); if (fread(pFrameData, lFrameDataSize, 1, pWMAFile) != 1) { // 释放帧数据 if (pFrameData != NULL) { delete[] pFrameData; pFrameData = NULL; } fclose(pWMAFile); m_bAnalyzeSuccess = false; return false; } // 读取成功关闭文件 fclose(pWMAFile); // 解析帧数据 ParseFrameData(pFrameData, lFrameDataSize); // 释放帧数据 if (pFrameData != NULL) { delete[] pFrameData; pFrameData = NULL; } // 返回分析结果 return m_bAnalyzeSuccess; } // 解析WMA文件 bool CMyWMATag::AnalyzeWMAFile(const wchar_t *filePathName) { // 参数有效性 if (filePathName == NULL) { return false; } // 计算转换为多字节字节数 int nChars = WideCharToMultiByte(CP_ACP, 0, filePathName, -1, NULL, 0, NULL, NULL); // 申请空间 char *pFileName = new char[nChars+1]; if (pFileName == NULL) { return false; } // 转换为多字节 memset(pFileName, 0, nChars+1); WideCharToMultiByte(CP_ACP, 0, filePathName, -1, pFileName, nChars, NULL, NULL); // 解析 bool bResult = AnalyzeWMAFile(pFileName); // 释放 if (pFileName != NULL) { delete[] pFileName; pFileName = NULL; } // 返回结果 return bResult; } // 解析WMA文件 bool CMyWMATag::AnalyzeWMAFile(const wstring &filePathName) { return AnalyzeWMAFile(filePathName.c_str()); } // 是否解析成功 bool CMyWMATag::BeSuccess() { return m_bAnalyzeSuccess; } // 取得头大小 unsigned long CMyWMATag::GetHeadSize() { return GetHeadSize(m_HeadInfo.HeadSize); } ////////////////////////////////////////////////////////////////////////// // 取得Txt属性内容接口 bool CMyWMATag::GetTxtItemContent(WMA_FRAMEID_T frameID, wstring &itemContent) { // 解析失败 if (!BeSuccess()) { return false; } // 查找 for (unsigned long i=0; i<m_WMAAttrArray.size(); i++) { if (frameID == m_WMAAttrArray[i].ID) { if (m_WMAAttrArray[i].AttrStyle == WMA_ATTRSTYLE_TXT) { itemContent = m_WMAAttrArray[i].StrContent; return true; } else { return false; } } } // 没有找到 return false; } // 取得Txt属性内容接口 bool CMyWMATag::GetTxtItemContent(WMA_FRAMEID_T frameID, string &itemContent) { wstring wContent; bool bOK = GetTxtItemContent(frameID, wContent); itemContent = TransFromWString(wContent); return bOK; } ////////////////////////////////////////////////////////////////////////// // 取得图片属性内容接口 // 取得第一张图片 bool CMyWMATag::GetFirstPic(CMYPICINFO &picInfo) { // 解析失败 if (!BeSuccess()) { return false; } // 查找是否有图片 if (m_WMAPicArray.size() == 0) { return false; } // 得到第一张图片 picInfo = m_WMAPicArray[0].PicData; return true; } // 保存第一张图片 bool CMyWMATag::SaveFirstPicToFile(const char *filePathName) { if (BeSuccess() && m_WMAPicArray.size()>0) { return m_WMAPicArray[0].PicData.SavePicToFile(filePathName); } return false; } bool CMyWMATag::SaveFirstPicToFile(const wchar_t *filePathName) { if (BeSuccess() && m_WMAPicArray.size()>0) { return m_WMAPicArray[0].PicData.SavePicToFile(filePathName); } return false; } // 取得第一张图片的地址及大小 const unsigned char* CMyWMATag::GetFirstPicAddr(unsigned long *pPicSize) { if (BeSuccess() && m_WMAPicArray.size()>0) { if (pPicSize != NULL) { *pPicSize = m_WMAPicArray[0].PicData.GetPicBufSize(); } return m_WMAPicArray[0].PicData.GetPicBufAddr(); } return NULL; } // 取得第一行图片的大小 unsigned long CMyWMATag::GetFirstPicSize() { if (BeSuccess() && m_WMAPicArray.size()>0) { return m_WMAPicArray[0].PicData.GetPicBufSize(); } return 0; } // 取得图片数量 unsigned long CMyWMATag::GetPicCounts() { return (unsigned long)m_WMAPicArray.size(); } // 取得第n张图片 bool CMyWMATag::GetPic(unsigned long picIndex, CMYPICINFO &picInfo) { // 解析失败 if (!BeSuccess()) { return false; } // 得到图片数量 unsigned long picCounts = GetPicCounts(); // 查找是否有图片 if (picCounts == 0) { return false; } // 索引是否有效 if (picIndex >= picCounts) { return false; } // 得到第picIndex张图片 picInfo = m_WMAPicArray[picIndex].PicData; return true; } // 取得第n张图片的地址 const unsigned char* CMyWMATag::GetPicAddr(unsigned long picIndex, unsigned long *pPicSize) { // 解析失败 if (!BeSuccess()) { return NULL; } // 得到图片数量 unsigned long picCounts = GetPicCounts(); // 查找是否有图片 if (picCounts == 0) { return NULL; } // 索引是否有效 if (picIndex >= picCounts) { return NULL; } // 取得图片大小 if (pPicSize != NULL) { *pPicSize = m_WMAPicArray[picIndex].PicData.GetPicBufSize(); } // 得到第picIndex张图片地址 return m_WMAPicArray[picIndex].PicData.GetPicBufAddr(); } // 保存第n张图片 bool CMyWMATag::SavePicToFile(unsigned long picIndex, const char *filePathName) { // 参数有效性 if (filePathName == NULL) { return false; } // 解析失败 if (!BeSuccess()) { return false; } // 得到图片数量 unsigned long picCounts = GetPicCounts(); // 查找是否有图片 if (picCounts == 0) { return false; } // 索引是否有效 if (picIndex >= picCounts) { return false; } return m_WMAPicArray[picIndex].PicData.SavePicToFile(filePathName); } // 保存第n张图片 bool CMyWMATag::SavePicToFile(unsigned long picIndex, const wchar_t *filePathName) { // 参数有效性 if (filePathName == NULL) { return false; } // 解析失败 if (!BeSuccess()) { return false; } // 得到图片数量 unsigned long picCounts = GetPicCounts(); // 查找是否有图片 if (picCounts == 0) { return false; } // 索引是否有效 if (picIndex >= picCounts) { return false; } return m_WMAPicArray[picIndex].PicData.SavePicToFile(filePathName); } ////////////////////////////////////////////////////////////////////////// // 私有函数 // 根据文件头结构判断是否WMA文件 bool CMyWMATag::BeWMAFile(const WMAHEADFLAG &headFlag) { for (int i=0; i<sizeof(WMA_HEAD_FLAGCONST.WmaFlag); i++) { if (headFlag.WmaFlag[i] != WMA_HEAD_FLAGCONST.WmaFlag[i]) { return false; } } return true; } // 清除信息 void CMyWMATag::ClearDataInfo() { memset(&m_HeadInfo, 0, sizeof(m_HeadInfo)); m_bAnalyzeSuccess = false; m_WMAAttrArray.clear(); m_WMAPicArray.clear(); } // 计算头大小 unsigned long CMyWMATag::GetHeadSize(const WMAHEADSIZE &headSize) { return (unsigned long)((headSize.Size[3]<<24) | (headSize.Size[2]<<16) | (headSize.Size[1]<<8) | headSize.Size[0]); } // 得到帧类型 WMA_FRAMESTYLE_T CMyWMATag::GetFrameStyle(const WMAFRAMEHEADFLAG &frameFlag) { // 判断是否标准帧 if (BeSameFrameFlag(frameFlag, WMA_FRAMEHEAD_STANDARD)) { return WMA_FRAMESTYLE_STANDARD; } // 判断是否扩展帧 if (BeSameFrameFlag(frameFlag, WMA_FRAMEHEAD_EXTEND)) { return WMA_FRAMESTYLE_EXTEND; } // 返回位置帧 return WMA_FRAMESTYLE_UNKNOWN; } // 判断两个帧头标识是否相等 bool CMyWMATag::BeSameFrameFlag(const WMAFRAMEHEADFLAG &firstFlag, const WMAFRAMEHEADFLAG &secondFlag) { for (int i=0; i<16; i++) { if (firstFlag.Flag[i] != secondFlag.Flag[i]) { return false; } } return true; } // 得到帧的大小 unsigned long CMyWMATag::GetFrameSize(const WMAFRAMEHEADSIZE &frameSize) { return (unsigned long)((frameSize.Size[3]<<24) | (frameSize.Size[2]<<16) | (frameSize.Size[1]<<8) | frameSize.Size[0]); } // 计算由2个字节拼接成的整数大小 unsigned long CMyWMATag::CalUInt16Val(const unsigned char *pByteBuf, int bufSize) { // 参数有效性 if (pByteBuf==NULL || bufSize<2) { return 0; } // 返回值 return ((pByteBuf[1]<<8) | pByteBuf[0]); } // 计算由4个字节拼接成的整数大小 unsigned long CMyWMATag::CalUInt32Val(const unsigned char *pByteBuf, int bufSize) { // 参数有效性 if (pByteBuf==NULL || bufSize<4) { return 0; } // 返回值 return ((pByteBuf[3]<<24) | (pByteBuf[2]<<16) | (pByteBuf[1]<<8) | pByteBuf[0]); } // 解析得到的帧数据 unsigned long CMyWMATag::ParseFrameData(const unsigned char *pFrameData, unsigned long bufLength) { // 清除上次数据 m_WMAAttrArray.clear(); m_WMAPicArray.clear(); // 参数有效性 if (pFrameData==NULL || bufLength==0) { return 0; } // 存放临时变量 WMAFRAMEHEADINFO frameHead; WMA_FRAMESTYLE_T frameStyle = WMA_FRAMESTYLE_UNKNOWN; unsigned long frameSize = 0; WMAATTRINFO attrItemInfo; // 遍历解析内容 unsigned long pos = 0; while (pos+24 < bufLength) { // 得到帧头失败 if (!GetFrameHeadInfo(pFrameData+pos, bufLength-pos, frameHead)) { break; } // 得到帧风格类型 frameStyle = GetFrameStyle(frameHead.FrameFlag); // 是正确风格,取得帧大小 frameSize = GetFrameSize(frameHead.FrameSize); // 取得帧体内容 if (frameSize>=24 && pos+23+frameSize<bufLength) { // 是标准帧,解析标准帧 if (frameStyle == WMA_FRAMESTYLE_STANDARD) { ParseStandardFrame(pFrameData+pos+24, frameSize-24, m_WMAAttrArray); } // 是扩展帧 else if (frameStyle == WMA_FRAMESTYLE_EXTEND) { ParseExtendFrame(pFrameData+pos+24, frameSize-24, m_WMAAttrArray, m_WMAPicArray); } // 改变索引 pos += frameSize; } else { pos++; } } for (unsigned int i=0; i<m_WMAAttrArray.size(); i++) { printf("ID:%d Content:%s/n", m_WMAAttrArray[i].ID, TransFromWString(m_WMAAttrArray[i].StrContent).c_str()); } // 返回解析的属性数量 return (unsigned long)m_WMAAttrArray.size() + (unsigned long)m_WMAPicArray.size(); } // 得到帧头信息 bool CMyWMATag::GetFrameHeadInfo(const unsigned char *pFrameData, unsigned long bufLength, WMAFRAMEHEADINFO &frameHead) { // 参数有效性 if (pFrameData==NULL || bufLength<24) { return false; } // 得到帧标识 int i = 0; for (i=0; i<16; i++) { frameHead.FrameFlag.Flag[i] = pFrameData[i]; } // 得到帧大小 for (i=0; i<8; i++) { frameHead.FrameSize.Size[i] = pFrameData[i+16]; } return true; } // 解析标准帧数据 bool CMyWMATag::ParseStandardFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray) { // 参数有效性 if (pItemFrameData==NULL || frameSize==0) { return false; } // 计算标题信息大小 unsigned long titleSize = CalUInt16Val(pItemFrameData, 2); // 计算艺术家信息大小 unsigned long artistSize = CalUInt16Val(pItemFrameData+2, 2); // 计算版权信息大小 unsigned long copyRightSize = CalUInt16Val(pItemFrameData+4, 2); // 计算备注信息大小 unsigned long commentSize = CalUInt16Val(pItemFrameData+6, 2); // 计算未知信息大小 unsigned long unknownSize = CalUInt16Val(pItemFrameData+8, 2); // 偏移量 unsigned long offset = 10; // 临时存放信息 WMAATTRINFO attrInfo; memset(&attrInfo, 0, sizeof(attrInfo)); attrInfo.AttrStyle = WMA_ATTRSTYLE_TXT; // 取得标题信息 attrInfo.ID = WMA_FRAMEID_TITLE; attrInfo.StrContent = GetWString(pItemFrameData+offset, titleSize); WMAAttrArray.push_back(attrInfo); offset += titleSize; // 取得艺术家信息 attrInfo.ID = WMA_FRAMEID_AUTHOR; attrInfo.StrContent = GetWString(pItemFrameData+offset, artistSize); WMAAttrArray.push_back(attrInfo); offset += artistSize; // 取得版权信息 attrInfo.ID = WMA_FRAMEID_COPYRIGHT; attrInfo.StrContent = GetWString(pItemFrameData+offset, copyRightSize); WMAAttrArray.push_back(attrInfo); offset += copyRightSize; // 取得备注信息 attrInfo.ID = WMA_FRAMEID_DESCRIPTION; attrInfo.StrContent = GetWString(pItemFrameData+offset, commentSize); WMAAttrArray.push_back(attrInfo); offset += commentSize; // 取得未知信息 attrInfo.ID = WMA_FRAMEID_RATING; attrInfo.StrContent = GetWString(pItemFrameData+offset, unknownSize); WMAAttrArray.push_back(attrInfo); offset += unknownSize; // 返回成功 return true; } // 得到string wstring CMyWMATag::GetWString(const unsigned char* pUCharBuf, unsigned long charsNums) { // 返回值 wstring strRet = L""; // 参数有效性 if (pUCharBuf==NULL || charsNums==0) { return strRet; } // 得到字符串 strRet.append((const wchar_t*)pUCharBuf, charsNums/2); return strRet; } // wstring转换为string string CMyWMATag::TransFromWString(const wstring &wstrVal) { // 计算字符数 int nCharNums = (int)wstrVal.length(); int mulBufSize = 2*nCharNums+10; // 申请空间 char *pCharBuf = new char[mulBufSize]; if (pCharBuf == NULL) { return ""; } memset(pCharBuf, 0, mulBufSize); // 转换 WideCharToMultiByte(CP_ACP, 0, wstrVal.c_str(), -1, pCharBuf, mulBufSize, NULL, NULL); // 得到结果 string strVal(pCharBuf); // 释放空间 if (pCharBuf != NULL) { delete[] pCharBuf; pCharBuf = NULL; } return strVal; } // 解析扩展帧数据 bool CMyWMATag::ParseExtendFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray, CWMAPicArray &WMAPicArray) { // 参数有效性 if (pItemFrameData==NULL || frameSize==0) { return false; } // 计算扩展信息数量 unsigned long exInfoCounts = CalUInt16Val(pItemFrameData, 2); // 地址偏移量 unsigned long offset = 2; // 临时存放扩展信息 unsigned long exNameSize = 0; wstring exName = L""; unsigned long exFlagVal = 0; unsigned long valSize = 0; WMA_FRAMEID_T frameID = WMA_FRAMEID_UNKNOWN; WMAATTRINFO attrInfo; WMAPICITEMINFO picItem; unsigned lenTmp = 0; // 取扩展信息 for (unsigned exIndex=0; exIndex<exInfoCounts; exIndex++) { // 清除上次内容 memset(&attrInfo, 0, sizeof(attrInfo)); // 计算扩展名大小 exNameSize = CalUInt16Val(pItemFrameData+offset, 2); offset += 2; // 取得扩展名称 exName = GetWString(pItemFrameData+offset, exNameSize); offset += exNameSize; // 取得扩展标识FLAG值 exFlagVal = CalUInt16Val(pItemFrameData+offset, 2); offset += 2; // 取得实际值的大小 valSize = CalUInt16Val(pItemFrameData+offset, 2); offset += 2; // 计算扩展属性ID frameID = GetExFrameID(exName); // 是否有效ID if (frameID != WMA_FRAMEID_UNKNOWN) { // 得到属性ID attrInfo.ID = frameID; // 图片得到图片信息 if (frameID == WMA_FRAMEID_PICTURE) { lenTmp = GetWstringByWChars(pItemFrameData+offset, frameSize-offset, picItem.MimeType); picItem.PicType = (char)((pItemFrameData+offset+lenTmp)[0]); lenTmp += 1; lenTmp += GetWstringByWChars(pItemFrameData+offset+lenTmp, frameSize-offset-lenTmp, picItem.Description); picItem.PicData.SetPicBufData((const char*)(pItemFrameData+offset+lenTmp), valSize-lenTmp); m_WMAPicArray.push_back(picItem); } else { // 扩展FLAG标识是字符串类型还是值类型 // 表示值类型 if (exFlagVal == 3) { attrInfo.AttrStyle = WMA_ATTRSTYLE_VAL; if (valSize >= 4) { attrInfo.ValContent = CalUInt32Val(pItemFrameData+offset, 4); } WMAAttrArray.push_back(attrInfo); } else { attrInfo.AttrStyle = WMA_ATTRSTYLE_TXT; attrInfo.StrContent = GetWString(pItemFrameData+offset, valSize); WMAAttrArray.push_back(attrInfo); } } } // 改变地址偏移量 offset += valSize; } // 返回成功 return true; } // 取得字符串根据0x00,0x00 unsigned long CMyWMATag::GetWstringByWChars(const unsigned char* pPicDataBuf, unsigned long bufSize, wstring &strVal) { // 返回数量 unsigned long lResult = 0; // 参数有效性 if (pPicDataBuf==NULL || bufSize==0) { return lResult; } // 遍历 const wchar_t *pWBuf = (const wchar_t*)pPicDataBuf; unsigned long wBufSize = bufSize/2; unsigned long wPos = 0; while (wPos < wBufSize) { if (pWBuf[wPos] == 0x00) { lResult = 2*(wPos+1); break; } else { wPos++; } } // 得到字符串 strVal = L""; strVal.append(pWBuf, wPos+1); // 返回 return lResult; } // 取得扩展帧属性ID WMA_FRAMEID_T CMyWMATag::GetExFrameID(const wstring &exName) { // 用于返回值 WMA_FRAMEID_T rtExFrameID = WMA_FRAMEID_UNKNOWN; // 与标识比较 if (wcscmp(exName.c_str(), L"WM/AlbumArtist") == 0) { rtExFrameID = WMA_FRAMEID_ALBUMARTIST; } else if (wcscmp(exName.c_str(), L"WM/AlbumCoverURL") == 0) { rtExFrameID = WMA_FRAMEID_ALBUMCOVERURL; } else if (wcscmp(exName.c_str(), L"WM/AlbumTitle") == 0) { rtExFrameID = WMA_FRAMEID_ALBUMTITLE; } else if (wcscmp(exName.c_str(), L"WM/AudioFileURL") == 0) { rtExFrameID = WMA_FRAMEID_AUDIOFILEURL; } else if (wcscmp(exName.c_str(), L"WM/AudioSourceURL") == 0) { rtExFrameID = WMA_FRAMEID_AUDIOSOURCEURL; } else if (wcscmp(exName.c_str(), L"WM/AuthorURL") == 0) { rtExFrameID = WMA_FRAMEID_AUTHORURL; } else if (wcscmp(exName.c_str(), L"WM/BeatsPerMinute") == 0) { rtExFrameID = WMA_FRAMEID_BPMT; } else if (wcscmp(exName.c_str(), L"WM/Category") == 0) { rtExFrameID = WMA_FRAMEID_CATEGORY; } else if (wcscmp(exName.c_str(), L"WM/Composer") == 0) { rtExFrameID = WMA_FRAMEID_COMPOSER; } else if (wcscmp(exName.c_str(), L"WM/Conductor") == 0) { rtExFrameID = WMA_FRAMEID_CONDUCTOR; } else if (wcscmp(exName.c_str(), L"WM/ContentDistributor") == 0) { rtExFrameID = WMA_FRAMEID_CONTENTDISTRIBUTOR; } else if (wcscmp(exName.c_str(), L"WM/ContentGroupDescription") == 0) { rtExFrameID = WMA_FRAMEID_CGDPN; } else if (wcscmp(exName.c_str(), L"WM/Director") == 0) { rtExFrameID = WMA_FRAMEID_DIRECTOR; } else if (wcscmp(exName.c_str(), L"WM/DVDID") == 0) { rtExFrameID = WMA_FRAMEID_DVDID; } else if (wcscmp(exName.c_str(), L"WM/EncodedBy") == 0) { rtExFrameID = WMA_FRAMEID_ENCODEDBY; } else if (wcscmp(exName.c_str(), L"WM/EncodingSettings") == 0) { rtExFrameID = WMA_FRAMEID_ENCODINGSETTINGS; } else if (wcscmp(exName.c_str(), L"WM/EncodingTime") == 0) { rtExFrameID = WMA_FRAMEID_ENCODINGTIME; } else if (wcscmp(exName.c_str(), L"WM/Genre") == 0) { rtExFrameID = WMA_FRAMEID_GENRE; } else if (wcscmp(exName.c_str(), L"WM/GenreID") == 0) { rtExFrameID = WMA_FRAMEID_GENREID; } else if (wcscmp(exName.c_str(), L"WM/InitialKey") == 0) { rtExFrameID = WMA_FRAMEID_INITIALKEY; } else if (wcscmp(exName.c_str(), L"WM/ISRC") == 0) { rtExFrameID = WMA_FRAMEID_ISRC; } else if (wcscmp(exName.c_str(), L"WM/Language") == 0) { rtExFrameID = WMA_FRAMEID_LANGUAGE; } else if (wcscmp(exName.c_str(), L"WM/Lyrics") == 0) { rtExFrameID = WMA_FRAMEID_LYRICS; } else if (wcscmp(exName.c_str(), L"WM/Lyrics_Synchronised") == 0) { rtExFrameID = WMA_FRAMEID_LYRICSSYNC; } else if (wcscmp(exName.c_str(), L"WM/MCDI") == 0) { rtExFrameID = WMA_FRAMEID_MCDI; } else if (wcscmp(exName.c_str(), L"WM/MediaClassPrimaryID") == 0) { rtExFrameID = WMA_FRAMEID_MCPID; } else if (wcscmp(exName.c_str(), L"WM/MediaClassSecondaryID") == 0) { rtExFrameID = WMA_FRAMEID_MCSID; } else if (wcscmp(exName.c_str(), L"WM/MediaCredits") == 0) { rtExFrameID = WMA_FRAMEID_MDACREDITS; } else if (wcscmp(exName.c_str(), L"WM/MediaIsDelay") == 0) { rtExFrameID = WMA_FRAMEID_MDAISDELAY; } else if (wcscmp(exName.c_str(), L"WM/MediaIsFinale") == 0) { rtExFrameID = WMA_FRAMEID_MDAISFINALE; } else if (wcscmp(exName.c_str(), L"WM/MediaIsLive") == 0) { rtExFrameID = WMA_FRAMEID_MDAISLIVE; } else if (wcscmp(exName.c_str(), L"WM/MediaIsPremiere") == 0) { rtExFrameID = WMA_FRAMEID_MDAISPREMIERE; } else if (wcscmp(exName.c_str(), L"WM/MediaIsRepeat") == 0) { rtExFrameID = WMA_FRAMEID_MDAISREPEAT; } else if (wcscmp(exName.c_str(), L"WM/MediaIsSAP") == 0) { rtExFrameID = WMA_FRAMEID_MDAISSAP; } else if (wcscmp(exName.c_str(), L"WM/MediaIsSubtitled") == 0) { rtExFrameID = WMA_FRAMEID_MDAISSUBTITLED; } else if (wcscmp(exName.c_str(), L"WM/MediaIsStereo") == 0) { rtExFrameID = WMA_FRAMEID_MDAISSTEREO; } else if (wcscmp(exName.c_str(), L"WM/MediaNetworkAffiliation") == 0) { rtExFrameID = WMA_FRAMEID_MDANETWORKAFFILIATION; } else if (wcscmp(exName.c_str(), L"WM/MediaOriginalBroadcastDateTime") == 0) { rtExFrameID = WMA_FRAMEID_MDAORIGINALBDT; } else if (wcscmp(exName.c_str(), L"WM/MediaOriginalChannel") == 0) { rtExFrameID = WMA_FRAMEID_MDAORIGINALCHANNEL; } else if (wcscmp(exName.c_str(), L"WM/MediaStationCallSign") == 0) { rtExFrameID = WMA_FRAMEID_MDASTATIONCALLSIGN; } else if (wcscmp(exName.c_str(), L"WM/MediaStationName") == 0) { rtExFrameID = WMA_FRAMEID_MDASTATIONNAME; } else if (wcscmp(exName.c_str(), L"WM/ModifiedBy") == 0) { rtExFrameID = WMA_FRAMEID_MODIFIEDBY; } else if (wcscmp(exName.c_str(), L"WM/Mood") == 0) { rtExFrameID = WMA_FRAMEID_MOOD; } else if (wcscmp(exName.c_str(), L"WM/OriginalAlbumTitle") == 0) { rtExFrameID = WMA_FRAMEID_ORIGALBUMTITLE; } else if (wcscmp(exName.c_str(), L"WM/OriginalArtist") == 0) { rtExFrameID = WMA_FRAMEID_ORIGARTIST; } else if (wcscmp(exName.c_str(), L"WM/OriginalFilename") == 0) { rtExFrameID = WMA_FRAMEID_ORIGFILENAME; } else if (wcscmp(exName.c_str(), L"WM/OriginalLyricist") == 0) { rtExFrameID = WMA_FRAMEID_ORIGLYRICIST; } else if (wcscmp(exName.c_str(), L"WM/OriginalReleaseTime") == 0) { rtExFrameID = WMA_FRAMEID_ORIGRELEASETIME; } else if (wcscmp(exName.c_str(), L"WM/OriginalReleaseYear") == 0) { rtExFrameID = WMA_FRAMEID_ORIGRELEASEYEAR; } else if (wcscmp(exName.c_str(), L"WM/ParentalRating") == 0) { rtExFrameID = WMA_FRAMEID_PARENTALRATING; } else if (wcscmp(exName.c_str(), L"WM/ParentalRatingReason") == 0) { rtExFrameID = WMA_FRAMEID_PARENTALRATINGREASON; } else if (wcscmp(exName.c_str(), L"WM/PartOfSet") == 0) { rtExFrameID = WMA_FRAMEID_PARTOFSET; } else if (wcscmp(exName.c_str(), L"WM/Period") == 0) { rtExFrameID = WMA_FRAMEID_PERIOD; } else if (wcscmp(exName.c_str(), L"WM/Picture") == 0) { rtExFrameID = WMA_FRAMEID_PICTURE; } else if (wcscmp(exName.c_str(), L"WM/Producer") == 0) { rtExFrameID = WMA_FRAMEID_PRODUCER; } else if (wcscmp(exName.c_str(), L"WM/PromotionURL") == 0) { rtExFrameID = WMA_FRAMEID_PROMOTIONURL; } else if (wcscmp(exName.c_str(), L"WM/Provider") == 0) { rtExFrameID = WMA_FRAMEID_PROVIDER; } else if (wcscmp(exName.c_str(), L"WM/ProviderCopyright") == 0) { rtExFrameID = WMA_FRAMEID_PROVIDERCPYRIGHT; } else if (wcscmp(exName.c_str(), L"WM/ProviderRating") == 0) { rtExFrameID = WMA_FRAMEID_PROVIDERRATING; } else if (wcscmp(exName.c_str(), L"WM/ProviderStyle") == 0) { rtExFrameID = WMA_FRAMEID_PROVIDERSTYLE; } else if (wcscmp(exName.c_str(), L"WM/Publisher") == 0) { rtExFrameID = WMA_FRAMEID_PUBLISHER; } else if (wcscmp(exName.c_str(), L"WM/RadioStationName") == 0) { rtExFrameID = WMA_FRAMEID_RADIOSTATIONNAME; } else if (wcscmp(exName.c_str(), L"WM/RadioStationOwner") == 0) { rtExFrameID = WMA_FRAMEID_RADIOSTATIONOWNER; } else if (wcscmp(exName.c_str(), L"WM/SharedUserRating") == 0) { rtExFrameID = WMA_FRAMEID_SHAREUSERRATING; } else if (wcscmp(exName.c_str(), L"WM/SubTitle") == 0) { rtExFrameID = WMA_FRAMEID_SUBTITLE; } else if (wcscmp(exName.c_str(), L"WM/SubTitleDescription") == 0) { rtExFrameID = WMA_FRAMEID_SUBTITLEDESCRIPTION; } else if (wcscmp(exName.c_str(), L"WM/Text") == 0) { rtExFrameID = WMA_FRAMEID_TEXT; } else if (wcscmp(exName.c_str(), L"WM/ToolName") == 0) { rtExFrameID = WMA_FRAMEID_TOOLNAME; } else if (wcscmp(exName.c_str(), L"WM/ToolVersion") == 0) { rtExFrameID = WMA_FRAMEID_TOOLVERSION; } else if (wcscmp(exName.c_str(), L"WM/Track") == 0) { rtExFrameID = WMA_FRAMEID_TRACK; } else if (wcscmp(exName.c_str(), L"WM/TrackNumber") == 0) { rtExFrameID = WMA_FRAMEID_TRACKNUMBER; } else if (wcscmp(exName.c_str(), L"WM/UniqueFileIdentifier") == 0) { rtExFrameID = WMA_FRAMEID_UNIQUEFILEIDENTIFIER; } else if (wcscmp(exName.c_str(), L"WM/UserWebURL") == 0) { rtExFrameID = WMA_FRAMEID_USERWEBURL; } else if (wcscmp(exName.c_str(), L"WM/WMCollectionGroupID") == 0) { rtExFrameID = WMA_FRAMEID_WMCOLLECTIONGROUPID; } else if (wcscmp(exName.c_str(), L"WM/WMCollectionID") == 0) { rtExFrameID = WMA_FRAMEID_WMCOLLECTIONID; } else if (wcscmp(exName.c_str(), L"WM/WMContentID") == 0) { rtExFrameID = WMA_FRAMEID_CONTENTID; } else if (wcscmp(exName.c_str(), L"WM/Writer") == 0) { rtExFrameID = WMA_FRAMEID_WRITER; } else if (wcscmp(exName.c_str(), L"WM/Year") == 0) { rtExFrameID = WMA_FRAMEID_YEAR; } else if (wcscmp(exName.c_str(), L"WMFSDKVersion") == 0) { rtExFrameID = WMA_FRAMEID_SDKVERSION; } else if (wcscmp(exName.c_str(), L"WMFSDKNeeded") == 0) { rtExFrameID = WMA_FRAMEID_SDKNEEDED; } else if (wcscmp(exName.c_str(), L"IsVBR") == 0) { rtExFrameID = WMA_FRAMEID_ISVBR; } else { rtExFrameID = WMA_FRAMEID_UNKNOWN; } return rtExFrameID; }
贴出上面实现中用到存储图片的类头文件:
/******************************************************************** created: 2010/05/14 created: 14:5:2010 9:03 filename: f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyPicInfo.h file path: f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG file base: CMyPicInfo file ext: h author: zhangwf purpose: 用于存储读取出的图片信息类 *********************************************************************/ #ifndef _CMY_PIC_INFO_H #define _CMY_PIC_INFO_H ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // 定义存放解析图片数据类 class CMYPICINFO { public: // 构造函数 CMYPICINFO(); // 析构函数 ~CMYPICINFO(); // 拷贝构造函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的拷贝构造函数) CMYPICINFO(const CMYPICINFO &otherPicInfo); // 赋值函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的赋值函数) CMYPICINFO& operator =(const CMYPICINFO &otherPicInfo); public: // 接口函数 // 得到图片缓冲区地址(注意判断为NULL的情况) const unsigned char* GetPicBufAddr(); // 得到缓冲区大小 unsigned long GetPicBufSize(); // 设置图片数据 bool SetPicBufData(const char *pPicData, unsigned long picDataLength); // 释放图片数据 void ReleaseData(); // 保存数据到文件 bool SavePicToFile(const char *filePathName); bool SavePicToFile(const wchar_t *filePathName); private: // 私有成员函数 // 申请空间 bool NewPicBuf(unsigned long bufSize); // 释放空间 void DeletePicBuf(); private: // 成员变量 unsigned char *m_pPicBuf; unsigned long m_lBufSize; }; ////////////////////////////////////////////////////////////////////////// #endif
贴出图片存储类实现文件:
/******************************************************************** created: 2010/05/14 created: 14:5:2010 9:03 filename: f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyPicInfo.cpp file path: f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG file base: CMyPicInfo file ext: cpp author: zhangwf purpose: 用于存储读取出的图片信息类 *********************************************************************/ ////////////////////////////////////////////////////////////////////////// #include "CMyPicInfo.h" #include <Windows.h> #include <stdio.h> ////////////////////////////////////////////////////////////////////////// // 存放解析到的图片数据类 // 构造函数 CMYPICINFO::CMYPICINFO() { // 初始化成员变量 m_pPicBuf = NULL; m_lBufSize = 0; } // 析构函数 CMYPICINFO::~CMYPICINFO() { // 释放空间 DeletePicBuf(); } // 拷贝构造函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的拷贝构造函数) CMYPICINFO::CMYPICINFO(const CMYPICINFO &otherPicInfo) { // 获得大小 m_lBufSize = otherPicInfo.m_lBufSize; // 拷贝图片数据 m_pPicBuf = NULL; if (otherPicInfo.m_pPicBuf != NULL) { m_pPicBuf = new unsigned char[otherPicInfo.m_lBufSize]; if (m_pPicBuf != NULL) { memcpy(m_pPicBuf, otherPicInfo.m_pPicBuf, otherPicInfo.m_lBufSize); } } } // 赋值函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的赋值函数) CMYPICINFO& CMYPICINFO::operator =(const CMYPICINFO &otherPicInfo) { // 检查自赋值 if (this == &otherPicInfo) { return *this; } // 释放图片数据 DeletePicBuf(); // 获得图片大小 m_lBufSize = otherPicInfo.m_lBufSize; // 拷贝图片数据 if (otherPicInfo.m_pPicBuf != NULL) { m_pPicBuf = new unsigned char[otherPicInfo.m_lBufSize]; if (m_pPicBuf != NULL) { memcpy(m_pPicBuf, otherPicInfo.m_pPicBuf, otherPicInfo.m_lBufSize); } } // 返回本对象的引用 return *this; } ////////////////////////////////////////////////////////////////////////// // 接口函数 // 得到图片缓冲区地址(注意判断为NULL的情况) const unsigned char* CMYPICINFO::GetPicBufAddr() { return m_pPicBuf; } // 得到缓冲区大小 unsigned long CMYPICINFO::GetPicBufSize() { return m_lBufSize; } // 设置图片数据 bool CMYPICINFO::SetPicBufData(const char *pPicData, unsigned long picDataLength) { // 参数有效性 if (pPicData==NULL || picDataLength==0) { return false; } // 重新申请空间 if (!NewPicBuf(picDataLength)) { return false; } // 拷贝数据 memcpy(m_pPicBuf, pPicData, picDataLength); // 返回成功 return true; } // 释放图片数据 void CMYPICINFO::ReleaseData() { DeletePicBuf(); } // 保存数据到文件 bool CMYPICINFO::SavePicToFile(const char *filePathName) { // 判断是否有数据 if (m_pPicBuf == NULL) { return false; } // 打开文件 FILE *pFile = fopen(filePathName, "wb"); if (pFile == NULL) { return false; } // 写入文件 fwrite(m_pPicBuf, m_lBufSize, 1, pFile); fclose(pFile); return true; } // 保存数据到文件 bool CMYPICINFO::SavePicToFile(const wchar_t *filePathName) { // 判断是否有数据 if (m_pPicBuf == NULL) { return false; } // 打开文件 FILE *pFile = _wfopen(filePathName, L"wb"); if (pFile == NULL) { return false; } // 写入文件 fwrite(m_pPicBuf, m_lBufSize, 1, pFile); fclose(pFile); return true; } ////////////////////////////////////////////////////////////////////////// // 私有函数 // 申请空间 bool CMYPICINFO::NewPicBuf(unsigned long bufSize) { // 释放上次 DeletePicBuf(); // 参数是否有效 if (bufSize == 0) { return false; } // 申请新的空间 m_pPicBuf = new unsigned char[bufSize]; if (m_pPicBuf == NULL) { return false; } // 得到缓冲区大小 m_lBufSize = bufSize; // 初始化内存空间 memset(m_pPicBuf, 0, m_lBufSize); // 返回成功 return true; } // 释放空间 void CMYPICINFO::DeletePicBuf() { if (m_pPicBuf != NULL) { delete[] m_pPicBuf; m_pPicBuf = NULL; m_lBufSize = 0; } }
相关文章推荐
- swf文件格式解析入门(tag解析)
- FTP服务器LIST指令获取的文件列表信息解析(UNIX格式)
- swf文件格式解析入门(tag解析)
- C++ 解析WAVE格式文件信息,并取得播放时间
- 解析静态库(Lib)文件,提取出所有函数信息,组织成自定义格式文件
- swf文件格式解析入门(tag解析)
- c# 借助cmd命令解析apk文件信息
- ArcGIS三大文件格式解析
- C++PE文件格式解析类(轻松制作自己的PE文件解析器)
- FLV文件格式解析
- (原创)bls文件格式的解析
- struts2 + ajax(由前台的form提交数据到后台,再根据form所调用返回获取的后台json格式的数据返回到前端,然后前端用jquery对json数据进行解析)==》》涉及文件上传的部分
- swf文件格式解析入门
- FLV文件格式解析
- MXF 文件解析,MXF Parse, MXF code. MXF文件格式
- MKV 文件格式解析
- FLV文件格式解析
- wav 文件格式解析
- ELF文件格式解析
- Ubuntu下的wxWidgets编程(学生信息管理写入文件,文件格式是.txt)