xref: /MusicPlayer2/MusicPlayer2/TagLibHelper.cpp (revision 65da13ced4128c82d03e75c1539e81ae079cadac)
1d2d85fe1SZhong Yang #include "stdafx.h"
2b4284970SZhong Yang #include "TagLibHelper.h"
3b4284970SZhong Yang #include "taglib/mp4file.h"
4b4284970SZhong Yang #include "taglib/mp4coverart.h"
5b4284970SZhong Yang #include "taglib/flacfile.h"
6b4284970SZhong Yang #include "taglib/flacpicture.h"
7b4284970SZhong Yang #include "taglib/mpegfile.h"
8b4284970SZhong Yang #include "Common.h"
9b4284970SZhong Yang #include "FilePathHelper.h"
10b4284970SZhong Yang #include "taglib/attachedpictureframe.h"
11b4284970SZhong Yang #include "taglib/id3v2tag.h"
12348374d3SZhong Yang #include "taglib/id3v1tag.h"
13b4284970SZhong Yang #include "taglib/apefile.h"
14b4284970SZhong Yang #include "taglib/wavfile.h"
15b4284970SZhong Yang #include "taglib/mpcfile.h"
16b4284970SZhong Yang #include "taglib/opusfile.h"
17b4284970SZhong Yang #include "taglib/wavpackfile.h"
18b4284970SZhong Yang #include "taglib/vorbisfile.h"
19b4284970SZhong Yang #include "taglib/trueaudiofile.h"
20b4284970SZhong Yang #include "taglib/aifffile.h"
21b4284970SZhong Yang #include "taglib/asffile.h"
22b4284970SZhong Yang #include "taglib/tpropertymap.h"
23b4284970SZhong Yang #include "AudioCommon.h"
24b4284970SZhong Yang #include "taglib/apetag.h"
25b4284970SZhong Yang #include "taglib/fileref.h"
26b86d7e7aSZhong Yang #include "taglib/speexfile.h"
2734f69099SZhong Yang #include "taglib/unsynchronizedlyricsframe.h"
28d2d85fe1SZhong Yang #include "taglib/id3v2frame.h"
29d2d85fe1SZhong Yang #include "taglib/popularimeterframe.h"
30b4284970SZhong Yang 
31b4284970SZhong Yang 
32b4284970SZhong Yang using namespace TagLib;
33b4284970SZhong Yang 
34b4284970SZhong Yang #define STR_MP4_COVER_TAG "covr"
35b4284970SZhong Yang #define STR_ASF_COVER_TAG "WM/Picture"
36b4284970SZhong Yang #define STR_APE_COVER_TAG "COVER ART (FRONT)"
3711e2bf4bSZhong Yang 
3811e2bf4bSZhong Yang #define STR_MP4_LYRICS_TAG "----:com.apple.iTunes:Lyrics"
39deb58856SZhong Yang #define STR_ID3V2_LYRIC_TAG "USLT"
40deb58856SZhong Yang #define STR_FLAC_LYRIC_TAG "LYRICS"
410efbb7bcSZhong Yang #define STR_ASF_LYRIC_TAG "LYRICS"
4211e2bf4bSZhong Yang 
43e95fbf71SZhong Yang #define STR_APE_CUE_TAG "CUESHEET"
44b4284970SZhong Yang 
4511e2bf4bSZhong Yang #define STR_ID3V2_RATEING_TAG "POPM"
4611e2bf4bSZhong Yang #define STR_FLAC_RATING_TAG "RATING"
477b80a5daSzhongyang219 //#define STR_WMA_RATING_TAG "RATING WMP"
4811e2bf4bSZhong Yang 
492715cf48SZhong Yang //将taglib中的字符串转换成std::wstring类型。
50d2d85fe1SZhong Yang //由于taglib将所有非unicode编码全部作为Latin编码处理,因此无法正确处理本地代码页
51d2d85fe1SZhong Yang //这里将Latin编码的字符串按本地代码页处理
TagStringToWstring(const String & str,bool to_local)522715cf48SZhong Yang static std::wstring TagStringToWstring(const String& str, bool to_local)
53ea6fbf76SZhong Yang {
542715cf48SZhong Yang     std::wstring result;
55ea6fbf76SZhong Yang     if (to_local && str.isLatin1())
56ea6fbf76SZhong Yang         result = CCommon::StrToUnicode(str.to8Bit(), CodeType::ANSI);
57ea6fbf76SZhong Yang     else
58ea6fbf76SZhong Yang         result = str.toWString();
59ea6fbf76SZhong Yang     return result;
60ea6fbf76SZhong Yang }
61b4284970SZhong Yang 
SongInfoToTag(const SongInfo & song_info,Tag * tag)62b4284970SZhong Yang static void SongInfoToTag(const SongInfo& song_info, Tag* tag)
63b4284970SZhong Yang {
64b4284970SZhong Yang     if (tag != nullptr)
65b4284970SZhong Yang     {
66b4284970SZhong Yang         tag->setTitle(song_info.title);
67b4284970SZhong Yang         tag->setArtist(song_info.artist);
68b4284970SZhong Yang         tag->setAlbum(song_info.album);
69b4284970SZhong Yang         tag->setGenre(song_info.genre);
70b4284970SZhong Yang         tag->setTrack(song_info.track);
71b4284970SZhong Yang         tag->setComment(song_info.comment);
720574ac5bSZhong Yang         tag->setYear(song_info.year);
73b4284970SZhong Yang     }
74b4284970SZhong Yang }
75b4284970SZhong Yang 
IsStringNumber(std::wstring str,int num)762715cf48SZhong Yang static bool IsStringNumber(std::wstring str, int num)
771c5564e2SZhong Yang {
781c5564e2SZhong Yang     if (!str.empty() && str.front() == L'(')
791c5564e2SZhong Yang         str = str.substr(1);
801c5564e2SZhong Yang     if (!str.empty() && str.back() == L')')
811c5564e2SZhong Yang         str.pop_back();
821c5564e2SZhong Yang     if (CCommon::StrIsNumber(str))
831c5564e2SZhong Yang     {
841c5564e2SZhong Yang         num = _wtoi(str.c_str());
851c5564e2SZhong Yang         return true;
861c5564e2SZhong Yang     }
871c5564e2SZhong Yang     return false;
881c5564e2SZhong Yang }
891c5564e2SZhong Yang 
TagToSongInfo(SongInfo & song_info,Tag * tag,bool to_local)90ea6fbf76SZhong Yang static void TagToSongInfo(SongInfo& song_info, Tag* tag, bool to_local)
91b4284970SZhong Yang {
92b4284970SZhong Yang     if (tag != nullptr)
93b4284970SZhong Yang     {
94ea6fbf76SZhong Yang         song_info.title = TagStringToWstring(tag->title(), to_local);
95ea6fbf76SZhong Yang         song_info.artist = TagStringToWstring(tag->artist(), to_local);
96ea6fbf76SZhong Yang         song_info.album = TagStringToWstring(tag->album(), to_local);
97ea6fbf76SZhong Yang         song_info.genre = TagStringToWstring(tag->genre(), to_local);
981c5564e2SZhong Yang         int genre_num{};
991c5564e2SZhong Yang         if (IsStringNumber(song_info.genre, genre_num))
100b4284970SZhong Yang         {
1011c5564e2SZhong Yang             song_info.genre = CAudioCommon::GetGenre(static_cast<BYTE>(genre_num));
102b4284970SZhong Yang         }
103b4284970SZhong Yang 
1040574ac5bSZhong Yang         song_info.year = tag->year();
105b4284970SZhong Yang         song_info.track = tag->track();
106ea6fbf76SZhong Yang         song_info.comment = TagStringToWstring(tag->comment(), to_local);
107b4284970SZhong Yang     }
108b4284970SZhong Yang }
109b4284970SZhong Yang 
110d2d85fe1SZhong Yang //将文件内容读取到ByteVector
FileToByteVector(ByteVector & data,const std::wstring & file_path)111b4284970SZhong Yang static void FileToByteVector(ByteVector& data, const std::wstring& file_path)
112b4284970SZhong Yang {
113b4284970SZhong Yang     std::ifstream file{ file_path, std::ios::binary | std::ios::in };
114b4284970SZhong Yang     if (file.fail())
115b4284970SZhong Yang         return;
116b4284970SZhong Yang 
117d2d85fe1SZhong Yang     //获取文件长度
118b4284970SZhong Yang     file.seekg(0, file.end);
1194df46f80Slrisora     unsigned int length = static_cast<unsigned int>(file.tellg());
120b4284970SZhong Yang     file.seekg(0, file.beg);
121b4284970SZhong Yang 
122b4284970SZhong Yang     data.clear();
1234df46f80Slrisora     data.resize(length);
124b4284970SZhong Yang 
125b4284970SZhong Yang     file.read(data.data(), length);
126b4284970SZhong Yang 
127b4284970SZhong Yang     file.close();
128b4284970SZhong Yang }
129b4284970SZhong Yang 
GetPicType(const std::wstring & mimeType)1302715cf48SZhong Yang int GetPicType(const std::wstring& mimeType)
131b4284970SZhong Yang {
132b4284970SZhong Yang     int type{ -1 };
133b4284970SZhong Yang     if (mimeType == L"image/jpeg" || mimeType == L"image/jpg")
134b4284970SZhong Yang         type = 0;
135b4284970SZhong Yang     else if (mimeType == L"image/png")
136b4284970SZhong Yang         type = 1;
137b4284970SZhong Yang     else if (mimeType == L"image/gif")
138b4284970SZhong Yang         type = 2;
139b4284970SZhong Yang     else if (mimeType == L"image/bmp")
140b4284970SZhong Yang         type = 3;
141b4284970SZhong Yang     else
142b4284970SZhong Yang         type = -1;
143b4284970SZhong Yang     return type;
144b4284970SZhong Yang }
145b4284970SZhong Yang 
GetId3v2AlbumCover(ID3v2::Tag * id3v2,string & cover_contents,int & type)146b4284970SZhong Yang static void GetId3v2AlbumCover(ID3v2::Tag* id3v2, string& cover_contents, int& type)
147b4284970SZhong Yang {
148b4284970SZhong Yang     if (id3v2 != nullptr)
149b4284970SZhong Yang     {
150b4284970SZhong Yang         auto pic_frame_list = id3v2->frameListMap()["APIC"];
151b4284970SZhong Yang         if (!pic_frame_list.isEmpty())
152b4284970SZhong Yang         {
153b4284970SZhong Yang             ID3v2::AttachedPictureFrame* frame = dynamic_cast<TagLib::ID3v2::AttachedPictureFrame*>(pic_frame_list.front());
154b4284970SZhong Yang             if (frame != nullptr)
155b4284970SZhong Yang             {
156b4284970SZhong Yang                 auto pic_data = frame->picture();
157d2d85fe1SZhong Yang                 //获取专辑封面
158b4284970SZhong Yang                 cover_contents.assign(pic_data.data(), pic_data.size());
1592715cf48SZhong Yang                 std::wstring img_type = frame->mimeType().toCWString();
160b4284970SZhong Yang                 type = GetPicType(img_type);
161b4284970SZhong Yang             }
162b4284970SZhong Yang         }
163b4284970SZhong Yang     }
164b4284970SZhong Yang }
165b4284970SZhong Yang 
DeleteId3v2AlbumCover(ID3v2::Tag * id3v2tag)166b4284970SZhong Yang static void DeleteId3v2AlbumCover(ID3v2::Tag* id3v2tag)
167b4284970SZhong Yang {
168b4284970SZhong Yang     if (id3v2tag != nullptr)
169b4284970SZhong Yang     {
170b4284970SZhong Yang         auto pic_frame_list = id3v2tag->frameListMap()["APIC"];
171b4284970SZhong Yang         if (!pic_frame_list.isEmpty())
172b4284970SZhong Yang         {
173b4284970SZhong Yang             for (auto frame : pic_frame_list)
174b4284970SZhong Yang                 id3v2tag->removeFrame(frame);
175b4284970SZhong Yang         }
176b4284970SZhong Yang     }
177b4284970SZhong Yang }
178b4284970SZhong Yang 
WriteId3v2AlbumCover(ID3v2::Tag * id3v2tag,const std::wstring & album_cover_path)1792715cf48SZhong Yang static void WriteId3v2AlbumCover(ID3v2::Tag* id3v2tag, const std::wstring& album_cover_path)
180b4284970SZhong Yang {
181b4284970SZhong Yang     if (id3v2tag != nullptr)
182b4284970SZhong Yang     {
183d2d85fe1SZhong Yang         //读取图片文件
184b4284970SZhong Yang         ByteVector pic_data;
185b4284970SZhong Yang         FileToByteVector(pic_data, album_cover_path);
186d2d85fe1SZhong Yang         //向音频文件写入图片文件
187b4284970SZhong Yang         ID3v2::AttachedPictureFrame* pic_frame = new ID3v2::AttachedPictureFrame();
188b4284970SZhong Yang         pic_frame->setPicture(pic_data);
189b4284970SZhong Yang         pic_frame->setType(ID3v2::AttachedPictureFrame::FrontCover);
1902715cf48SZhong Yang         std::wstring ext = CFilePathHelper(album_cover_path).GetFileExtension();
191b4284970SZhong Yang         pic_frame->setMimeType(L"image/" + ext);
192b4284970SZhong Yang         id3v2tag->addFrame(pic_frame);
193b4284970SZhong Yang     }
194b4284970SZhong Yang }
195b4284970SZhong Yang 
196b4284970SZhong Yang 
GetApeTagAlbumCover(APE::Tag * tag,string & cover_contents,int & type)197b4284970SZhong Yang static void GetApeTagAlbumCover(APE::Tag* tag, string& cover_contents, int& type)
198b4284970SZhong Yang {
199b4284970SZhong Yang     if (tag != nullptr)
200b4284970SZhong Yang     {
201b4284970SZhong Yang         auto item_list_map = tag->itemListMap();
202b4284970SZhong Yang         auto pic_item = item_list_map[STR_APE_COVER_TAG];
203b4284970SZhong Yang         auto pic_data = pic_item.binaryData();
204b4284970SZhong Yang         if (!pic_data.isEmpty())
205b4284970SZhong Yang         {
206b4284970SZhong Yang             cover_contents.assign(pic_data.data(), pic_data.size());
207b4284970SZhong Yang 
208b4284970SZhong Yang             size_t index{};
209b4284970SZhong Yang             index = cover_contents.find('\0');
210b4284970SZhong Yang             std::string pic_desc;
211b4284970SZhong Yang             if (index != std::string::npos)
212b4284970SZhong Yang             {
213b4284970SZhong Yang                 pic_desc = cover_contents.substr(0, index);
214b4284970SZhong Yang                 cover_contents = cover_contents.substr(index + 1);
215b4284970SZhong Yang             }
216b4284970SZhong Yang 
217b4284970SZhong Yang             if (!pic_desc.empty())
218b4284970SZhong Yang             {
219b4284970SZhong Yang                 std::string img_type;
220b4284970SZhong Yang                 index = pic_desc.rfind('.');
221b4284970SZhong Yang                 if (index != std::string::npos && index < pic_desc.size() - 1)
222b4284970SZhong Yang                 {
223b4284970SZhong Yang                     img_type = pic_desc.substr(index + 1);
224b4284970SZhong Yang                     img_type = "image/" + img_type;
225b4284970SZhong Yang                     type = GetPicType(CCommon::ASCIIToUnicode(img_type));
226b4284970SZhong Yang                 }
227b4284970SZhong Yang             }
228b4284970SZhong Yang         }
229b4284970SZhong Yang     }
2307172d8f8SZhong Yang }
231b4284970SZhong Yang 
WriteApeTagAlbumCover(APE::Tag * tag,const std::wstring & album_cover_path,bool remove_exist)2322715cf48SZhong Yang static void WriteApeTagAlbumCover(APE::Tag* tag, const std::wstring& album_cover_path, bool remove_exist)
2337172d8f8SZhong Yang {
2347172d8f8SZhong Yang     if (remove_exist)
2357172d8f8SZhong Yang     {
2367172d8f8SZhong Yang         tag->removeItem(STR_APE_COVER_TAG);
2377172d8f8SZhong Yang     }
2387172d8f8SZhong Yang 
2397172d8f8SZhong Yang     if (!album_cover_path.empty())
2407172d8f8SZhong Yang     {
2417172d8f8SZhong Yang         ByteVector pic_data;
2427172d8f8SZhong Yang         FileToByteVector(pic_data, album_cover_path);
2437172d8f8SZhong Yang 
2447172d8f8SZhong Yang         ByteVector pic_item_data;
2457172d8f8SZhong Yang         pic_item_data = "Cover Art (Front).";
2462715cf48SZhong Yang         std::wstring file_type = CFilePathHelper(album_cover_path).GetFileExtension();
2477172d8f8SZhong Yang         for (wchar_t ch : file_type)
2487172d8f8SZhong Yang             pic_item_data.append(static_cast<char>(ch));
2497172d8f8SZhong Yang         pic_item_data.append('\0');
2507172d8f8SZhong Yang         pic_item_data.append(pic_data);
2517172d8f8SZhong Yang 
2527172d8f8SZhong Yang         APE::Item pic_item(STR_APE_COVER_TAG, pic_item_data, true);
2537172d8f8SZhong Yang         tag->setItem(STR_APE_COVER_TAG, pic_item);
2547172d8f8SZhong Yang     }
255b4284970SZhong Yang }
256b4284970SZhong Yang 
WriteXiphCommentAlbumCover(Ogg::XiphComment * tag,const std::wstring & album_cover_path,bool remove_exist)2572715cf48SZhong Yang static void WriteXiphCommentAlbumCover(Ogg::XiphComment* tag, const std::wstring& album_cover_path, bool remove_exist)
258de03cfedSZhong Yang {
259d2d85fe1SZhong Yang     //先删除专辑封面
260de03cfedSZhong Yang     if (remove_exist)
261de03cfedSZhong Yang     {
262de03cfedSZhong Yang         tag->removeAllPictures();
263de03cfedSZhong Yang     }
264de03cfedSZhong Yang 
265de03cfedSZhong Yang     if (!album_cover_path.empty())
266de03cfedSZhong Yang     {
267de03cfedSZhong Yang         ByteVector pic_data;
268de03cfedSZhong Yang         FileToByteVector(pic_data, album_cover_path);
269de03cfedSZhong Yang         FLAC::Picture* newpic = new FLAC::Picture();
270de03cfedSZhong Yang         newpic->setType(FLAC::Picture::FrontCover);
271de03cfedSZhong Yang         newpic->setData(pic_data);
2722715cf48SZhong Yang         std::wstring ext = CFilePathHelper(album_cover_path).GetFileExtension();
273de03cfedSZhong Yang         newpic->setMimeType(L"image/" + ext);
274de03cfedSZhong Yang         tag->addPicture(newpic);
275de03cfedSZhong Yang     }
276de03cfedSZhong Yang }
277de03cfedSZhong Yang 
278de03cfedSZhong Yang 
GetXiphCommentAlbumCover(Ogg::XiphComment * tag,string & cover_contents,int & type)279d2d85fe1SZhong Yang static void GetXiphCommentAlbumCover(Ogg::XiphComment* tag, string& cover_contents, int& type)
280de03cfedSZhong Yang {
281de03cfedSZhong Yang     const auto& cover_list = tag->pictureList();
282de03cfedSZhong Yang     if (!cover_list.isEmpty())
283de03cfedSZhong Yang     {
284de03cfedSZhong Yang         auto pic = cover_list.front();
285de03cfedSZhong Yang         if (pic != nullptr)
286de03cfedSZhong Yang         {
287de03cfedSZhong Yang             const auto& pic_data = pic->data();
288d2d85fe1SZhong Yang             //获取专辑封面
289de03cfedSZhong Yang             cover_contents.assign(pic_data.data(), pic_data.size());
290de03cfedSZhong Yang 
2912715cf48SZhong Yang             std::wstring img_type = pic->mimeType().toCWString();
292de03cfedSZhong Yang             type = GetPicType(img_type);
293de03cfedSZhong Yang         }
294de03cfedSZhong Yang     }
295de03cfedSZhong Yang }
296de03cfedSZhong Yang 
GetId3v2Lyric(ID3v2::Tag * id3v2)2972715cf48SZhong Yang static std::wstring GetId3v2Lyric(ID3v2::Tag* id3v2)
298e5862982SZhong Yang {
2992715cf48SZhong Yang     std::wstring lyrics;
300e5862982SZhong Yang     if (id3v2 != nullptr)
301e5862982SZhong Yang     {
302e5862982SZhong Yang         auto frame_list_map = id3v2->frameListMap();
303e5862982SZhong Yang         auto lyric_frame = frame_list_map[STR_ID3V2_LYRIC_TAG];
304e5862982SZhong Yang         if (!lyric_frame.isEmpty())
305e5862982SZhong Yang             lyrics = lyric_frame.front()->toString().toWString();
306e5862982SZhong Yang     }
307e5862982SZhong Yang     return lyrics;
308e5862982SZhong Yang }
309e5862982SZhong Yang 
310e5862982SZhong Yang 
WriteId3v2Lyric(ID3v2::Tag * id3v2,const std::wstring & lyric_contents)3112715cf48SZhong Yang static void WriteId3v2Lyric(ID3v2::Tag* id3v2, const std::wstring& lyric_contents)
312e5862982SZhong Yang {
313e5862982SZhong Yang     if (id3v2 != nullptr)
314e5862982SZhong Yang     {
315d2d85fe1SZhong Yang         //先删除歌词帧
316e5862982SZhong Yang         auto lyric_frame_list = id3v2->frameListMap()[STR_ID3V2_LYRIC_TAG];
317e5862982SZhong Yang         if (!lyric_frame_list.isEmpty())
318e5862982SZhong Yang         {
319e5862982SZhong Yang             for (auto frame : lyric_frame_list)
320e5862982SZhong Yang                 id3v2->removeFrame(frame);
321e5862982SZhong Yang         }
322e5862982SZhong Yang 
323e5862982SZhong Yang         if (!lyric_contents.empty())
324e5862982SZhong Yang         {
325d2d85fe1SZhong Yang             //写入歌词帧
326e5862982SZhong Yang             ID3v2::UnsynchronizedLyricsFrame* lyric_frame = new ID3v2::UnsynchronizedLyricsFrame();
327e5862982SZhong Yang             lyric_frame->setText(lyric_contents.c_str());
328e5862982SZhong Yang             id3v2->addFrame(lyric_frame);
329e5862982SZhong Yang         }
330e5862982SZhong Yang     }
331e5862982SZhong Yang }
332e5862982SZhong Yang 
333e5862982SZhong Yang 
33467323609SZhong Yang template<class T>
GetTagPropertyMap(T * tag,std::map<std::wstring,std::wstring> & property_map)3352715cf48SZhong Yang void GetTagPropertyMap(T* tag, std::map<std::wstring, std::wstring>& property_map)
33667323609SZhong Yang {
33767323609SZhong Yang     if (tag != nullptr)
33867323609SZhong Yang     {
33967323609SZhong Yang         auto properties = tag->properties();
34067323609SZhong Yang         for (const auto& prop : properties)
34167323609SZhong Yang         {
3422715cf48SZhong Yang             std::wstring key = prop.first.toWString();
3432715cf48SZhong Yang             std::wstring value = TagStringToWstring(prop.second.toString(L";"), true);
344348374d3SZhong Yang             auto iter = property_map.find(key);
345348374d3SZhong Yang             if (iter == property_map.end())
34667323609SZhong Yang                 property_map[key] = value;
347348374d3SZhong Yang             else if (iter->second.empty())
348348374d3SZhong Yang                 iter->second = value;
34967323609SZhong Yang         }
35067323609SZhong Yang     }
35167323609SZhong Yang }
35267323609SZhong Yang 
GetMapValue(const std::wstring & key,const std::map<std::wstring,std::wstring> & property_map)353fbf97538Szhongyang219 static std::wstring GetMapValue(const std::wstring& key, const std::map<std::wstring, std::wstring>& property_map)
354fbf97538Szhongyang219 {
355fbf97538Szhongyang219     auto iter = property_map.find(key);
356fbf97538Szhongyang219     if (iter != property_map.end())
357fbf97538Szhongyang219         return iter->second;
358fbf97538Szhongyang219     return std::wstring();
359fbf97538Szhongyang219 }
360fbf97538Szhongyang219 
361911a52b0Szhongyang219 //将标签属性中额外的信息保存到SongInfo中
OtherPropertyToSongInfo(SongInfo & song_info,const std::map<std::wstring,std::wstring> & property_map)362fbf97538Szhongyang219 static void OtherPropertyToSongInfo(SongInfo& song_info, const std::map<std::wstring, std::wstring>& property_map)
363fbf97538Szhongyang219 {
364fbf97538Szhongyang219     //获取唱片集艺术家
365fbf97538Szhongyang219     song_info.album_artist = GetMapValue(L"ALBUMARTIST", property_map);
366fbf97538Szhongyang219 
367fbf97538Szhongyang219     //获取音轨总数
368fbf97538Szhongyang219     std::wstring track_number = GetMapValue(L"TRACKNUMBER", property_map);
369fbf97538Szhongyang219     size_t index = track_number.find(L'/');
3702715cf48SZhong Yang     if (index != std::wstring::npos)
371fbf97538Szhongyang219     {
372fbf97538Szhongyang219         song_info.total_tracks = static_cast<BYTE>(_wtoi(track_number.substr(index + 1).c_str()));
373fbf97538Szhongyang219     }
374fbf97538Szhongyang219 
375fbf97538Szhongyang219     //获取CD序号和CD总数
376fbf97538Szhongyang219     std::wstring disc_number = GetMapValue(L"DISCNUMBER", property_map);
377fbf97538Szhongyang219     index = disc_number.find(L'/');
3782715cf48SZhong Yang     if (index != std::wstring::npos)
379fbf97538Szhongyang219     {
380*65da13ceSZhong Yang         song_info.total_discs = static_cast<BYTE>(CCommon::StringToInt(disc_number.substr(index + 1)));
381fbf97538Szhongyang219     }
382*65da13ceSZhong Yang     song_info.disc_num = static_cast<BYTE>(CCommon::StringToInt(disc_number));
383fbf97538Szhongyang219 }
384fbf97538Szhongyang219 
3858e2d3903SZhong Yang template<class T>
WriteOtherProperties(const SongInfo & song_info,T & file)3868e2d3903SZhong Yang static void WriteOtherProperties(const SongInfo& song_info, T& file)
3878e2d3903SZhong Yang {
3888e2d3903SZhong Yang     TagLib::PropertyMap properties = file.properties();
3893a6e9808Slrisora     properties["ALBUMARTIST"].clear();
3903a6e9808Slrisora     properties["DISCNUMBER"].clear();
3918e2d3903SZhong Yang     if (!song_info.album_artist.empty())
3928e2d3903SZhong Yang         properties["ALBUMARTIST"].append(song_info.album_artist);
3938e2d3903SZhong Yang     if (song_info.disc_num != 0)
3948e2d3903SZhong Yang         properties["DISCNUMBER"].append(std::to_wstring(static_cast<int>(song_info.disc_num)));
3958e2d3903SZhong Yang     file.setProperties(properties);
3968e2d3903SZhong Yang }
397fbf97538Szhongyang219 
398d2d85fe1SZhong Yang //解析Windows资源管理器设置的分级信息
ParseAudioRating(int rate_raw)399d2d85fe1SZhong Yang static int ParseAudioRating(int rate_raw)
400d2d85fe1SZhong Yang {
401d2d85fe1SZhong Yang     //使用Windows资源管理器设置了分级后,POPM字段的内容为以下格式:
402d2d85fe1SZhong Yang     //Windows Media Player 9 Series rating=196 counter=0
403d2d85fe1SZhong Yang     //其中rating后面的数字为分级,rating与分级的对应关系如下所示
404d2d85fe1SZhong Yang     /*
405d2d85fe1SZhong Yang       rating   |    分级
406d2d85fe1SZhong Yang       ---------|------------
407d2d85fe1SZhong Yang         255    |     5
408d2d85fe1SZhong Yang         196    |     4
409d2d85fe1SZhong Yang         128    |     3
410d2d85fe1SZhong Yang         64     |     2
411d2d85fe1SZhong Yang         1      |     1
412d2d85fe1SZhong Yang     */
413e5862982SZhong Yang 
414d2d85fe1SZhong Yang     //根据分级转换成1~5星
415d2d85fe1SZhong Yang     if (rate_raw == 1)
416d2d85fe1SZhong Yang         return 1;
417d2d85fe1SZhong Yang     else if (rate_raw <= 64)
418d2d85fe1SZhong Yang         return 2;
419d2d85fe1SZhong Yang     else if (rate_raw <= 128)
420d2d85fe1SZhong Yang         return 3;
421d2d85fe1SZhong Yang     else if (rate_raw <= 196)
422d2d85fe1SZhong Yang         return 4;
423d2d85fe1SZhong Yang     else if (rate_raw <= 255)
424d2d85fe1SZhong Yang         return 5;
425d2d85fe1SZhong Yang     return 0;
426d2d85fe1SZhong Yang }
427d2d85fe1SZhong Yang 
GenerateAudioRating(int rate)428d2d85fe1SZhong Yang static int GenerateAudioRating(int rate)
429d2d85fe1SZhong Yang {
430d2d85fe1SZhong Yang     switch (rate)
431d2d85fe1SZhong Yang     {
432d2d85fe1SZhong Yang     case 1:
433d2d85fe1SZhong Yang         return 1;
434d2d85fe1SZhong Yang     case 2:
435d2d85fe1SZhong Yang         return 64;
436d2d85fe1SZhong Yang     case 3:
437d2d85fe1SZhong Yang         return 128;
438d2d85fe1SZhong Yang     case 4:
439d2d85fe1SZhong Yang         return 196;
440d2d85fe1SZhong Yang     case 5:
441d2d85fe1SZhong Yang         return 255;
442d2d85fe1SZhong Yang     default:
443d2d85fe1SZhong Yang         return 0;
444d2d85fe1SZhong Yang     }
445d2d85fe1SZhong Yang }
446d2d85fe1SZhong Yang 
GetId3v2Rating(ID3v2::Tag * id3v2)447d2d85fe1SZhong Yang static int GetId3v2Rating(ID3v2::Tag* id3v2)
448d2d85fe1SZhong Yang {
449d2d85fe1SZhong Yang     if (id3v2 != nullptr)
450d2d85fe1SZhong Yang     {
451d2d85fe1SZhong Yang         auto frame_list_map = id3v2->frameListMap();
452d2d85fe1SZhong Yang         auto rate_frame = frame_list_map[STR_ID3V2_RATEING_TAG];
453d2d85fe1SZhong Yang         if (!rate_frame.isEmpty())
454d2d85fe1SZhong Yang         {
455d2d85fe1SZhong Yang             ID3v2::PopularimeterFrame* pFrame = dynamic_cast<ID3v2::PopularimeterFrame*>(rate_frame.front());
456d2d85fe1SZhong Yang             if (pFrame != nullptr)
457d2d85fe1SZhong Yang             {
458d2d85fe1SZhong Yang                 int rate_raw = pFrame->rating();
459d2d85fe1SZhong Yang                 return ParseAudioRating(rate_raw);
460d2d85fe1SZhong Yang             }
461d2d85fe1SZhong Yang         }
462d2d85fe1SZhong Yang     }
463d2d85fe1SZhong Yang     return 0;
464d2d85fe1SZhong Yang }
465d2d85fe1SZhong Yang 
WriteId3v2Rating(ID3v2::Tag * id3v2,int rate)466d2d85fe1SZhong Yang static void WriteId3v2Rating(ID3v2::Tag* id3v2, int rate)
467d2d85fe1SZhong Yang {
468d2d85fe1SZhong Yang     if (id3v2 != nullptr)
469d2d85fe1SZhong Yang     {
470d2d85fe1SZhong Yang         auto frameListMap = id3v2->frameListMap();
471d2d85fe1SZhong Yang 
472d2d85fe1SZhong Yang         //先删除POPM帧
473d2d85fe1SZhong Yang         auto rate_frame_list = id3v2->frameListMap()[STR_ID3V2_RATEING_TAG];
474d2d85fe1SZhong Yang         if (!rate_frame_list.isEmpty())
475d2d85fe1SZhong Yang         {
476d2d85fe1SZhong Yang             for (auto frame : rate_frame_list)
477d2d85fe1SZhong Yang                 id3v2->removeFrame(frame);
478d2d85fe1SZhong Yang         }
479d2d85fe1SZhong Yang 
48011e2bf4bSZhong Yang         if (rate >= 1 && rate <= 5)
48111e2bf4bSZhong Yang         {
482d2d85fe1SZhong Yang             ID3v2::PopularimeterFrame* rate_frame = new ID3v2::PopularimeterFrame();
483d2d85fe1SZhong Yang             int rate_raw = GenerateAudioRating(rate);
484d2d85fe1SZhong Yang             rate_frame->setRating(rate_raw);
485d2d85fe1SZhong Yang             id3v2->addFrame(rate_frame);
486d2d85fe1SZhong Yang         }
487d2d85fe1SZhong Yang     }
48811e2bf4bSZhong Yang }
489b4284970SZhong Yang 
getFlacPropertyMap(FLAC::File & file,std::map<std::wstring,std::wstring> & property_map)4902715cf48SZhong Yang static void getFlacPropertyMap(FLAC::File& file, std::map<std::wstring, std::wstring>& property_map)
491fbf97538Szhongyang219 {
492fbf97538Szhongyang219     if (file.hasXiphComment())
493fbf97538Szhongyang219         GetTagPropertyMap(file.xiphComment(), property_map);
494fbf97538Szhongyang219     if (file.hasID3v2Tag())
495fbf97538Szhongyang219         GetTagPropertyMap(file.ID3v2Tag(), property_map);
496fbf97538Szhongyang219     if (file.hasID3v1Tag())
497fbf97538Szhongyang219         GetTagPropertyMap(file.ID3v1Tag(), property_map);
498fbf97538Szhongyang219 }
499fbf97538Szhongyang219 
getM4aPropertyMap(MP4::File & file,std::map<std::wstring,std::wstring> & property_map)5002715cf48SZhong Yang static void getM4aPropertyMap(MP4::File& file, std::map<std::wstring, std::wstring>& property_map)
501fbf97538Szhongyang219 {
502fbf97538Szhongyang219     auto tag = file.tag();
503fbf97538Szhongyang219     GetTagPropertyMap(tag, property_map);
504fbf97538Szhongyang219 }
505fbf97538Szhongyang219 
getMpegPropertyMap(MPEG::File & file,std::map<std::wstring,std::wstring> & property_map)5062715cf48SZhong Yang static void getMpegPropertyMap(MPEG::File& file, std::map<std::wstring, std::wstring>& property_map)
507fbf97538Szhongyang219 {
508fbf97538Szhongyang219     if (file.hasID3v2Tag())
509fbf97538Szhongyang219         GetTagPropertyMap(file.ID3v2Tag(), property_map);
510fbf97538Szhongyang219     if (file.hasAPETag())
511fbf97538Szhongyang219         GetTagPropertyMap(file.APETag(), property_map);
512fbf97538Szhongyang219     if (file.hasID3v1Tag())
513fbf97538Szhongyang219         GetTagPropertyMap(file.ID3v1Tag(), property_map);
514fbf97538Szhongyang219 }
515fbf97538Szhongyang219 
getAsfPropertyMap(ASF::File & file,std::map<std::wstring,std::wstring> & property_map)5162715cf48SZhong Yang static void getAsfPropertyMap(ASF::File& file, std::map<std::wstring, std::wstring>& property_map)
517fbf97538Szhongyang219 {
518fbf97538Szhongyang219     auto tag = file.tag();
519fbf97538Szhongyang219     GetTagPropertyMap(tag, property_map);
520fbf97538Szhongyang219 }
521fbf97538Szhongyang219 
getApePropertyMap(APE::File & file,std::map<std::wstring,std::wstring> & property_map)5222715cf48SZhong Yang static void getApePropertyMap(APE::File& file, std::map<std::wstring, std::wstring>& property_map)
523fbf97538Szhongyang219 {
524fbf97538Szhongyang219     if (file.hasAPETag())
525fbf97538Szhongyang219         GetTagPropertyMap(file.APETag(), property_map);
526fbf97538Szhongyang219     if (file.hasID3v1Tag())
527fbf97538Szhongyang219         GetTagPropertyMap(file.ID3v1Tag(), property_map);
528fbf97538Szhongyang219 }
529fbf97538Szhongyang219 
getWavPropertyMap(RIFF::WAV::File & file,std::map<std::wstring,std::wstring> & property_map)5302715cf48SZhong Yang static void getWavPropertyMap(RIFF::WAV::File& file, std::map<std::wstring, std::wstring>& property_map)
531fbf97538Szhongyang219 {
532fbf97538Szhongyang219     if (file.hasID3v2Tag())
533fbf97538Szhongyang219         GetTagPropertyMap(file.ID3v2Tag(), property_map);
534fbf97538Szhongyang219     if (file.hasInfoTag())
535fbf97538Szhongyang219         GetTagPropertyMap(file.InfoTag(), property_map);
536fbf97538Szhongyang219 }
537fbf97538Szhongyang219 
getOggPropertyMap(Vorbis::File & file,std::map<std::wstring,std::wstring> & property_map)5382715cf48SZhong Yang static void getOggPropertyMap(Vorbis::File& file, std::map<std::wstring, std::wstring>& property_map)
539fbf97538Szhongyang219 {
540fbf97538Szhongyang219     auto tag = file.tag();
541fbf97538Szhongyang219     GetTagPropertyMap(tag, property_map);
542fbf97538Szhongyang219 }
543fbf97538Szhongyang219 
getMpcPropertyMap(MPC::File & file,std::map<std::wstring,std::wstring> & property_map)5442715cf48SZhong Yang static void getMpcPropertyMap(MPC::File& file, std::map<std::wstring, std::wstring>& property_map)
545fbf97538Szhongyang219 {
546fbf97538Szhongyang219     if (file.hasAPETag())
547fbf97538Szhongyang219         GetTagPropertyMap(file.APETag(), property_map);
548fbf97538Szhongyang219     if (file.hasID3v1Tag())
549fbf97538Szhongyang219         GetTagPropertyMap(file.ID3v1Tag(), property_map);
550fbf97538Szhongyang219 }
551fbf97538Szhongyang219 
getOpusPropertyMap(Ogg::Opus::File & file,std::map<std::wstring,std::wstring> & property_map)5522715cf48SZhong Yang static void getOpusPropertyMap(Ogg::Opus::File& file, std::map<std::wstring, std::wstring>& property_map)
553fbf97538Szhongyang219 {
554fbf97538Szhongyang219     auto tag = file.tag();
555fbf97538Szhongyang219     GetTagPropertyMap(tag, property_map);
556fbf97538Szhongyang219 }
557fbf97538Szhongyang219 
getWavPackPropertyMap(WavPack::File & file,std::map<std::wstring,std::wstring> & property_map)5582715cf48SZhong Yang static void getWavPackPropertyMap(WavPack::File& file, std::map<std::wstring, std::wstring>& property_map)
559fbf97538Szhongyang219 {
560fbf97538Szhongyang219     if (file.hasAPETag())
561fbf97538Szhongyang219         GetTagPropertyMap(file.APETag(), property_map);
562fbf97538Szhongyang219     if (file.hasID3v1Tag())
563fbf97538Szhongyang219         GetTagPropertyMap(file.ID3v1Tag(), property_map);
564fbf97538Szhongyang219 }
565fbf97538Szhongyang219 
getTtaPropertyMap(TrueAudio::File & file,std::map<std::wstring,std::wstring> & property_map)5662715cf48SZhong Yang static void getTtaPropertyMap(TrueAudio::File& file, std::map<std::wstring, std::wstring>& property_map)
567fbf97538Szhongyang219 {
568fbf97538Szhongyang219     if (file.hasID3v2Tag())
569fbf97538Szhongyang219         GetTagPropertyMap(file.ID3v2Tag(), property_map);
570fbf97538Szhongyang219     if (file.hasID3v1Tag())
571fbf97538Szhongyang219         GetTagPropertyMap(file.ID3v1Tag(), property_map);
572fbf97538Szhongyang219 }
573fbf97538Szhongyang219 
getAiffPropertyMap(RIFF::AIFF::File & file,std::map<std::wstring,std::wstring> & property_map)5742715cf48SZhong Yang static void getAiffPropertyMap(RIFF::AIFF::File& file, std::map<std::wstring, std::wstring>& property_map)
575fbf97538Szhongyang219 {
576fbf97538Szhongyang219     auto tag = file.tag();
577fbf97538Szhongyang219     GetTagPropertyMap(tag, property_map);
578fbf97538Szhongyang219 }
579fbf97538Szhongyang219 
getSpxPropertyMap(Ogg::Speex::File & file,std::map<std::wstring,std::wstring> & property_map)5802715cf48SZhong Yang static void getSpxPropertyMap(Ogg::Speex::File& file, std::map<std::wstring, std::wstring>& property_map)
581fbf97538Szhongyang219 {
582fbf97538Szhongyang219     auto tag = file.tag();
583fbf97538Szhongyang219     GetTagPropertyMap(tag, property_map);
584fbf97538Szhongyang219 }
585fbf97538Szhongyang219 
getAnyFilePropertyMap(FileRef & file,std::map<std::wstring,std::wstring> & property_map)5862715cf48SZhong Yang static void getAnyFilePropertyMap(FileRef& file, std::map<std::wstring, std::wstring>& property_map)
587fbf97538Szhongyang219 {
588fbf97538Szhongyang219     auto tag = file.tag();
589fbf97538Szhongyang219     GetTagPropertyMap(tag, property_map);
590fbf97538Szhongyang219 }
591fbf97538Szhongyang219 
592fbf97538Szhongyang219 
593b4284970SZhong Yang ///////////////////////////////////////////////////////////////////////////////////
594b4284970SZhong Yang ///////////////////////////////////////////////////////////////////////////////////
595d2d85fe1SZhong Yang ///////////////////////////////////////////////////////////////////////////////////
596d2d85fe1SZhong Yang 
59703045520Szhongyang219 bool CTagLibHelper::m_write_id3v2_3{ false };
598b4284970SZhong Yang 
CTagLibHelper()599b4284970SZhong Yang CTagLibHelper::CTagLibHelper()
600b4284970SZhong Yang {
601b4284970SZhong Yang }
602b4284970SZhong Yang 
~CTagLibHelper()603b4284970SZhong Yang CTagLibHelper::~CTagLibHelper()
604b4284970SZhong Yang {
605b4284970SZhong Yang }
606b4284970SZhong Yang 
SetWriteId3V2_3(bool write_id3v2_3)60703045520Szhongyang219 void CTagLibHelper::SetWriteId3V2_3(bool write_id3v2_3)
60803045520Szhongyang219 {
60903045520Szhongyang219     m_write_id3v2_3 = write_id3v2_3;
61003045520Szhongyang219 }
61103045520Szhongyang219 
GetM4aAlbumCover(const std::wstring & file_path,int & type)6122715cf48SZhong Yang string CTagLibHelper::GetM4aAlbumCover(const std::wstring& file_path, int& type)
613b4284970SZhong Yang {
614b4284970SZhong Yang     string cover_contents;
615b4284970SZhong Yang     MP4::File file(file_path.c_str());
616b4284970SZhong Yang     auto tag = file.tag();
617b4284970SZhong Yang     if (tag != nullptr)
618b4284970SZhong Yang     {
619b4284970SZhong Yang         auto cover_item = tag->item(STR_MP4_COVER_TAG).toCoverArtList();
620b4284970SZhong Yang         if (!cover_item.isEmpty())
621b4284970SZhong Yang         {
622b4284970SZhong Yang             const auto& pic_data = cover_item.front().data();
623d2d85fe1SZhong Yang             //获取专辑封面
624b4284970SZhong Yang             cover_contents.assign(pic_data.data(), pic_data.size());
625b4284970SZhong Yang 
626d2d85fe1SZhong Yang             //获取封面格式
627b4284970SZhong Yang             switch (cover_item.front().format())
628b4284970SZhong Yang             {
629b4284970SZhong Yang             case MP4::CoverArt::JPEG:
630b4284970SZhong Yang                 type = 0;
631b4284970SZhong Yang                 break;
632b4284970SZhong Yang             case MP4::CoverArt::PNG:
633b4284970SZhong Yang                 type = 1;
634b4284970SZhong Yang                 break;
635b4284970SZhong Yang             case MP4::CoverArt::BMP:
636b4284970SZhong Yang                 type = 3;
637b4284970SZhong Yang                 break;
638b4284970SZhong Yang             case MP4::CoverArt::GIF:
639b4284970SZhong Yang                 type = 2;
640b4284970SZhong Yang                 break;
641b4284970SZhong Yang             default:
642b4284970SZhong Yang                 type = -1;
643b4284970SZhong Yang                 break;
644b4284970SZhong Yang             }
645b4284970SZhong Yang         }
646b4284970SZhong Yang     }
647b4284970SZhong Yang     return cover_contents;
648b4284970SZhong Yang }
649b4284970SZhong Yang 
GetFlacAlbumCover(const std::wstring & file_path,int & type)6502715cf48SZhong Yang string CTagLibHelper::GetFlacAlbumCover(const std::wstring& file_path, int& type)
651b4284970SZhong Yang {
652b4284970SZhong Yang     string cover_contents;
653b4284970SZhong Yang     FLAC::File file(file_path.c_str());
654b4284970SZhong Yang     const auto& cover_list = file.pictureList();
655b4284970SZhong Yang     if (!cover_list.isEmpty())
656b4284970SZhong Yang     {
657b4284970SZhong Yang         auto pic = cover_list.front();
658b4284970SZhong Yang         if (pic != nullptr)
659b4284970SZhong Yang         {
660b4284970SZhong Yang             const auto& pic_data = pic->data();
661d2d85fe1SZhong Yang             //获取专辑封面
662b4284970SZhong Yang             cover_contents.assign(pic_data.data(), pic_data.size());
663b4284970SZhong Yang 
6642715cf48SZhong Yang             std::wstring img_type = pic->mimeType().toCWString();
665b4284970SZhong Yang             type = GetPicType(img_type);
666b4284970SZhong Yang         }
667b4284970SZhong Yang     }
668b4284970SZhong Yang     return cover_contents;
669b4284970SZhong Yang }
670b4284970SZhong Yang 
GetMp3AlbumCover(const std::wstring & file_path,int & type)6712715cf48SZhong Yang string CTagLibHelper::GetMp3AlbumCover(const std::wstring& file_path, int& type)
672b4284970SZhong Yang {
673b4284970SZhong Yang     string cover_contents;
674b4284970SZhong Yang     MPEG::File file(file_path.c_str());
675b4284970SZhong Yang     auto id3v2 = file.ID3v2Tag();
676b4284970SZhong Yang     GetId3v2AlbumCover(id3v2, cover_contents, type);
677b4284970SZhong Yang     return cover_contents;
678b4284970SZhong Yang }
679b4284970SZhong Yang 
GetAsfAlbumCover(const std::wstring & file_path,int & type)6802715cf48SZhong Yang string CTagLibHelper::GetAsfAlbumCover(const std::wstring& file_path, int& type)
681b4284970SZhong Yang {
682b4284970SZhong Yang     string cover_contents;
683b4284970SZhong Yang     ASF::File file(file_path.c_str());
684b4284970SZhong Yang     auto tag = file.tag();
685b4284970SZhong Yang     if (tag != nullptr)
686b4284970SZhong Yang     {
687b4284970SZhong Yang         ASF::AttributeList attr = tag->attribute("WM/Picture");
688b4284970SZhong Yang         if (!attr.isEmpty())
689b4284970SZhong Yang         {
690b4284970SZhong Yang             ASF::Picture picture = attr.front().toPicture();
691b4284970SZhong Yang             auto pic_data = picture.picture();
692b4284970SZhong Yang             cover_contents.assign(pic_data.data(), pic_data.size());
6932715cf48SZhong Yang             std::wstring img_type = picture.mimeType().toCWString();
694b4284970SZhong Yang             type = GetPicType(img_type);
695b4284970SZhong Yang         }
696b4284970SZhong Yang     }
697b4284970SZhong Yang     return cover_contents;
698b4284970SZhong Yang }
699b4284970SZhong Yang 
GetWavAlbumCover(const std::wstring & file_path,int & type)7002715cf48SZhong Yang string CTagLibHelper::GetWavAlbumCover(const std::wstring& file_path, int& type)
701b4284970SZhong Yang {
702b4284970SZhong Yang     string cover_contents;
703b4284970SZhong Yang     RIFF::WAV::File file(file_path.c_str());
704b4284970SZhong Yang     auto id3v2 = file.ID3v2Tag();
705b4284970SZhong Yang     GetId3v2AlbumCover(id3v2, cover_contents, type);
706b4284970SZhong Yang     return cover_contents;
707b4284970SZhong Yang }
708b4284970SZhong Yang 
GetTtaAlbumCover(const std::wstring & file_path,int & type)7092715cf48SZhong Yang string CTagLibHelper::GetTtaAlbumCover(const std::wstring& file_path, int& type)
710b4284970SZhong Yang {
711b4284970SZhong Yang     string cover_contents;
712b4284970SZhong Yang     TrueAudio::File file(file_path.c_str());
713b4284970SZhong Yang     auto id3v2 = file.ID3v2Tag();
714b4284970SZhong Yang     GetId3v2AlbumCover(id3v2, cover_contents, type);
715b4284970SZhong Yang     return cover_contents;
716b4284970SZhong Yang }
717b4284970SZhong Yang 
GetApeAlbumCover(const std::wstring & file_path,int & type)7182715cf48SZhong Yang string CTagLibHelper::GetApeAlbumCover(const std::wstring& file_path, int& type)
719b4284970SZhong Yang {
720b4284970SZhong Yang     string cover_contents;
721b4284970SZhong Yang     APE::File file(file_path.c_str());
722b4284970SZhong Yang     auto tag = file.APETag();
723b4284970SZhong Yang     GetApeTagAlbumCover(tag, cover_contents, type);
724b4284970SZhong Yang     return cover_contents;
725b4284970SZhong Yang }
726b4284970SZhong Yang 
727de03cfedSZhong Yang 
GetOggAlbumCover(const std::wstring & file_path,int & type)7282715cf48SZhong Yang string CTagLibHelper::GetOggAlbumCover(const std::wstring& file_path, int& type)
729de03cfedSZhong Yang {
730de03cfedSZhong Yang     string cover_contents;
731de03cfedSZhong Yang     Ogg::Vorbis::File file(file_path.c_str());
732de03cfedSZhong Yang     auto tag = file.tag();
733de03cfedSZhong Yang     if (tag != nullptr)
734de03cfedSZhong Yang     {
735de03cfedSZhong Yang         GetXiphCommentAlbumCover(tag, cover_contents, type);
736de03cfedSZhong Yang     }
737de03cfedSZhong Yang     return cover_contents;
738de03cfedSZhong Yang }
739de03cfedSZhong Yang 
GetOpusAlbumCover(const std::wstring & file_path,int & type)7402715cf48SZhong Yang string CTagLibHelper::GetOpusAlbumCover(const std::wstring& file_path, int& type)
741de03cfedSZhong Yang {
742de03cfedSZhong Yang     string cover_contents;
743de03cfedSZhong Yang     Ogg::Opus::File file(file_path.c_str());
744de03cfedSZhong Yang     auto tag = file.tag();
745de03cfedSZhong Yang     if (tag != nullptr)
746de03cfedSZhong Yang     {
747de03cfedSZhong Yang         GetXiphCommentAlbumCover(tag, cover_contents, type);
748de03cfedSZhong Yang     }
749de03cfedSZhong Yang     return cover_contents;
750de03cfedSZhong Yang }
751de03cfedSZhong Yang 
GetSpxAlbumCover(const std::wstring & file_path,int & type)7522715cf48SZhong Yang string CTagLibHelper::GetSpxAlbumCover(const std::wstring& file_path, int& type)
753de03cfedSZhong Yang {
754de03cfedSZhong Yang     string cover_contents;
755de03cfedSZhong Yang     Ogg::Speex::File file(file_path.c_str());
756de03cfedSZhong Yang     auto tag = file.tag();
757de03cfedSZhong Yang     if (tag != nullptr)
758de03cfedSZhong Yang     {
759de03cfedSZhong Yang         GetXiphCommentAlbumCover(tag, cover_contents, type);
760de03cfedSZhong Yang     }
761de03cfedSZhong Yang     return cover_contents;
762de03cfedSZhong Yang }
763de03cfedSZhong Yang 
GetAiffAlbumCover(const std::wstring & file_path,int & type)7642715cf48SZhong Yang string CTagLibHelper::GetAiffAlbumCover(const std::wstring& file_path, int& type)
7656067fa7dSZhong Yang {
7666067fa7dSZhong Yang     string cover_contents;
7676067fa7dSZhong Yang     RIFF::AIFF::File file(file_path.c_str());
7686067fa7dSZhong Yang     auto id3v2 = file.tag();
7696067fa7dSZhong Yang     GetId3v2AlbumCover(id3v2, cover_contents, type);
7706067fa7dSZhong Yang     return cover_contents;
7716067fa7dSZhong Yang 
7726067fa7dSZhong Yang }
7736067fa7dSZhong Yang 
GetMpcAlbumCover(const std::wstring & file_path,int & type)7742715cf48SZhong Yang string CTagLibHelper::GetMpcAlbumCover(const std::wstring& file_path, int& type)
7757172d8f8SZhong Yang {
7767172d8f8SZhong Yang     string cover_contents;
7777172d8f8SZhong Yang     MPC::File file(file_path.c_str());
7787172d8f8SZhong Yang     auto ape_tag = file.APETag();
7797172d8f8SZhong Yang     GetApeTagAlbumCover(ape_tag, cover_contents, type);
7807172d8f8SZhong Yang     return cover_contents;
7817172d8f8SZhong Yang }
7827172d8f8SZhong Yang 
GetWavePackAlbumCover(const std::wstring & file_path,int & type)7832715cf48SZhong Yang string CTagLibHelper::GetWavePackAlbumCover(const std::wstring& file_path, int& type)
7847172d8f8SZhong Yang {
7857172d8f8SZhong Yang     string cover_contents;
7867172d8f8SZhong Yang     WavPack::File file(file_path.c_str());
7877172d8f8SZhong Yang     auto ape_tag = file.APETag();
7887172d8f8SZhong Yang     GetApeTagAlbumCover(ape_tag, cover_contents, type);
7897172d8f8SZhong Yang     return cover_contents;
7907172d8f8SZhong Yang }
7917172d8f8SZhong Yang 
GetFlacTagInfo(SongInfo & song_info)792b4284970SZhong Yang void CTagLibHelper::GetFlacTagInfo(SongInfo& song_info)
793b4284970SZhong Yang {
794b4284970SZhong Yang     FLAC::File file(song_info.file_path.c_str());
795b4284970SZhong Yang     if (file.hasID3v1Tag())
796b4284970SZhong Yang         song_info.tag_type |= T_ID3V1;
797b4284970SZhong Yang     if (file.hasID3v2Tag())
798b4284970SZhong Yang         song_info.tag_type |= T_ID3V2;
799b4284970SZhong Yang     auto tag = file.tag();
800b4284970SZhong Yang     if (tag != nullptr)
801b4284970SZhong Yang     {
80270540c1aSZhong Yang         TagToSongInfo(song_info, tag, true);
803b4284970SZhong Yang     }
804fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
805fbf97538Szhongyang219     getFlacPropertyMap(file, property_map);
806fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
807b4284970SZhong Yang }
808b4284970SZhong Yang 
GetM4aTagInfo(SongInfo & song_info)809b4284970SZhong Yang void CTagLibHelper::GetM4aTagInfo(SongInfo& song_info)
810b4284970SZhong Yang {
811b4284970SZhong Yang     MP4::File file(song_info.file_path.c_str());
812b4284970SZhong Yang     if (file.hasMP4Tag())
813b4284970SZhong Yang         song_info.tag_type |= T_MP4;
814b4284970SZhong Yang     auto tag = file.tag();
815b4284970SZhong Yang     if (tag != nullptr)
816b4284970SZhong Yang     {
817ea6fbf76SZhong Yang         TagToSongInfo(song_info, tag, false);
818b4284970SZhong Yang     }
819fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
820fbf97538Szhongyang219     getM4aPropertyMap(file, property_map);
821fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
822b4284970SZhong Yang }
823b4284970SZhong Yang 
GetMpegTagInfo(SongInfo & song_info)824b4284970SZhong Yang void CTagLibHelper::GetMpegTagInfo(SongInfo& song_info)
825b4284970SZhong Yang {
826b4284970SZhong Yang     MPEG::File file(song_info.file_path.c_str());
827b4284970SZhong Yang     if (file.hasID3v1Tag())
828b4284970SZhong Yang         song_info.tag_type |= T_ID3V1;
829b4284970SZhong Yang     if (file.hasID3v2Tag())
830b4284970SZhong Yang         song_info.tag_type |= T_ID3V2;
831b4284970SZhong Yang     if (file.hasAPETag())
832b4284970SZhong Yang         song_info.tag_type |= T_APE;
833b4284970SZhong Yang 
834b4284970SZhong Yang     auto tag = file.tag();
835b4284970SZhong Yang     if (tag != nullptr)
836b4284970SZhong Yang     {
83770540c1aSZhong Yang         TagToSongInfo(song_info, tag, true);
838b4284970SZhong Yang     }
839fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
840fbf97538Szhongyang219     getMpegPropertyMap(file, property_map);
841fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
842b4284970SZhong Yang }
843b4284970SZhong Yang 
GetAsfTagInfo(SongInfo & song_info)844b4284970SZhong Yang void CTagLibHelper::GetAsfTagInfo(SongInfo& song_info)
845b4284970SZhong Yang {
846b4284970SZhong Yang     ASF::File file(song_info.file_path.c_str());
847b4284970SZhong Yang     auto tag = file.tag();
848b4284970SZhong Yang     if (tag != nullptr)
849b4284970SZhong Yang     {
850ea6fbf76SZhong Yang         TagToSongInfo(song_info, tag, false);
851b4284970SZhong Yang     }
852fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
853fbf97538Szhongyang219     getAsfPropertyMap(file, property_map);
854fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
855b4284970SZhong Yang }
856b4284970SZhong Yang 
GetApeTagInfo(SongInfo & song_info)857b4284970SZhong Yang void CTagLibHelper::GetApeTagInfo(SongInfo& song_info)
858b4284970SZhong Yang {
859b4284970SZhong Yang     APE::File file(song_info.file_path.c_str());
860b4284970SZhong Yang     if (file.hasID3v1Tag())
861b4284970SZhong Yang         song_info.tag_type |= T_ID3V1;
862b4284970SZhong Yang     if (file.hasAPETag())
863b4284970SZhong Yang         song_info.tag_type |= T_APE;
864b4284970SZhong Yang 
865b4284970SZhong Yang     auto tag = file.tag();
866b4284970SZhong Yang     if (tag != nullptr)
867b4284970SZhong Yang     {
86870540c1aSZhong Yang         TagToSongInfo(song_info, tag, true);
869b4284970SZhong Yang     }
870fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
871fbf97538Szhongyang219     getApePropertyMap(file, property_map);
872fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
873b4284970SZhong Yang }
874b4284970SZhong Yang 
GetWavTagInfo(SongInfo & song_info)875b4284970SZhong Yang void CTagLibHelper::GetWavTagInfo(SongInfo& song_info)
876b4284970SZhong Yang {
877b4284970SZhong Yang     RIFF::WAV::File file(song_info.file_path.c_str());
878b4284970SZhong Yang     if (file.hasID3v2Tag())
879b4284970SZhong Yang         song_info.tag_type |= T_ID3V2;
880b4284970SZhong Yang     if (file.hasInfoTag())
881b4284970SZhong Yang         song_info.tag_type |= T_RIFF;
882b4284970SZhong Yang     auto tag = file.tag();
883b4284970SZhong Yang     if (tag != nullptr)
884b4284970SZhong Yang     {
885ea6fbf76SZhong Yang         TagToSongInfo(song_info, tag, false);
886b4284970SZhong Yang     }
887fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
888fbf97538Szhongyang219     getWavPropertyMap(file, property_map);
889fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
890b4284970SZhong Yang }
891b4284970SZhong Yang 
GetOggTagInfo(SongInfo & song_info)892b4284970SZhong Yang void CTagLibHelper::GetOggTagInfo(SongInfo& song_info)
893b4284970SZhong Yang {
894b4284970SZhong Yang     Vorbis::File file(song_info.file_path.c_str());
895b4284970SZhong Yang     auto tag = file.tag();
896b4284970SZhong Yang     if (tag != nullptr)
897b4284970SZhong Yang     {
898ea6fbf76SZhong Yang         TagToSongInfo(song_info, tag, false);
899b4284970SZhong Yang     }
900fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
901fbf97538Szhongyang219     getOggPropertyMap(file, property_map);
902fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
903b4284970SZhong Yang }
904b4284970SZhong Yang 
GetMpcTagInfo(SongInfo & song_info)905b4284970SZhong Yang void CTagLibHelper::GetMpcTagInfo(SongInfo& song_info)
906b4284970SZhong Yang {
907b4284970SZhong Yang     MPC::File file(song_info.file_path.c_str());
908b4284970SZhong Yang     if (file.hasAPETag())
909b4284970SZhong Yang         song_info.tag_type |= T_APE;
910b4284970SZhong Yang     if (file.hasID3v1Tag())
911b4284970SZhong Yang         song_info.tag_type |= T_ID3V1;
912b4284970SZhong Yang     auto tag = file.tag();
913b4284970SZhong Yang     if (tag != nullptr)
914b4284970SZhong Yang     {
91570540c1aSZhong Yang         TagToSongInfo(song_info, tag, true);
916b4284970SZhong Yang     }
917fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
918fbf97538Szhongyang219     getMpcPropertyMap(file, property_map);
919fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
920b4284970SZhong Yang }
921b4284970SZhong Yang 
GetOpusTagInfo(SongInfo & song_info)922b4284970SZhong Yang void CTagLibHelper::GetOpusTagInfo(SongInfo& song_info)
923b4284970SZhong Yang {
924b4284970SZhong Yang     Ogg::Opus::File file(song_info.file_path.c_str());
925b4284970SZhong Yang     auto tag = file.tag();
926b4284970SZhong Yang     if (tag != nullptr)
927b4284970SZhong Yang     {
928ea6fbf76SZhong Yang         TagToSongInfo(song_info, tag, false);
929b4284970SZhong Yang     }
930fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
931fbf97538Szhongyang219     getOpusPropertyMap(file, property_map);
932fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
933b4284970SZhong Yang }
934b4284970SZhong Yang 
GetWavPackTagInfo(SongInfo & song_info)935b4284970SZhong Yang void CTagLibHelper::GetWavPackTagInfo(SongInfo& song_info)
936b4284970SZhong Yang {
937b4284970SZhong Yang     WavPack::File file(song_info.file_path.c_str());
938b4284970SZhong Yang     if (file.hasAPETag())
939b4284970SZhong Yang         song_info.tag_type |= T_APE;
940b4284970SZhong Yang     if (file.hasID3v1Tag())
941b4284970SZhong Yang         song_info.tag_type |= T_ID3V1;
942b4284970SZhong Yang     auto tag = file.tag();
943b4284970SZhong Yang     if (tag != nullptr)
944b4284970SZhong Yang     {
94570540c1aSZhong Yang         TagToSongInfo(song_info, tag, true);
946b4284970SZhong Yang     }
947fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
948fbf97538Szhongyang219     getWavPackPropertyMap(file, property_map);
949fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
950b4284970SZhong Yang }
951b4284970SZhong Yang 
GetTtaTagInfo(SongInfo & song_info)952b4284970SZhong Yang void CTagLibHelper::GetTtaTagInfo(SongInfo& song_info)
953b4284970SZhong Yang {
954b4284970SZhong Yang     TrueAudio::File file(song_info.file_path.c_str());
955b4284970SZhong Yang     if (file.hasID3v1Tag())
956b4284970SZhong Yang         song_info.tag_type |= T_ID3V1;
957b4284970SZhong Yang     if (file.hasID3v2Tag())
958b4284970SZhong Yang         song_info.tag_type |= T_ID3V2;
959b4284970SZhong Yang     auto tag = file.tag();
960b4284970SZhong Yang     if (tag != nullptr)
961b4284970SZhong Yang     {
96270540c1aSZhong Yang         TagToSongInfo(song_info, tag, true);
963b4284970SZhong Yang     }
964fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
965fbf97538Szhongyang219     getTtaPropertyMap(file, property_map);
966fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
967b4284970SZhong Yang }
968b4284970SZhong Yang 
GetAiffTagInfo(SongInfo & song_info)969b4284970SZhong Yang void CTagLibHelper::GetAiffTagInfo(SongInfo& song_info)
970b4284970SZhong Yang {
971b4284970SZhong Yang     RIFF::AIFF::File file(song_info.file_path.c_str());
972b4284970SZhong Yang     if (file.hasID3v2Tag())
973b4284970SZhong Yang         song_info.tag_type |= T_ID3V2;
974b4284970SZhong Yang     auto tag = file.tag();
975b4284970SZhong Yang     if (tag != nullptr)
976b4284970SZhong Yang     {
977ea6fbf76SZhong Yang         TagToSongInfo(song_info, tag, false);
978b4284970SZhong Yang     }
979fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
980fbf97538Szhongyang219     getAiffPropertyMap(file, property_map);
981fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
982b4284970SZhong Yang }
983b4284970SZhong Yang 
GetSpxTagInfo(SongInfo & song_info)984b86d7e7aSZhong Yang void CTagLibHelper::GetSpxTagInfo(SongInfo& song_info)
985b86d7e7aSZhong Yang {
986b86d7e7aSZhong Yang     Ogg::Speex::File file(song_info.file_path.c_str());
987b86d7e7aSZhong Yang     auto tag = file.tag();
988b86d7e7aSZhong Yang     if (tag != nullptr)
989b86d7e7aSZhong Yang     {
990ea6fbf76SZhong Yang         TagToSongInfo(song_info, tag, false);
991b86d7e7aSZhong Yang     }
992fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
993fbf97538Szhongyang219     getSpxPropertyMap(file, property_map);
994fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
995b86d7e7aSZhong Yang }
996b86d7e7aSZhong Yang 
GetAnyFileTagInfo(SongInfo & song_info)997b4284970SZhong Yang void CTagLibHelper::GetAnyFileTagInfo(SongInfo& song_info)
998b4284970SZhong Yang {
999b4284970SZhong Yang     FileRef file(song_info.file_path.c_str());
1000b4284970SZhong Yang     auto tag = file.tag();
1001b4284970SZhong Yang     if (tag != nullptr)
1002b4284970SZhong Yang     {
1003ea6fbf76SZhong Yang         TagToSongInfo(song_info, tag, false);
1004b4284970SZhong Yang     }
1005fbf97538Szhongyang219     std::map<std::wstring, std::wstring> property_map;
1006fbf97538Szhongyang219     getAnyFilePropertyMap(file, property_map);
1007fbf97538Szhongyang219     OtherPropertyToSongInfo(song_info, property_map);
1008b4284970SZhong Yang }
1009b4284970SZhong Yang 
GetFlacPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10102715cf48SZhong Yang void CTagLibHelper::GetFlacPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
101167323609SZhong Yang {
101267323609SZhong Yang     FLAC::File file(file_path.c_str());
1013fbf97538Szhongyang219     getFlacPropertyMap(file, property_map);
101467323609SZhong Yang }
101567323609SZhong Yang 
GetM4aPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10162715cf48SZhong Yang void CTagLibHelper::GetM4aPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
101767323609SZhong Yang {
101867323609SZhong Yang     MP4::File file(file_path.c_str());
1019fbf97538Szhongyang219     getM4aPropertyMap(file, property_map);
102067323609SZhong Yang }
102167323609SZhong Yang 
GetMpegPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10222715cf48SZhong Yang void CTagLibHelper::GetMpegPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
102367323609SZhong Yang {
102467323609SZhong Yang     MPEG::File file(file_path.c_str());
1025fbf97538Szhongyang219     getMpegPropertyMap(file, property_map);
102667323609SZhong Yang }
102767323609SZhong Yang 
GetAsfPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10282715cf48SZhong Yang void CTagLibHelper::GetAsfPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
102967323609SZhong Yang {
103067323609SZhong Yang     ASF::File file(file_path.c_str());
1031fbf97538Szhongyang219     getAsfPropertyMap(file, property_map);
103267323609SZhong Yang }
103367323609SZhong Yang 
GetApePropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10342715cf48SZhong Yang void CTagLibHelper::GetApePropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
103567323609SZhong Yang {
103667323609SZhong Yang     APE::File file(file_path.c_str());
1037fbf97538Szhongyang219     getApePropertyMap(file, property_map);
103867323609SZhong Yang }
103967323609SZhong Yang 
GetWavPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10402715cf48SZhong Yang void CTagLibHelper::GetWavPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
104167323609SZhong Yang {
104267323609SZhong Yang     RIFF::WAV::File file(file_path.c_str());
1043fbf97538Szhongyang219     getWavPropertyMap(file, property_map);
104467323609SZhong Yang }
104567323609SZhong Yang 
GetOggPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10462715cf48SZhong Yang void CTagLibHelper::GetOggPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
104767323609SZhong Yang {
104867323609SZhong Yang     Vorbis::File file(file_path.c_str());
1049fbf97538Szhongyang219     getOggPropertyMap(file, property_map);
105067323609SZhong Yang }
105167323609SZhong Yang 
GetMpcPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10522715cf48SZhong Yang void CTagLibHelper::GetMpcPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
105367323609SZhong Yang {
105467323609SZhong Yang     MPC::File file(file_path.c_str());
1055fbf97538Szhongyang219     getMpcPropertyMap(file, property_map);
105667323609SZhong Yang }
105767323609SZhong Yang 
GetOpusPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10582715cf48SZhong Yang void CTagLibHelper::GetOpusPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
105967323609SZhong Yang {
106067323609SZhong Yang     Ogg::Opus::File file(file_path.c_str());
1061fbf97538Szhongyang219     getOpusPropertyMap(file, property_map);
106267323609SZhong Yang }
106367323609SZhong Yang 
GetWavPackPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10642715cf48SZhong Yang void CTagLibHelper::GetWavPackPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
106567323609SZhong Yang {
106667323609SZhong Yang     WavPack::File file(file_path.c_str());
1067fbf97538Szhongyang219     getWavPackPropertyMap(file, property_map);
106867323609SZhong Yang }
106967323609SZhong Yang 
GetTtaPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10702715cf48SZhong Yang void CTagLibHelper::GetTtaPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
107167323609SZhong Yang {
107267323609SZhong Yang     TrueAudio::File file(file_path.c_str());
1073fbf97538Szhongyang219     getTtaPropertyMap(file, property_map);
107467323609SZhong Yang }
107567323609SZhong Yang 
GetAiffPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10762715cf48SZhong Yang void CTagLibHelper::GetAiffPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
107767323609SZhong Yang {
107867323609SZhong Yang     RIFF::AIFF::File file(file_path.c_str());
1079fbf97538Szhongyang219     getAiffPropertyMap(file, property_map);
108067323609SZhong Yang }
108167323609SZhong Yang 
GetSpxPropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10822715cf48SZhong Yang void CTagLibHelper::GetSpxPropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
108367323609SZhong Yang {
108467323609SZhong Yang     Ogg::Speex::File file(file_path.c_str());
1085fbf97538Szhongyang219     getSpxPropertyMap(file, property_map);
108667323609SZhong Yang }
108767323609SZhong Yang 
GetAnyFilePropertyMap(const std::wstring & file_path,std::map<std::wstring,std::wstring> & property_map)10882715cf48SZhong Yang void CTagLibHelper::GetAnyFilePropertyMap(const std::wstring& file_path, std::map<std::wstring, std::wstring>& property_map)
108967323609SZhong Yang {
109067323609SZhong Yang     FileRef file(file_path.c_str());
1091fbf97538Szhongyang219     getAnyFilePropertyMap(file, property_map);
109267323609SZhong Yang }
109367323609SZhong Yang 
GetMpegLyric(const std::wstring & file_path)10942715cf48SZhong Yang std::wstring CTagLibHelper::GetMpegLyric(const std::wstring& file_path)
1095b4284970SZhong Yang {
1096b4284970SZhong Yang     MPEG::File file(file_path.c_str());
1097b4284970SZhong Yang     auto id3v2 = file.ID3v2Tag();
1098e5862982SZhong Yang     return GetId3v2Lyric(id3v2);
1099b4284970SZhong Yang }
1100b4284970SZhong Yang 
GetM4aLyric(const std::wstring & file_path)11012715cf48SZhong Yang std::wstring CTagLibHelper::GetM4aLyric(const std::wstring& file_path)
1102b4284970SZhong Yang {
11032715cf48SZhong Yang     std::wstring lyrics;
1104b4284970SZhong Yang     MP4::File file(file_path.c_str());
1105b4284970SZhong Yang     auto tag = file.tag();
1106b4284970SZhong Yang     if (tag != nullptr)
1107b4284970SZhong Yang     {
1108b4284970SZhong Yang         auto item_map = file.tag()->itemMap();
1109b4284970SZhong Yang         auto lyric_item = item_map[STR_MP4_LYRICS_TAG].toStringList();;
1110b4284970SZhong Yang         if (!lyric_item.isEmpty())
1111b4284970SZhong Yang             lyrics = lyric_item.front().toWString();
1112b4284970SZhong Yang     }
1113b4284970SZhong Yang     return lyrics;
1114b4284970SZhong Yang }
1115b4284970SZhong Yang 
GetFlacLyric(const std::wstring & file_path)11162715cf48SZhong Yang std::wstring CTagLibHelper::GetFlacLyric(const std::wstring& file_path)
1117b4284970SZhong Yang {
11182715cf48SZhong Yang     std::wstring lyrics;
1119b4284970SZhong Yang     FLAC::File file(file_path.c_str());
1120b4284970SZhong Yang     auto properties = file.properties();
1121fefb2ef6SZhong Yang     if (file.isValid())
1122fefb2ef6SZhong Yang     {
1123deb58856SZhong Yang         auto lyric_item = properties[STR_FLAC_LYRIC_TAG];
1124b4284970SZhong Yang         if (!lyric_item.isEmpty())
1125b4284970SZhong Yang         {
1126b4284970SZhong Yang             lyrics = lyric_item.front().toWString();
1127b4284970SZhong Yang         }
1128fefb2ef6SZhong Yang     }
1129b4284970SZhong Yang     return lyrics;
1130b4284970SZhong Yang }
1131b4284970SZhong Yang 
GetAsfLyric(const std::wstring & file_path)11322715cf48SZhong Yang std::wstring CTagLibHelper::GetAsfLyric(const std::wstring& file_path)
1133b4284970SZhong Yang {
11342715cf48SZhong Yang     std::wstring lyrics;
1135b4284970SZhong Yang     ASF::File file(file_path.c_str());
1136fefb2ef6SZhong Yang     if (file.isValid())
1137fefb2ef6SZhong Yang     {
1138b4284970SZhong Yang         auto properties = file.properties();
11390efbb7bcSZhong Yang         auto lyric_item = properties[STR_ASF_LYRIC_TAG];
1140b4284970SZhong Yang         if (!lyric_item.isEmpty())
1141b4284970SZhong Yang         {
1142b4284970SZhong Yang             lyrics = lyric_item.front().toWString();
1143b4284970SZhong Yang         }
1144fefb2ef6SZhong Yang     }
1145b4284970SZhong Yang     return lyrics;
1146b4284970SZhong Yang }
1147b4284970SZhong Yang 
1148b4284970SZhong Yang 
GetWavLyric(const std::wstring & file_path)11492715cf48SZhong Yang std::wstring CTagLibHelper::GetWavLyric(const std::wstring& file_path)
1150e5862982SZhong Yang {
1151e5862982SZhong Yang     RIFF::WAV::File file(file_path.c_str());
1152e5862982SZhong Yang     auto id3v2 = file.ID3v2Tag();
1153e5862982SZhong Yang     return GetId3v2Lyric(id3v2);
1154e5862982SZhong Yang 
1155e5862982SZhong Yang }
1156e5862982SZhong Yang 
WriteMpegLyric(const std::wstring & file_path,const std::wstring & lyric_contents)11572715cf48SZhong Yang bool CTagLibHelper::WriteMpegLyric(const std::wstring& file_path, const std::wstring& lyric_contents)
115834f69099SZhong Yang {
11592715cf48SZhong Yang     std::wstring lyrics;
116034f69099SZhong Yang     MPEG::File file(file_path.c_str());
116134f69099SZhong Yang     auto id3v2 = file.ID3v2Tag();
1162e5862982SZhong Yang     WriteId3v2Lyric(id3v2, lyric_contents);
116334f69099SZhong Yang     int tags = MPEG::File::ID3v2;
116434f69099SZhong Yang     if (file.hasAPETag())
116534f69099SZhong Yang         tags |= MPEG::File::APE;
116603045520Szhongyang219     bool saved = file.save(tags, File::StripOthers, GetWriteId3v2Version());
116734f69099SZhong Yang     return saved;
116834f69099SZhong Yang }
116934f69099SZhong Yang 
WriteFlacLyric(const std::wstring & file_path,const std::wstring & lyric_contents)11702715cf48SZhong Yang bool CTagLibHelper::WriteFlacLyric(const std::wstring& file_path, const std::wstring& lyric_contents)
1171deb58856SZhong Yang {
1172deb58856SZhong Yang     FLAC::File file(file_path.c_str());
1173fefb2ef6SZhong Yang     if (file.isValid())
1174fefb2ef6SZhong Yang     {
1175deb58856SZhong Yang         auto properties = file.properties();
1176deb58856SZhong Yang         if (lyric_contents.empty())
1177deb58856SZhong Yang         {
1178deb58856SZhong Yang             properties.erase(STR_FLAC_LYRIC_TAG);
1179deb58856SZhong Yang         }
1180deb58856SZhong Yang         else
1181deb58856SZhong Yang         {
1182deb58856SZhong Yang             StringList lyric_item;
1183deb58856SZhong Yang             lyric_item.append(lyric_contents);
1184deb58856SZhong Yang             properties[STR_FLAC_LYRIC_TAG] = lyric_item;
1185deb58856SZhong Yang         }
1186deb58856SZhong Yang         file.setProperties(properties);
1187deb58856SZhong Yang         bool saved = file.save();
1188deb58856SZhong Yang         return saved;
1189deb58856SZhong Yang     }
1190fefb2ef6SZhong Yang     return false;
1191fefb2ef6SZhong Yang }
1192deb58856SZhong Yang 
WriteM4aLyric(const std::wstring & file_path,const std::wstring & lyric_contents)11932715cf48SZhong Yang bool CTagLibHelper::WriteM4aLyric(const std::wstring& file_path, const std::wstring& lyric_contents)
11948fb4cd22SZhong Yang {
11958fb4cd22SZhong Yang     MP4::File file(file_path.c_str());
11968fb4cd22SZhong Yang     auto tag = file.tag();
11978fb4cd22SZhong Yang     if (tag != nullptr)
11988fb4cd22SZhong Yang     {
11998fb4cd22SZhong Yang         if (lyric_contents.empty())
12008fb4cd22SZhong Yang         {
12018fb4cd22SZhong Yang             tag->removeItem(STR_MP4_LYRICS_TAG);
12028fb4cd22SZhong Yang         }
12038fb4cd22SZhong Yang         else
12048fb4cd22SZhong Yang         {
12058fb4cd22SZhong Yang             StringList lyric_list;
12068fb4cd22SZhong Yang             lyric_list.append(lyric_contents);
12078fb4cd22SZhong Yang             MP4::Item lyrics_item(lyric_list);
12088fb4cd22SZhong Yang             tag->setItem(STR_MP4_LYRICS_TAG, lyrics_item);
12098fb4cd22SZhong Yang         }
12108fb4cd22SZhong Yang         bool saved = file.save();
12118fb4cd22SZhong Yang         return saved;
12128fb4cd22SZhong Yang     }
12138fb4cd22SZhong Yang     return false;
12148fb4cd22SZhong Yang }
12158fb4cd22SZhong Yang 
WriteAsfLyric(const std::wstring & file_path,const std::wstring & lyric_contents)12162715cf48SZhong Yang bool CTagLibHelper::WriteAsfLyric(const std::wstring& file_path, const std::wstring& lyric_contents)
12170efbb7bcSZhong Yang {
12180efbb7bcSZhong Yang     ASF::File file(file_path.c_str());
1219fefb2ef6SZhong Yang     if (file.isValid())
1220fefb2ef6SZhong Yang     {
12210efbb7bcSZhong Yang         auto properties = file.properties();
12220efbb7bcSZhong Yang         if (lyric_contents.empty())
12230efbb7bcSZhong Yang         {
12240efbb7bcSZhong Yang             properties.erase(STR_ASF_LYRIC_TAG);
12250efbb7bcSZhong Yang         }
12260efbb7bcSZhong Yang         else
12270efbb7bcSZhong Yang         {
12280efbb7bcSZhong Yang             StringList lyric_item;
12290efbb7bcSZhong Yang             lyric_item.append(lyric_contents);
12300efbb7bcSZhong Yang             properties[STR_ASF_LYRIC_TAG] = lyric_item;
12310efbb7bcSZhong Yang         }
12320efbb7bcSZhong Yang         file.setProperties(properties);
12330efbb7bcSZhong Yang         bool saved = file.save();
12340efbb7bcSZhong Yang         return saved;
12350efbb7bcSZhong Yang     }
1236fefb2ef6SZhong Yang     return false;
1237fefb2ef6SZhong Yang }
12380efbb7bcSZhong Yang 
WriteWavLyric(const std::wstring & file_path,const std::wstring & lyric_contents)12392715cf48SZhong Yang bool CTagLibHelper::WriteWavLyric(const std::wstring& file_path, const std::wstring& lyric_contents)
1240e5862982SZhong Yang {
12412715cf48SZhong Yang     std::wstring lyrics;
1242e5862982SZhong Yang     RIFF::WAV::File file(file_path.c_str());
1243e5862982SZhong Yang     auto id3v2 = file.ID3v2Tag();
1244e5862982SZhong Yang     WriteId3v2Lyric(id3v2, lyric_contents);
124503045520Szhongyang219     bool saved = file.save(RIFF::WAV::File::TagTypes::AllTags, File::StripOthers, GetWriteId3v2Version());
1246e5862982SZhong Yang     return saved;
1247e5862982SZhong Yang }
1248e5862982SZhong Yang 
WriteMp3AlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)12492715cf48SZhong Yang bool CTagLibHelper::WriteMp3AlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist)
1250b4284970SZhong Yang {
1251b4284970SZhong Yang     MPEG::File file(file_path.c_str());
1252b4284970SZhong Yang     if (!file.isValid())
1253b4284970SZhong Yang         return false;
1254b4284970SZhong Yang 
1255d2d85fe1SZhong Yang     //先删除专辑封面
1256b4284970SZhong Yang     if (remove_exist)
1257b4284970SZhong Yang     {
1258b4284970SZhong Yang         auto id3v2tag = file.ID3v2Tag();
1259b4284970SZhong Yang         DeleteId3v2AlbumCover(id3v2tag);
1260b4284970SZhong Yang     }
1261b4284970SZhong Yang     if (!album_cover_path.empty())
1262b4284970SZhong Yang     {
1263b4284970SZhong Yang         auto id3v2tag = file.ID3v2Tag(true);
1264b4284970SZhong Yang         WriteId3v2AlbumCover(id3v2tag, album_cover_path);
1265b4284970SZhong Yang     }
126634f69099SZhong Yang     int tags = MPEG::File::ID3v2;
126734f69099SZhong Yang     if (file.hasAPETag())
126834f69099SZhong Yang         tags |= MPEG::File::APE;
126903045520Szhongyang219     bool saved = file.save(tags, File::StripOthers, GetWriteId3v2Version());
1270b4284970SZhong Yang     return saved;
1271b4284970SZhong Yang }
1272b4284970SZhong Yang 
WriteFlacAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)12732715cf48SZhong Yang bool CTagLibHelper::WriteFlacAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist)
1274b4284970SZhong Yang {
1275b4284970SZhong Yang     FLAC::File file(file_path.c_str());
1276b4284970SZhong Yang     if (!file.isValid())
1277b4284970SZhong Yang         return false;
1278b4284970SZhong Yang 
1279d2d85fe1SZhong Yang     //先删除专辑封面
1280b4284970SZhong Yang     if (remove_exist)
1281b4284970SZhong Yang     {
1282b4284970SZhong Yang         file.removePictures();
1283b4284970SZhong Yang     }
1284b4284970SZhong Yang 
1285b4284970SZhong Yang     if (!album_cover_path.empty())
1286b4284970SZhong Yang     {
1287b4284970SZhong Yang         ByteVector pic_data;
1288b4284970SZhong Yang         FileToByteVector(pic_data, album_cover_path);
1289b4284970SZhong Yang         FLAC::Picture* newpic = new FLAC::Picture();
1290b4284970SZhong Yang         newpic->setType(FLAC::Picture::FrontCover);
1291b4284970SZhong Yang         newpic->setData(pic_data);
12922715cf48SZhong Yang         std::wstring ext = CFilePathHelper(album_cover_path).GetFileExtension();
1293b4284970SZhong Yang         newpic->setMimeType(L"image/" + ext);
1294b4284970SZhong Yang         file.addPicture(newpic);
1295b4284970SZhong Yang     }
1296b4284970SZhong Yang     bool saved = file.save();
1297b4284970SZhong Yang     return saved;
1298b4284970SZhong Yang }
1299b4284970SZhong Yang 
WriteM4aAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)13002715cf48SZhong Yang bool CTagLibHelper::WriteM4aAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist /*= true*/)
1301b4284970SZhong Yang {
1302b4284970SZhong Yang     MP4::File file(file_path.c_str());
1303b4284970SZhong Yang     if (!file.isValid())
1304b4284970SZhong Yang         return false;
1305b4284970SZhong Yang 
1306b4284970SZhong Yang     auto tag = file.tag();
1307b4284970SZhong Yang     if (tag == nullptr)
1308b4284970SZhong Yang         return false;
1309b4284970SZhong Yang 
1310b4284970SZhong Yang     if (remove_exist)
1311b4284970SZhong Yang     {
1312b4284970SZhong Yang         if (tag->contains(STR_MP4_COVER_TAG))
1313b4284970SZhong Yang         {
1314b4284970SZhong Yang             tag->removeItem(STR_MP4_COVER_TAG);
1315b4284970SZhong Yang         }
1316b4284970SZhong Yang     }
1317b4284970SZhong Yang 
1318b4284970SZhong Yang     if (!album_cover_path.empty())
1319b4284970SZhong Yang     {
1320b4284970SZhong Yang         ByteVector pic_data;
1321b4284970SZhong Yang         FileToByteVector(pic_data, album_cover_path);
1322b4284970SZhong Yang         MP4::CoverArt::Format format = MP4::CoverArt::Format::Unknown;
13232715cf48SZhong Yang         std::wstring ext = CFilePathHelper(album_cover_path).GetFileExtension();
1324b4284970SZhong Yang         if (ext == L"jpg" || ext == L"jpeg")
1325b4284970SZhong Yang             format = MP4::CoverArt::Format::JPEG;
1326b4284970SZhong Yang         else if (ext == L"png")
1327b4284970SZhong Yang             format = MP4::CoverArt::Format::PNG;
1328b4284970SZhong Yang         else if (ext == L"gif")
1329b4284970SZhong Yang             format = MP4::CoverArt::Format::GIF;
1330b4284970SZhong Yang         else if (ext == L"bmp")
1331b4284970SZhong Yang             format = MP4::CoverArt::Format::BMP;
1332b4284970SZhong Yang         MP4::CoverArt cover_item(format, pic_data);
1333b4284970SZhong Yang 
1334b4284970SZhong Yang         auto cover_item_list = tag->item(STR_MP4_COVER_TAG).toCoverArtList();
1335b4284970SZhong Yang         cover_item_list.append(cover_item);
1336b4284970SZhong Yang         tag->setItem(STR_MP4_COVER_TAG, cover_item_list);
1337b4284970SZhong Yang     }
1338b4284970SZhong Yang     bool saved = file.save();
1339b4284970SZhong Yang     return saved;
1340b4284970SZhong Yang }
1341b4284970SZhong Yang 
WriteAsfAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)13422715cf48SZhong Yang bool CTagLibHelper::WriteAsfAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist /*= true*/)
1343b4284970SZhong Yang {
1344b4284970SZhong Yang     ASF::File file(file_path.c_str());
1345b4284970SZhong Yang     if (!file.isValid())
1346b4284970SZhong Yang         return false;
1347b4284970SZhong Yang 
1348b4284970SZhong Yang     auto tag = file.tag();
1349b4284970SZhong Yang     if (tag == nullptr)
1350b4284970SZhong Yang         return false;
1351b4284970SZhong Yang 
1352b4284970SZhong Yang     if (remove_exist)
1353b4284970SZhong Yang     {
1354b4284970SZhong Yang         if (tag->contains(STR_ASF_COVER_TAG))
1355b4284970SZhong Yang         {
1356b4284970SZhong Yang             tag->removeItem(STR_ASF_COVER_TAG);
1357b4284970SZhong Yang         }
1358b4284970SZhong Yang     }
1359b4284970SZhong Yang 
1360b4284970SZhong Yang     if (!album_cover_path.empty())
1361b4284970SZhong Yang     {
1362b4284970SZhong Yang         ByteVector pic_data;
1363b4284970SZhong Yang         FileToByteVector(pic_data, album_cover_path);
1364b4284970SZhong Yang 
1365b4284970SZhong Yang         ASF::Picture picture;
13662715cf48SZhong Yang         std::wstring str_mine_type = L"image/" + CFilePathHelper(album_cover_path).GetFileExtension();
1367b4284970SZhong Yang         picture.setMimeType(str_mine_type);
1368b4284970SZhong Yang         picture.setType(ASF::Picture::FrontCover);
1369b4284970SZhong Yang         picture.setPicture(pic_data);
1370b4284970SZhong Yang         tag->setAttribute(STR_ASF_COVER_TAG, picture);
1371b4284970SZhong Yang     }
1372b4284970SZhong Yang     bool saved = file.save();
1373b4284970SZhong Yang     return saved;
1374b4284970SZhong Yang }
1375b4284970SZhong Yang 
WriteWavAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)13762715cf48SZhong Yang bool CTagLibHelper::WriteWavAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist /*= true*/)
1377b4284970SZhong Yang {
1378b4284970SZhong Yang     RIFF::WAV::File file(file_path.c_str());
1379b4284970SZhong Yang     if (!file.isValid())
1380b4284970SZhong Yang         return false;
1381b4284970SZhong Yang 
1382d2d85fe1SZhong Yang     //先删除专辑封面
1383b4284970SZhong Yang     auto id3v2tag = file.ID3v2Tag();
1384b4284970SZhong Yang     if (remove_exist)
1385b4284970SZhong Yang     {
1386b4284970SZhong Yang         DeleteId3v2AlbumCover(id3v2tag);
1387b4284970SZhong Yang     }
1388b4284970SZhong Yang     if (!album_cover_path.empty())
1389b4284970SZhong Yang     {
1390b4284970SZhong Yang         WriteId3v2AlbumCover(id3v2tag, album_cover_path);
1391b4284970SZhong Yang     }
139203045520Szhongyang219     bool saved = file.save(RIFF::WAV::File::AllTags, File::StripOthers, GetWriteId3v2Version());
1393b4284970SZhong Yang     return saved;
1394b4284970SZhong Yang }
1395b4284970SZhong Yang 
WriteTtaAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)13962715cf48SZhong Yang bool CTagLibHelper::WriteTtaAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist /*= true*/)
1397b4284970SZhong Yang {
13987172d8f8SZhong Yang     TrueAudio::File file(file_path.c_str());
13997172d8f8SZhong Yang     if (!file.isValid())
14007172d8f8SZhong Yang         return false;
14017172d8f8SZhong Yang 
14027172d8f8SZhong Yang     if (remove_exist)
14037172d8f8SZhong Yang     {
14047172d8f8SZhong Yang         auto id3v2tag = file.ID3v2Tag();
14057172d8f8SZhong Yang         DeleteId3v2AlbumCover(id3v2tag);
14067172d8f8SZhong Yang     }
14077172d8f8SZhong Yang     if (!album_cover_path.empty())
14087172d8f8SZhong Yang     {
14097172d8f8SZhong Yang         auto id3v2tag = file.ID3v2Tag(true);
14107172d8f8SZhong Yang         WriteId3v2AlbumCover(id3v2tag, album_cover_path);
14117172d8f8SZhong Yang     }
14127172d8f8SZhong Yang     bool saved = file.save();
14137172d8f8SZhong Yang     return saved;
1414b4284970SZhong Yang     return false;
1415b4284970SZhong Yang }
1416b4284970SZhong Yang 
WriteApeAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)14172715cf48SZhong Yang bool CTagLibHelper::WriteApeAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist /*= true*/)
1418b4284970SZhong Yang {
1419b4284970SZhong Yang     APE::File file(file_path.c_str());
1420b4284970SZhong Yang     if (!file.isValid())
1421b4284970SZhong Yang         return false;
1422b4284970SZhong Yang 
1423b4284970SZhong Yang     auto tag = file.APETag(true);
14247172d8f8SZhong Yang     WriteApeTagAlbumCover(tag, album_cover_path, remove_exist);
1425b4284970SZhong Yang     bool saved = file.save();
1426b4284970SZhong Yang     return saved;
1427b4284970SZhong Yang }
1428b4284970SZhong Yang 
WriteOggAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)14292715cf48SZhong Yang bool CTagLibHelper::WriteOggAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist /*= true*/)
1430de03cfedSZhong Yang {
1431de03cfedSZhong Yang     Ogg::Vorbis::File file(file_path.c_str());
1432de03cfedSZhong Yang     if (!file.isValid())
1433de03cfedSZhong Yang         return false;
1434de03cfedSZhong Yang 
1435de03cfedSZhong Yang     auto tag = file.tag();
1436de03cfedSZhong Yang     if (tag != nullptr)
1437de03cfedSZhong Yang     {
1438de03cfedSZhong Yang         WriteXiphCommentAlbumCover(tag, album_cover_path, remove_exist);
1439de03cfedSZhong Yang         bool saved = file.save();
1440de03cfedSZhong Yang         return saved;
1441de03cfedSZhong Yang     }
1442de03cfedSZhong Yang     return false;
1443de03cfedSZhong Yang }
1444de03cfedSZhong Yang 
WriteOpusAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)14452715cf48SZhong Yang bool CTagLibHelper::WriteOpusAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist)
1446de03cfedSZhong Yang {
1447de03cfedSZhong Yang     Ogg::Opus::File file(file_path.c_str());
1448de03cfedSZhong Yang     if (!file.isValid())
1449de03cfedSZhong Yang         return false;
1450de03cfedSZhong Yang 
1451de03cfedSZhong Yang     auto tag = file.tag();
1452de03cfedSZhong Yang     if (tag != nullptr)
1453de03cfedSZhong Yang     {
1454de03cfedSZhong Yang         WriteXiphCommentAlbumCover(tag, album_cover_path, remove_exist);
1455de03cfedSZhong Yang         bool saved = file.save();
1456de03cfedSZhong Yang         return saved;
1457de03cfedSZhong Yang     }
1458de03cfedSZhong Yang     return false;
1459de03cfedSZhong Yang }
1460de03cfedSZhong Yang 
WriteSpxAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)14612715cf48SZhong Yang bool CTagLibHelper::WriteSpxAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist /*= true*/)
1462de03cfedSZhong Yang {
1463de03cfedSZhong Yang     Ogg::Speex::File file(file_path.c_str());
1464de03cfedSZhong Yang     if (!file.isValid())
1465de03cfedSZhong Yang         return false;
1466de03cfedSZhong Yang 
1467de03cfedSZhong Yang     auto tag = file.tag();
1468de03cfedSZhong Yang     if (tag != nullptr)
1469de03cfedSZhong Yang     {
1470de03cfedSZhong Yang         WriteXiphCommentAlbumCover(tag, album_cover_path, remove_exist);
1471de03cfedSZhong Yang         bool saved = file.save();
1472de03cfedSZhong Yang         return saved;
1473de03cfedSZhong Yang     }
1474de03cfedSZhong Yang     return false;
1475de03cfedSZhong Yang }
1476de03cfedSZhong Yang 
WriteAiffAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)14772715cf48SZhong Yang bool CTagLibHelper::WriteAiffAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist /*= true*/)
14786067fa7dSZhong Yang {
14796067fa7dSZhong Yang     RIFF::AIFF::File file(file_path.c_str());
14806067fa7dSZhong Yang     if (!file.isValid())
14816067fa7dSZhong Yang         return false;
14826067fa7dSZhong Yang 
1483d2d85fe1SZhong Yang     //先删除专辑封面
14846067fa7dSZhong Yang     auto id3v2tag = file.tag();
14856067fa7dSZhong Yang     if (remove_exist)
14866067fa7dSZhong Yang     {
14876067fa7dSZhong Yang         DeleteId3v2AlbumCover(id3v2tag);
14886067fa7dSZhong Yang     }
14896067fa7dSZhong Yang     if (!album_cover_path.empty())
14906067fa7dSZhong Yang     {
14916067fa7dSZhong Yang         WriteId3v2AlbumCover(id3v2tag, album_cover_path);
14926067fa7dSZhong Yang     }
149303045520Szhongyang219     bool saved = file.save(GetWriteId3v2Version());
14946067fa7dSZhong Yang     return saved;
14956067fa7dSZhong Yang }
14966067fa7dSZhong Yang 
WriteMpcAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)14972715cf48SZhong Yang bool CTagLibHelper::WriteMpcAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist /*= true*/)
14987172d8f8SZhong Yang {
14997172d8f8SZhong Yang     MPC::File file(file_path.c_str());
15007172d8f8SZhong Yang     if (!file.isValid())
15017172d8f8SZhong Yang         return false;
15027172d8f8SZhong Yang 
15037172d8f8SZhong Yang     auto tag = file.APETag(true);
15047172d8f8SZhong Yang     WriteApeTagAlbumCover(tag, album_cover_path, remove_exist);
15057172d8f8SZhong Yang     bool saved = file.save();
15067172d8f8SZhong Yang     return saved;
15077172d8f8SZhong Yang }
15087172d8f8SZhong Yang 
WriteWavePackAlbumCover(const std::wstring & file_path,const std::wstring & album_cover_path,bool remove_exist)15092715cf48SZhong Yang bool CTagLibHelper::WriteWavePackAlbumCover(const std::wstring& file_path, const std::wstring& album_cover_path, bool remove_exist /*= true*/)
15107172d8f8SZhong Yang {
15117172d8f8SZhong Yang     WavPack::File file(file_path.c_str());
15127172d8f8SZhong Yang     if (!file.isValid())
15137172d8f8SZhong Yang         return false;
15147172d8f8SZhong Yang 
15157172d8f8SZhong Yang     auto tag = file.APETag(true);
15167172d8f8SZhong Yang     WriteApeTagAlbumCover(tag, album_cover_path, remove_exist);
15177172d8f8SZhong Yang     bool saved = file.save();
15187172d8f8SZhong Yang     return saved;
15197172d8f8SZhong Yang }
15207172d8f8SZhong Yang 
WriteMpegTag(const SongInfo & song_info)15215db8215aSzhongyang219 bool CTagLibHelper::WriteMpegTag(const SongInfo& song_info)
1522b4284970SZhong Yang {
1523b4284970SZhong Yang     MPEG::File file(song_info.file_path.c_str());
1524b4284970SZhong Yang     auto tag = file.tag();
1525b4284970SZhong Yang     SongInfoToTag(song_info, tag);
1526b4284970SZhong Yang     int tags = MPEG::File::ID3v2;
1527b4284970SZhong Yang     //if (file.hasID3v1Tag())
1528b4284970SZhong Yang     //    tags |= MPEG::File::ID3v1;
1529b4284970SZhong Yang     if (file.hasAPETag())
1530b4284970SZhong Yang         tags |= MPEG::File::APE;
15318e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
153203045520Szhongyang219     bool saved = file.save(tags, File::StripOthers, GetWriteId3v2Version());
1533b4284970SZhong Yang     return saved;
1534b4284970SZhong Yang }
1535b4284970SZhong Yang 
WriteFlacTag(const SongInfo & song_info)15365db8215aSzhongyang219 bool CTagLibHelper::WriteFlacTag(const SongInfo& song_info)
1537b4284970SZhong Yang {
1538b4284970SZhong Yang     FLAC::File file(song_info.file_path.c_str());
1539b4284970SZhong Yang     auto tag = file.tag();
1540b4284970SZhong Yang     SongInfoToTag(song_info, tag);
15418e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
1542b4284970SZhong Yang     bool saved = file.save();
1543b4284970SZhong Yang     return saved;
1544b4284970SZhong Yang }
1545b4284970SZhong Yang 
WriteM4aTag(const SongInfo & song_info)15465db8215aSzhongyang219 bool CTagLibHelper::WriteM4aTag(const SongInfo& song_info)
1547b4284970SZhong Yang {
1548b4284970SZhong Yang     MP4::File file(song_info.file_path.c_str());
1549b4284970SZhong Yang     auto tag = file.tag();
1550b4284970SZhong Yang     SongInfoToTag(song_info, tag);
1551b4284970SZhong Yang     bool saved = file.save();
1552b4284970SZhong Yang     return saved;
1553b4284970SZhong Yang }
1554b4284970SZhong Yang 
WriteWavTag(const SongInfo & song_info)15555db8215aSzhongyang219 bool CTagLibHelper::WriteWavTag(const SongInfo& song_info)
1556b4284970SZhong Yang {
1557b4284970SZhong Yang     RIFF::WAV::File file(song_info.file_path.c_str());
1558b4284970SZhong Yang     auto tag = file.tag();
1559b4284970SZhong Yang     SongInfoToTag(song_info, tag);
15608e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
156103045520Szhongyang219     bool saved = file.save(RIFF::WAV::File::AllTags, File::StripOthers, GetWriteId3v2Version());
1562b4284970SZhong Yang     return saved;
1563b4284970SZhong Yang }
1564b4284970SZhong Yang 
WriteOggTag(const SongInfo & song_info)15655db8215aSzhongyang219 bool CTagLibHelper::WriteOggTag(const SongInfo& song_info)
1566b4284970SZhong Yang {
1567b4284970SZhong Yang     Vorbis::File file(song_info.file_path.c_str());
1568b4284970SZhong Yang     auto tag = file.tag();
1569b4284970SZhong Yang     SongInfoToTag(song_info, tag);
15708e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
1571b4284970SZhong Yang     bool saved = file.save();
1572b4284970SZhong Yang     return saved;
1573b4284970SZhong Yang }
1574b4284970SZhong Yang 
WriteApeTag(const SongInfo & song_info)15755db8215aSzhongyang219 bool CTagLibHelper::WriteApeTag(const SongInfo& song_info)
1576b4284970SZhong Yang {
1577b4284970SZhong Yang     APE::File file(song_info.file_path.c_str());
1578b4284970SZhong Yang     auto tag = file.tag();
1579b4284970SZhong Yang     SongInfoToTag(song_info, tag);
15808e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
1581b4284970SZhong Yang     bool saved = file.save();
1582b4284970SZhong Yang     return saved;
1583b4284970SZhong Yang }
1584b4284970SZhong Yang 
WriteMpcTag(const SongInfo & song_info)15855db8215aSzhongyang219 bool CTagLibHelper::WriteMpcTag(const SongInfo& song_info)
1586b4284970SZhong Yang {
1587b4284970SZhong Yang     MPC::File file(song_info.file_path.c_str());
1588b4284970SZhong Yang     auto tag = file.tag();
1589b4284970SZhong Yang     SongInfoToTag(song_info, tag);
15908e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
1591b4284970SZhong Yang     bool saved = file.save();
1592b4284970SZhong Yang     return saved;
1593b4284970SZhong Yang }
1594b4284970SZhong Yang 
WriteOpusTag(const SongInfo & song_info)15955db8215aSzhongyang219 bool CTagLibHelper::WriteOpusTag(const SongInfo& song_info)
1596b4284970SZhong Yang {
1597b4284970SZhong Yang     Ogg::Opus::File file(song_info.file_path.c_str());
1598b4284970SZhong Yang     auto tag = file.tag();
1599b4284970SZhong Yang     SongInfoToTag(song_info, tag);
16008e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
1601b4284970SZhong Yang     bool saved = file.save();
1602b4284970SZhong Yang     return saved;
1603b4284970SZhong Yang }
1604b4284970SZhong Yang 
WriteWavPackTag(const SongInfo & song_info)16055db8215aSzhongyang219 bool CTagLibHelper::WriteWavPackTag(const SongInfo& song_info)
1606b4284970SZhong Yang {
1607b4284970SZhong Yang     WavPack::File file(song_info.file_path.c_str());
1608b4284970SZhong Yang     auto tag = file.tag();
1609b4284970SZhong Yang     SongInfoToTag(song_info, tag);
16108e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
1611b4284970SZhong Yang     bool saved = file.save();
1612b4284970SZhong Yang     return saved;
1613b4284970SZhong Yang }
1614b4284970SZhong Yang 
WriteTtaTag(const SongInfo & song_info)16155db8215aSzhongyang219 bool CTagLibHelper::WriteTtaTag(const SongInfo& song_info)
1616b4284970SZhong Yang {
1617b4284970SZhong Yang     TrueAudio::File file(song_info.file_path.c_str());
1618b4284970SZhong Yang     auto tag = file.tag();
1619b4284970SZhong Yang     SongInfoToTag(song_info, tag);
16208e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
1621b4284970SZhong Yang     bool saved = file.save();
1622b4284970SZhong Yang     return saved;
1623b4284970SZhong Yang }
1624b4284970SZhong Yang 
WriteAiffTag(const SongInfo & song_info)16255db8215aSzhongyang219 bool CTagLibHelper::WriteAiffTag(const SongInfo& song_info)
1626b4284970SZhong Yang {
1627b4284970SZhong Yang     RIFF::AIFF::File file(song_info.file_path.c_str());
1628b4284970SZhong Yang     auto tag = file.tag();
1629b4284970SZhong Yang     SongInfoToTag(song_info, tag);
16308e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
163103045520Szhongyang219     bool saved = file.save(GetWriteId3v2Version());
1632b4284970SZhong Yang     return saved;
1633b4284970SZhong Yang }
1634b4284970SZhong Yang 
WriteAsfTag(const SongInfo & song_info)16355db8215aSzhongyang219 bool CTagLibHelper::WriteAsfTag(const SongInfo& song_info)
1636b4284970SZhong Yang {
1637b4284970SZhong Yang     ASF::File file(song_info.file_path.c_str());
1638b4284970SZhong Yang     auto tag = file.tag();
1639b4284970SZhong Yang     SongInfoToTag(song_info, tag);
16408e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
1641b4284970SZhong Yang     bool saved = file.save();
1642b4284970SZhong Yang     return saved;
1643b4284970SZhong Yang }
1644b86d7e7aSZhong Yang 
WriteSpxTag(const SongInfo & song_info)16455db8215aSzhongyang219 bool CTagLibHelper::WriteSpxTag(const SongInfo& song_info)
1646b86d7e7aSZhong Yang {
1647b86d7e7aSZhong Yang     Ogg::Speex::File file(song_info.file_path.c_str());
1648b86d7e7aSZhong Yang     auto tag = file.tag();
1649b86d7e7aSZhong Yang     SongInfoToTag(song_info, tag);
16508e2d3903SZhong Yang     WriteOtherProperties(song_info, file);
1651b86d7e7aSZhong Yang     bool saved = file.save();
1652b86d7e7aSZhong Yang     return saved;
1653b86d7e7aSZhong Yang }
1654e95fbf71SZhong Yang 
GetApeCue(const std::wstring & file_path)16552715cf48SZhong Yang std::wstring CTagLibHelper::GetApeCue(const std::wstring& file_path)
1656e95fbf71SZhong Yang {
16572715cf48SZhong Yang     std::wstring cue_contents;
1658e95fbf71SZhong Yang     APE::File file(file_path.c_str());
1659e95fbf71SZhong Yang     auto tag = file.APETag();
1660fefb2ef6SZhong Yang     if (tag != nullptr)
1661fefb2ef6SZhong Yang     {
1662e95fbf71SZhong Yang         auto item_list_map = tag->itemListMap();
1663e95fbf71SZhong Yang         auto cue_item = item_list_map[STR_APE_CUE_TAG];
1664e95fbf71SZhong Yang         cue_contents = cue_item.toString().toWString();
1665fefb2ef6SZhong Yang     }
1666e95fbf71SZhong Yang     return cue_contents;
1667e95fbf71SZhong Yang }
1668d2d85fe1SZhong Yang 
GetMepgRating(const std::wstring & file_path)16692715cf48SZhong Yang int CTagLibHelper::GetMepgRating(const std::wstring& file_path)
1670d2d85fe1SZhong Yang {
1671d2d85fe1SZhong Yang     MPEG::File file(file_path.c_str());
1672d2d85fe1SZhong Yang     auto id3v2 = file.ID3v2Tag();
1673d2d85fe1SZhong Yang     return GetId3v2Rating(id3v2);
1674d2d85fe1SZhong Yang }
1675d2d85fe1SZhong Yang 
GetFlacRating(const std::wstring & file_path)16762715cf48SZhong Yang int CTagLibHelper::GetFlacRating(const std::wstring& file_path)
167711e2bf4bSZhong Yang {
167811e2bf4bSZhong Yang     FLAC::File file(file_path.c_str());
167911e2bf4bSZhong Yang     auto properties = file.properties();
168011e2bf4bSZhong Yang     if (file.isValid())
168111e2bf4bSZhong Yang     {
168211e2bf4bSZhong Yang         auto rating_item = properties[STR_FLAC_RATING_TAG];
168311e2bf4bSZhong Yang         if (!rating_item.isEmpty())
168411e2bf4bSZhong Yang         {
168511e2bf4bSZhong Yang             int rating = _wtoi(rating_item.front().toWString().c_str());
168611e2bf4bSZhong Yang             return rating;
168711e2bf4bSZhong Yang         }
168811e2bf4bSZhong Yang     }
168911e2bf4bSZhong Yang     return 0;
169011e2bf4bSZhong Yang 
169111e2bf4bSZhong Yang }
169211e2bf4bSZhong Yang 
GetWmaRating(const std::wstring & file_path)16932715cf48SZhong Yang int CTagLibHelper::GetWmaRating(const std::wstring& file_path)
16945a85e7a2Szhongyang219 {
16955a85e7a2Szhongyang219     int rate{};
16965a85e7a2Szhongyang219     ASF::File file(file_path.c_str());
16975a85e7a2Szhongyang219     if (file.isValid())
16985a85e7a2Szhongyang219     {
16997b80a5daSzhongyang219         ASF::Tag* tag = file.tag();
17007b80a5daSzhongyang219         auto rating_str = tag->rating();
17017b80a5daSzhongyang219         rate = _wtoi(rating_str.toWString().c_str());
17025a85e7a2Szhongyang219     }
17035a85e7a2Szhongyang219     return rate;
17045a85e7a2Szhongyang219 }
17055a85e7a2Szhongyang219 
WriteMpegRating(const std::wstring & file_path,int rate)17062715cf48SZhong Yang bool CTagLibHelper::WriteMpegRating(const std::wstring& file_path, int rate)
1707d2d85fe1SZhong Yang {
1708d2d85fe1SZhong Yang     MPEG::File file(file_path.c_str());
1709d2d85fe1SZhong Yang     auto id3v2 = file.ID3v2Tag();
1710d2d85fe1SZhong Yang     WriteId3v2Rating(id3v2, rate);
1711d2d85fe1SZhong Yang     int tags = MPEG::File::ID3v2;
1712d2d85fe1SZhong Yang     if (file.hasAPETag())
1713d2d85fe1SZhong Yang         tags |= MPEG::File::APE;
171403045520Szhongyang219     bool saved = file.save(tags, File::StripOthers, GetWriteId3v2Version());
1715d2d85fe1SZhong Yang     return saved;
1716d2d85fe1SZhong Yang }
171703045520Szhongyang219 
WriteFlacRating(const std::wstring & file_path,int rate)17182715cf48SZhong Yang bool CTagLibHelper::WriteFlacRating(const std::wstring& file_path, int rate)
1719cd50d5eaSzhongyang219 {
1720cd50d5eaSzhongyang219     FLAC::File file(file_path.c_str());
1721cd50d5eaSzhongyang219     if (file.isValid())
1722cd50d5eaSzhongyang219     {
1723cd50d5eaSzhongyang219         auto properties = file.properties();
1724cd50d5eaSzhongyang219         properties[STR_FLAC_RATING_TAG].clear();
1725cd50d5eaSzhongyang219         properties[STR_FLAC_RATING_TAG].append(std::to_wstring(rate).c_str());
1726cd50d5eaSzhongyang219         file.setProperties(properties);
1727cd50d5eaSzhongyang219         bool saved = file.save();
1728cd50d5eaSzhongyang219         return saved;
1729cd50d5eaSzhongyang219     }
1730cd50d5eaSzhongyang219     return false;
1731cd50d5eaSzhongyang219 }
1732cd50d5eaSzhongyang219 
WriteWmaRating(const std::wstring & file_path,int rate)17332715cf48SZhong Yang bool CTagLibHelper::WriteWmaRating(const std::wstring& file_path, int rate)
17345a85e7a2Szhongyang219 {
17355a85e7a2Szhongyang219     ASF::File file(file_path.c_str());
17365a85e7a2Szhongyang219     if (file.isValid())
17375a85e7a2Szhongyang219     {
17387b80a5daSzhongyang219         auto tag = file.tag();
17397b80a5daSzhongyang219         tag->setRating(std::to_wstring(rate));
17405a85e7a2Szhongyang219         bool saved = file.save();
17415a85e7a2Szhongyang219         return saved;
17425a85e7a2Szhongyang219     }
17435a85e7a2Szhongyang219     return false;
17445a85e7a2Szhongyang219 }
17455a85e7a2Szhongyang219 
GetWriteId3v2Version()174603045520Szhongyang219 TagLib::ID3v2::Version CTagLibHelper::GetWriteId3v2Version()
174703045520Szhongyang219 {
174803045520Szhongyang219     return (m_write_id3v2_3 ? ID3v2::Version::v3 : ID3v2::Version::v4);
174903045520Szhongyang219 }
1750