mirror of
https://github.com/zhongyang219/MusicPlayer2.git
synced 2026-10-22 17:35:51 +08:00
1390 lines
38 KiB
C++
1390 lines
38 KiB
C++
#include "stdafx.h"
|
|
#include "TagLibHelper.h"
|
|
#include "taglib/mp4file.h"
|
|
#include "taglib/mp4coverart.h"
|
|
#include "taglib/flacfile.h"
|
|
#include "taglib/flacpicture.h"
|
|
#include "taglib/mpegfile.h"
|
|
#include "Common.h"
|
|
#include "FilePathHelper.h"
|
|
#include "taglib/attachedpictureframe.h"
|
|
#include "taglib/id3v2tag.h"
|
|
#include "taglib/id3v1tag.h"
|
|
#include "taglib/apefile.h"
|
|
#include "taglib/wavfile.h"
|
|
#include "taglib/mpcfile.h"
|
|
#include "taglib/opusfile.h"
|
|
#include "taglib/wavpackfile.h"
|
|
#include "taglib/vorbisfile.h"
|
|
#include "taglib/trueaudiofile.h"
|
|
#include "taglib/aifffile.h"
|
|
#include "taglib/asffile.h"
|
|
#include "taglib/tpropertymap.h"
|
|
#include "AudioCommon.h"
|
|
#include "taglib/apetag.h"
|
|
#include "taglib/fileref.h"
|
|
#include "taglib/speexfile.h"
|
|
#include "taglib/unsynchronizedlyricsframe.h"
|
|
|
|
|
|
using namespace TagLib;
|
|
|
|
#define STR_MP4_COVER_TAG "covr"
|
|
#define STR_MP4_LYRICS_TAG "----:com.apple.iTunes:Lyrics"
|
|
#define STR_ASF_COVER_TAG "WM/Picture"
|
|
#define STR_APE_COVER_TAG "COVER ART (FRONT)"
|
|
#define STR_ID3V2_LYRIC_TAG "USLT"
|
|
#define STR_FLAC_LYRIC_TAG "LYRICS"
|
|
#define STR_ASF_LYRIC_TAG "LYRICS"
|
|
#define STR_APE_CUE_TAG "CUESHEET"
|
|
|
|
//将taglib中的字符串转换成wstring类型。
|
|
//由于taglib将所有非unicode编码全部作为Latin编码处理,因此无法正确处理本地代码页
|
|
//这里将Latin编码的字符串按本地代码页处理
|
|
static wstring TagStringToWstring(const String& str, bool to_local)
|
|
{
|
|
wstring result;
|
|
if (to_local && str.isLatin1())
|
|
result = CCommon::StrToUnicode(str.to8Bit(), CodeType::ANSI);
|
|
else
|
|
result = str.toWString();
|
|
return result;
|
|
}
|
|
|
|
static void SongInfoToTag(const SongInfo& song_info, Tag* tag)
|
|
{
|
|
if (tag != nullptr)
|
|
{
|
|
tag->setTitle(song_info.title);
|
|
tag->setArtist(song_info.artist);
|
|
tag->setAlbum(song_info.album);
|
|
tag->setGenre(song_info.genre);
|
|
tag->setTrack(song_info.track);
|
|
tag->setComment(song_info.comment);
|
|
tag->setYear(song_info.year);
|
|
}
|
|
}
|
|
|
|
static bool IsStringNumber(wstring str, int num)
|
|
{
|
|
if (!str.empty() && str.front() == L'(')
|
|
str = str.substr(1);
|
|
if (!str.empty() && str.back() == L')')
|
|
str.pop_back();
|
|
if (CCommon::StrIsNumber(str))
|
|
{
|
|
num = _wtoi(str.c_str());
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static void TagToSongInfo(SongInfo& song_info, Tag* tag, bool to_local)
|
|
{
|
|
if (tag != nullptr)
|
|
{
|
|
song_info.title = TagStringToWstring(tag->title(), to_local);
|
|
song_info.artist = TagStringToWstring(tag->artist(), to_local);
|
|
song_info.album = TagStringToWstring(tag->album(), to_local);
|
|
song_info.genre = TagStringToWstring(tag->genre(), to_local);
|
|
int genre_num{};
|
|
if (IsStringNumber(song_info.genre, genre_num))
|
|
{
|
|
song_info.genre = CAudioCommon::GetGenre(static_cast<BYTE>(genre_num));
|
|
}
|
|
|
|
song_info.year = tag->year();
|
|
song_info.track = tag->track();
|
|
song_info.comment = TagStringToWstring(tag->comment(), to_local);
|
|
}
|
|
}
|
|
|
|
//将文件内容读取到ByteVector
|
|
static void FileToByteVector(ByteVector& data, const std::wstring& file_path)
|
|
{
|
|
std::ifstream file{ file_path, std::ios::binary | std::ios::in };
|
|
if (file.fail())
|
|
return;
|
|
|
|
//获取文件长度
|
|
file.seekg(0, file.end);
|
|
size_t length = file.tellg();
|
|
file.seekg(0, file.beg);
|
|
|
|
data.clear();
|
|
data.resize(static_cast<unsigned int>(length));
|
|
|
|
file.read(data.data(), length);
|
|
|
|
file.close();
|
|
}
|
|
|
|
int GetPicType(const wstring& mimeType)
|
|
{
|
|
int type{ -1 };
|
|
if (mimeType == L"image/jpeg" || mimeType == L"image/jpg")
|
|
type = 0;
|
|
else if (mimeType == L"image/png")
|
|
type = 1;
|
|
else if (mimeType == L"image/gif")
|
|
type = 2;
|
|
else if (mimeType == L"image/bmp")
|
|
type = 3;
|
|
else
|
|
type = -1;
|
|
return type;
|
|
}
|
|
|
|
static void GetId3v2AlbumCover(ID3v2::Tag* id3v2, string& cover_contents, int& type)
|
|
{
|
|
if (id3v2 != nullptr)
|
|
{
|
|
auto pic_frame_list = id3v2->frameListMap()["APIC"];
|
|
if (!pic_frame_list.isEmpty())
|
|
{
|
|
ID3v2::AttachedPictureFrame *frame = dynamic_cast<TagLib::ID3v2::AttachedPictureFrame*>(pic_frame_list.front());
|
|
if (frame != nullptr)
|
|
{
|
|
auto pic_data = frame->picture();
|
|
//获取专辑封面
|
|
cover_contents.assign(pic_data.data(), pic_data.size());
|
|
wstring img_type = frame->mimeType().toCWString();
|
|
type = GetPicType(img_type);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void DeleteId3v2AlbumCover(ID3v2::Tag* id3v2tag)
|
|
{
|
|
if (id3v2tag != nullptr)
|
|
{
|
|
auto pic_frame_list = id3v2tag->frameListMap()["APIC"];
|
|
if (!pic_frame_list.isEmpty())
|
|
{
|
|
for (auto frame : pic_frame_list)
|
|
id3v2tag->removeFrame(frame);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void WriteId3v2AlbumCover(ID3v2::Tag* id3v2tag, const wstring& album_cover_path)
|
|
{
|
|
if (id3v2tag != nullptr)
|
|
{
|
|
//读取图片文件
|
|
ByteVector pic_data;
|
|
FileToByteVector(pic_data, album_cover_path);
|
|
//向音频文件写入图片文件
|
|
ID3v2::AttachedPictureFrame* pic_frame = new ID3v2::AttachedPictureFrame();
|
|
pic_frame->setPicture(pic_data);
|
|
pic_frame->setType(ID3v2::AttachedPictureFrame::FrontCover);
|
|
wstring ext = CFilePathHelper(album_cover_path).GetFileExtension();
|
|
pic_frame->setMimeType(L"image/" + ext);
|
|
id3v2tag->addFrame(pic_frame);
|
|
}
|
|
}
|
|
|
|
|
|
static void GetApeTagAlbumCover(APE::Tag* tag, string& cover_contents, int& type)
|
|
{
|
|
if (tag != nullptr)
|
|
{
|
|
auto item_list_map = tag->itemListMap();
|
|
auto pic_item = item_list_map[STR_APE_COVER_TAG];
|
|
auto pic_data = pic_item.binaryData();
|
|
if (!pic_data.isEmpty())
|
|
{
|
|
cover_contents.assign(pic_data.data(), pic_data.size());
|
|
|
|
size_t index{};
|
|
index = cover_contents.find('\0');
|
|
std::string pic_desc;
|
|
if (index != std::string::npos)
|
|
{
|
|
pic_desc = cover_contents.substr(0, index);
|
|
cover_contents = cover_contents.substr(index + 1);
|
|
}
|
|
|
|
if (!pic_desc.empty())
|
|
{
|
|
std::string img_type;
|
|
index = pic_desc.rfind('.');
|
|
if (index != std::string::npos && index < pic_desc.size() - 1)
|
|
{
|
|
img_type = pic_desc.substr(index + 1);
|
|
img_type = "image/" + img_type;
|
|
type = GetPicType(CCommon::ASCIIToUnicode(img_type));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void WriteApeTagAlbumCover(APE::Tag* tag, const wstring &album_cover_path, bool remove_exist)
|
|
{
|
|
if (remove_exist)
|
|
{
|
|
tag->removeItem(STR_APE_COVER_TAG);
|
|
}
|
|
|
|
if (!album_cover_path.empty())
|
|
{
|
|
ByteVector pic_data;
|
|
FileToByteVector(pic_data, album_cover_path);
|
|
|
|
ByteVector pic_item_data;
|
|
pic_item_data = "Cover Art (Front).";
|
|
wstring file_type = CFilePathHelper(album_cover_path).GetFileExtension();
|
|
for (wchar_t ch : file_type)
|
|
pic_item_data.append(static_cast<char>(ch));
|
|
pic_item_data.append('\0');
|
|
pic_item_data.append(pic_data);
|
|
|
|
APE::Item pic_item(STR_APE_COVER_TAG, pic_item_data, true);
|
|
tag->setItem(STR_APE_COVER_TAG, pic_item);
|
|
}
|
|
}
|
|
|
|
static void WriteXiphCommentAlbumCover(Ogg::XiphComment * tag, const wstring &album_cover_path, bool remove_exist)
|
|
{
|
|
//先删除专辑封面
|
|
if (remove_exist)
|
|
{
|
|
tag->removeAllPictures();
|
|
}
|
|
|
|
if (!album_cover_path.empty())
|
|
{
|
|
ByteVector pic_data;
|
|
FileToByteVector(pic_data, album_cover_path);
|
|
FLAC::Picture *newpic = new FLAC::Picture();
|
|
newpic->setType(FLAC::Picture::FrontCover);
|
|
newpic->setData(pic_data);
|
|
wstring ext = CFilePathHelper(album_cover_path).GetFileExtension();
|
|
newpic->setMimeType(L"image/" + ext);
|
|
tag->addPicture(newpic);
|
|
}
|
|
}
|
|
|
|
|
|
void GetXiphCommentAlbumCover(Ogg::XiphComment * tag, string &cover_contents, int& type)
|
|
{
|
|
const auto& cover_list = tag->pictureList();
|
|
if (!cover_list.isEmpty())
|
|
{
|
|
auto pic = cover_list.front();
|
|
if (pic != nullptr)
|
|
{
|
|
const auto& pic_data = pic->data();
|
|
//获取专辑封面
|
|
cover_contents.assign(pic_data.data(), pic_data.size());
|
|
|
|
wstring img_type = pic->mimeType().toCWString();
|
|
type = GetPicType(img_type);
|
|
}
|
|
}
|
|
}
|
|
|
|
wstring GetId3v2Lyric(ID3v2::Tag* id3v2)
|
|
{
|
|
wstring lyrics;
|
|
if (id3v2 != nullptr)
|
|
{
|
|
auto frame_list_map = id3v2->frameListMap();
|
|
auto lyric_frame = frame_list_map[STR_ID3V2_LYRIC_TAG];
|
|
if (!lyric_frame.isEmpty())
|
|
lyrics = lyric_frame.front()->toString().toWString();
|
|
}
|
|
return lyrics;
|
|
}
|
|
|
|
|
|
void WriteId3v2Lyric(ID3v2::Tag * id3v2, const wstring &lyric_contents)
|
|
{
|
|
if (id3v2 != nullptr)
|
|
{
|
|
//先删除歌词帧
|
|
auto lyric_frame_list = id3v2->frameListMap()[STR_ID3V2_LYRIC_TAG];
|
|
if (!lyric_frame_list.isEmpty())
|
|
{
|
|
for (auto frame : lyric_frame_list)
|
|
id3v2->removeFrame(frame);
|
|
}
|
|
|
|
if (!lyric_contents.empty())
|
|
{
|
|
//写入歌词帧
|
|
ID3v2::UnsynchronizedLyricsFrame* lyric_frame = new ID3v2::UnsynchronizedLyricsFrame();
|
|
lyric_frame->setText(lyric_contents.c_str());
|
|
id3v2->addFrame(lyric_frame);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
template<class T>
|
|
void GetTagPropertyMap(T* tag, std::map<wstring, wstring>& property_map)
|
|
{
|
|
if (tag != nullptr)
|
|
{
|
|
auto properties = tag->properties();
|
|
for (const auto& prop : properties)
|
|
{
|
|
wstring key = prop.first.toWString();
|
|
wstring value = TagStringToWstring(prop.second.toString(L";"), true);
|
|
auto iter = property_map.find(key);
|
|
if (iter == property_map.end())
|
|
property_map[key] = value;
|
|
else if (iter->second.empty())
|
|
iter->second = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CTagLibHelper::CTagLibHelper()
|
|
{
|
|
}
|
|
|
|
CTagLibHelper::~CTagLibHelper()
|
|
{
|
|
}
|
|
|
|
string CTagLibHelper::GetM4aAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
MP4::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
if(tag != nullptr)
|
|
{
|
|
auto cover_item = tag->item(STR_MP4_COVER_TAG).toCoverArtList();
|
|
if (!cover_item.isEmpty())
|
|
{
|
|
const auto& pic_data = cover_item.front().data();
|
|
//获取专辑封面
|
|
cover_contents.assign(pic_data.data(), pic_data.size());
|
|
|
|
//获取封面格式
|
|
switch (cover_item.front().format())
|
|
{
|
|
case MP4::CoverArt::JPEG:
|
|
type = 0;
|
|
break;
|
|
case MP4::CoverArt::PNG:
|
|
type = 1;
|
|
break;
|
|
case MP4::CoverArt::BMP:
|
|
type = 3;
|
|
break;
|
|
case MP4::CoverArt::GIF:
|
|
type = 2;
|
|
break;
|
|
default:
|
|
type = -1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return cover_contents;
|
|
}
|
|
|
|
string CTagLibHelper::GetFlacAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
FLAC::File file(file_path.c_str());
|
|
const auto& cover_list = file.pictureList();
|
|
if (!cover_list.isEmpty())
|
|
{
|
|
auto pic = cover_list.front();
|
|
if (pic != nullptr)
|
|
{
|
|
const auto& pic_data = pic->data();
|
|
//获取专辑封面
|
|
cover_contents.assign(pic_data.data(), pic_data.size());
|
|
|
|
wstring img_type = pic->mimeType().toCWString();
|
|
type = GetPicType(img_type);
|
|
}
|
|
}
|
|
return cover_contents;
|
|
}
|
|
|
|
string CTagLibHelper::GetMp3AlbumCover(const wstring & file_path, int & type)
|
|
{
|
|
string cover_contents;
|
|
MPEG::File file(file_path.c_str());
|
|
auto id3v2 = file.ID3v2Tag();
|
|
GetId3v2AlbumCover(id3v2, cover_contents, type);
|
|
return cover_contents;
|
|
}
|
|
|
|
string CTagLibHelper::GetAsfAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
ASF::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
ASF::AttributeList attr = tag->attribute("WM/Picture");
|
|
if (!attr.isEmpty())
|
|
{
|
|
ASF::Picture picture = attr.front().toPicture();
|
|
auto pic_data = picture.picture();
|
|
cover_contents.assign(pic_data.data(), pic_data.size());
|
|
wstring img_type = picture.mimeType().toCWString();
|
|
type = GetPicType(img_type);
|
|
}
|
|
}
|
|
return cover_contents;
|
|
}
|
|
|
|
string CTagLibHelper::GetWavAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
RIFF::WAV::File file(file_path.c_str());
|
|
auto id3v2 = file.ID3v2Tag();
|
|
GetId3v2AlbumCover(id3v2, cover_contents, type);
|
|
return cover_contents;
|
|
}
|
|
|
|
string CTagLibHelper::GetTtaAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
TrueAudio::File file(file_path.c_str());
|
|
auto id3v2 = file.ID3v2Tag();
|
|
GetId3v2AlbumCover(id3v2, cover_contents, type);
|
|
return cover_contents;
|
|
}
|
|
|
|
string CTagLibHelper::GetApeAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
APE::File file(file_path.c_str());
|
|
auto tag = file.APETag();
|
|
GetApeTagAlbumCover(tag, cover_contents, type);
|
|
return cover_contents;
|
|
}
|
|
|
|
|
|
string CTagLibHelper::GetOggAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
Ogg::Vorbis::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
GetXiphCommentAlbumCover(tag, cover_contents, type);
|
|
}
|
|
return cover_contents;
|
|
}
|
|
|
|
string CTagLibHelper::GetOpusAlbumCover(const wstring & file_path, int & type)
|
|
{
|
|
string cover_contents;
|
|
Ogg::Opus::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
GetXiphCommentAlbumCover(tag, cover_contents, type);
|
|
}
|
|
return cover_contents;
|
|
}
|
|
|
|
string CTagLibHelper::GetSpxAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
Ogg::Speex::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
GetXiphCommentAlbumCover(tag, cover_contents, type);
|
|
}
|
|
return cover_contents;
|
|
}
|
|
|
|
string CTagLibHelper::GetAiffAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
RIFF::AIFF::File file(file_path.c_str());
|
|
auto id3v2 = file.tag();
|
|
GetId3v2AlbumCover(id3v2, cover_contents, type);
|
|
return cover_contents;
|
|
|
|
}
|
|
|
|
string CTagLibHelper::GetMpcAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
MPC::File file(file_path.c_str());
|
|
auto ape_tag = file.APETag();
|
|
GetApeTagAlbumCover(ape_tag, cover_contents, type);
|
|
return cover_contents;
|
|
}
|
|
|
|
string CTagLibHelper::GetWavePackAlbumCover(const wstring& file_path, int& type)
|
|
{
|
|
string cover_contents;
|
|
WavPack::File file(file_path.c_str());
|
|
auto ape_tag = file.APETag();
|
|
GetApeTagAlbumCover(ape_tag, cover_contents, type);
|
|
return cover_contents;
|
|
}
|
|
|
|
void CTagLibHelper::GetFlacTagInfo(SongInfo& song_info)
|
|
{
|
|
FLAC::File file(song_info.file_path.c_str());
|
|
if (file.hasID3v1Tag())
|
|
song_info.tag_type |= T_ID3V1;
|
|
if (file.hasID3v2Tag())
|
|
song_info.tag_type |= T_ID3V2;
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, true);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetM4aTagInfo(SongInfo& song_info)
|
|
{
|
|
MP4::File file(song_info.file_path.c_str());
|
|
if (file.hasMP4Tag())
|
|
song_info.tag_type |= T_MP4;
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, false);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetMpegTagInfo(SongInfo& song_info)
|
|
{
|
|
MPEG::File file(song_info.file_path.c_str());
|
|
if (file.hasID3v1Tag())
|
|
song_info.tag_type |= T_ID3V1;
|
|
if (file.hasID3v2Tag())
|
|
song_info.tag_type |= T_ID3V2;
|
|
if (file.hasAPETag())
|
|
song_info.tag_type |= T_APE;
|
|
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, true);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetAsfTagInfo(SongInfo& song_info)
|
|
{
|
|
ASF::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, false);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetApeTagInfo(SongInfo& song_info)
|
|
{
|
|
APE::File file(song_info.file_path.c_str());
|
|
if (file.hasID3v1Tag())
|
|
song_info.tag_type |= T_ID3V1;
|
|
if (file.hasAPETag())
|
|
song_info.tag_type |= T_APE;
|
|
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, true);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetWavTagInfo(SongInfo& song_info)
|
|
{
|
|
RIFF::WAV::File file(song_info.file_path.c_str());
|
|
if (file.hasID3v2Tag())
|
|
song_info.tag_type |= T_ID3V2;
|
|
if (file.hasInfoTag())
|
|
song_info.tag_type |= T_RIFF;
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, false);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetOggTagInfo(SongInfo& song_info)
|
|
{
|
|
Vorbis::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, false);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetMpcTagInfo(SongInfo& song_info)
|
|
{
|
|
MPC::File file(song_info.file_path.c_str());
|
|
if (file.hasAPETag())
|
|
song_info.tag_type |= T_APE;
|
|
if (file.hasID3v1Tag())
|
|
song_info.tag_type |= T_ID3V1;
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, true);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetOpusTagInfo(SongInfo& song_info)
|
|
{
|
|
Ogg::Opus::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, false);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetWavPackTagInfo(SongInfo& song_info)
|
|
{
|
|
WavPack::File file(song_info.file_path.c_str());
|
|
if (file.hasAPETag())
|
|
song_info.tag_type |= T_APE;
|
|
if (file.hasID3v1Tag())
|
|
song_info.tag_type |= T_ID3V1;
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, true);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetTtaTagInfo(SongInfo& song_info)
|
|
{
|
|
TrueAudio::File file(song_info.file_path.c_str());
|
|
if (file.hasID3v1Tag())
|
|
song_info.tag_type |= T_ID3V1;
|
|
if (file.hasID3v2Tag())
|
|
song_info.tag_type |= T_ID3V2;
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, true);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetAiffTagInfo(SongInfo& song_info)
|
|
{
|
|
RIFF::AIFF::File file(song_info.file_path.c_str());
|
|
if (file.hasID3v2Tag())
|
|
song_info.tag_type |= T_ID3V2;
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, false);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetSpxTagInfo(SongInfo& song_info)
|
|
{
|
|
Ogg::Speex::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, false);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetAnyFileTagInfo(SongInfo & song_info)
|
|
{
|
|
FileRef file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
TagToSongInfo(song_info, tag, false);
|
|
}
|
|
}
|
|
|
|
void CTagLibHelper::GetFlacPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
FLAC::File file(file_path.c_str());
|
|
if (file.hasXiphComment())
|
|
GetTagPropertyMap(file.xiphComment(), property_map);
|
|
if (file.hasID3v2Tag())
|
|
GetTagPropertyMap(file.ID3v2Tag(), property_map);
|
|
if (file.hasID3v1Tag())
|
|
GetTagPropertyMap(file.ID3v1Tag(), property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetM4aPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
MP4::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
GetTagPropertyMap(tag, property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetMpegPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
MPEG::File file(file_path.c_str());
|
|
if (file.hasID3v2Tag())
|
|
GetTagPropertyMap(file.ID3v2Tag(), property_map);
|
|
if (file.hasAPETag())
|
|
GetTagPropertyMap(file.APETag(), property_map);
|
|
if (file.hasID3v1Tag())
|
|
GetTagPropertyMap(file.ID3v1Tag(), property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetAsfPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
ASF::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
GetTagPropertyMap(tag, property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetApePropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
APE::File file(file_path.c_str());
|
|
if (file.hasAPETag())
|
|
GetTagPropertyMap(file.APETag(), property_map);
|
|
if (file.hasID3v1Tag())
|
|
GetTagPropertyMap(file.ID3v1Tag(), property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetWavPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
RIFF::WAV::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
GetTagPropertyMap(tag, property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetOggPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
Vorbis::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
GetTagPropertyMap(tag, property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetMpcPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
MPC::File file(file_path.c_str());
|
|
if (file.hasAPETag())
|
|
GetTagPropertyMap(file.APETag(), property_map);
|
|
if (file.hasID3v1Tag())
|
|
GetTagPropertyMap(file.ID3v1Tag(), property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetOpusPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
Ogg::Opus::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
GetTagPropertyMap(tag, property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetWavPackPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
WavPack::File file(file_path.c_str());
|
|
if (file.hasAPETag())
|
|
GetTagPropertyMap(file.APETag(), property_map);
|
|
if (file.hasID3v1Tag())
|
|
GetTagPropertyMap(file.ID3v1Tag(), property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetTtaPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
TrueAudio::File file(file_path.c_str());
|
|
if (file.hasID3v2Tag())
|
|
GetTagPropertyMap(file.ID3v2Tag(), property_map);
|
|
if (file.hasID3v1Tag())
|
|
GetTagPropertyMap(file.ID3v1Tag(), property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetAiffPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
RIFF::AIFF::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
GetTagPropertyMap(tag, property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetSpxPropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
Ogg::Speex::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
GetTagPropertyMap(tag, property_map);
|
|
}
|
|
|
|
void CTagLibHelper::GetAnyFilePropertyMap(const wstring & file_path, std::map<wstring, wstring>& property_map)
|
|
{
|
|
FileRef file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
GetTagPropertyMap(tag, property_map);
|
|
}
|
|
|
|
wstring CTagLibHelper::GetMpegLyric(const wstring& file_path)
|
|
{
|
|
MPEG::File file(file_path.c_str());
|
|
auto id3v2 = file.ID3v2Tag();
|
|
return GetId3v2Lyric(id3v2);
|
|
}
|
|
|
|
wstring CTagLibHelper::GetM4aLyric(const wstring& file_path)
|
|
{
|
|
wstring lyrics;
|
|
MP4::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
auto item_map = file.tag()->itemMap();
|
|
auto lyric_item = item_map[STR_MP4_LYRICS_TAG].toStringList();;
|
|
if (!lyric_item.isEmpty())
|
|
lyrics = lyric_item.front().toWString();
|
|
}
|
|
return lyrics;
|
|
}
|
|
|
|
wstring CTagLibHelper::GetFlacLyric(const wstring& file_path)
|
|
{
|
|
wstring lyrics;
|
|
FLAC::File file(file_path.c_str());
|
|
auto properties = file.properties();
|
|
if (file.isValid())
|
|
{
|
|
auto lyric_item = properties[STR_FLAC_LYRIC_TAG];
|
|
if (!lyric_item.isEmpty())
|
|
{
|
|
lyrics = lyric_item.front().toWString();
|
|
}
|
|
}
|
|
return lyrics;
|
|
}
|
|
|
|
wstring CTagLibHelper::GetAsfLyric(const wstring& file_path)
|
|
{
|
|
wstring lyrics;
|
|
ASF::File file(file_path.c_str());
|
|
if (file.isValid())
|
|
{
|
|
auto properties = file.properties();
|
|
auto lyric_item = properties[STR_ASF_LYRIC_TAG];
|
|
if (!lyric_item.isEmpty())
|
|
{
|
|
lyrics = lyric_item.front().toWString();
|
|
}
|
|
}
|
|
return lyrics;
|
|
}
|
|
|
|
|
|
wstring CTagLibHelper::GetWavLyric(const wstring& file_path)
|
|
{
|
|
RIFF::WAV::File file(file_path.c_str());
|
|
auto id3v2 = file.ID3v2Tag();
|
|
return GetId3v2Lyric(id3v2);
|
|
|
|
}
|
|
|
|
bool CTagLibHelper::WriteMpegLyric(const wstring& file_path, const wstring& lyric_contents)
|
|
{
|
|
wstring lyrics;
|
|
MPEG::File file(file_path.c_str());
|
|
auto id3v2 = file.ID3v2Tag();
|
|
WriteId3v2Lyric(id3v2, lyric_contents);
|
|
int tags = MPEG::File::ID3v2;
|
|
if (file.hasAPETag())
|
|
tags |= MPEG::File::APE;
|
|
bool saved = file.save(tags);
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteFlacLyric(const wstring& file_path, const wstring& lyric_contents)
|
|
{
|
|
FLAC::File file(file_path.c_str());
|
|
if (file.isValid())
|
|
{
|
|
auto properties = file.properties();
|
|
if (lyric_contents.empty())
|
|
{
|
|
properties.erase(STR_FLAC_LYRIC_TAG);
|
|
}
|
|
else
|
|
{
|
|
StringList lyric_item;
|
|
lyric_item.append(lyric_contents);
|
|
properties[STR_FLAC_LYRIC_TAG] = lyric_item;
|
|
}
|
|
file.setProperties(properties);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteM4aLyric(const wstring& file_path, const wstring& lyric_contents)
|
|
{
|
|
MP4::File file(file_path.c_str());
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
if (lyric_contents.empty())
|
|
{
|
|
tag->removeItem(STR_MP4_LYRICS_TAG);
|
|
}
|
|
else
|
|
{
|
|
StringList lyric_list;
|
|
lyric_list.append(lyric_contents);
|
|
MP4::Item lyrics_item(lyric_list);
|
|
tag->setItem(STR_MP4_LYRICS_TAG, lyrics_item);
|
|
}
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteAsfLyric(const wstring& file_path, const wstring& lyric_contents)
|
|
{
|
|
ASF::File file(file_path.c_str());
|
|
if (file.isValid())
|
|
{
|
|
auto properties = file.properties();
|
|
if (lyric_contents.empty())
|
|
{
|
|
properties.erase(STR_ASF_LYRIC_TAG);
|
|
}
|
|
else
|
|
{
|
|
StringList lyric_item;
|
|
lyric_item.append(lyric_contents);
|
|
properties[STR_ASF_LYRIC_TAG] = lyric_item;
|
|
}
|
|
file.setProperties(properties);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteWavLyric(const wstring& file_path, const wstring& lyric_contents)
|
|
{
|
|
wstring lyrics;
|
|
RIFF::WAV::File file(file_path.c_str());
|
|
auto id3v2 = file.ID3v2Tag();
|
|
WriteId3v2Lyric(id3v2, lyric_contents);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteMp3AlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist)
|
|
{
|
|
MPEG::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
//先删除专辑封面
|
|
if (remove_exist)
|
|
{
|
|
auto id3v2tag = file.ID3v2Tag();
|
|
DeleteId3v2AlbumCover(id3v2tag);
|
|
}
|
|
if (!album_cover_path.empty())
|
|
{
|
|
auto id3v2tag = file.ID3v2Tag(true);
|
|
WriteId3v2AlbumCover(id3v2tag, album_cover_path);
|
|
}
|
|
int tags = MPEG::File::ID3v2;
|
|
if (file.hasAPETag())
|
|
tags |= MPEG::File::APE;
|
|
bool saved = file.save(tags);
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteFlacAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist)
|
|
{
|
|
FLAC::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
//先删除专辑封面
|
|
if (remove_exist)
|
|
{
|
|
file.removePictures();
|
|
}
|
|
|
|
if (!album_cover_path.empty())
|
|
{
|
|
ByteVector pic_data;
|
|
FileToByteVector(pic_data, album_cover_path);
|
|
FLAC::Picture *newpic = new FLAC::Picture();
|
|
newpic->setType(FLAC::Picture::FrontCover);
|
|
newpic->setData(pic_data);
|
|
wstring ext = CFilePathHelper(album_cover_path).GetFileExtension();
|
|
newpic->setMimeType(L"image/" + ext);
|
|
file.addPicture(newpic);
|
|
}
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteM4aAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist /*= true*/)
|
|
{
|
|
MP4::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
auto tag = file.tag();
|
|
if (tag == nullptr)
|
|
return false;
|
|
|
|
if (remove_exist)
|
|
{
|
|
if (tag->contains(STR_MP4_COVER_TAG))
|
|
{
|
|
tag->removeItem(STR_MP4_COVER_TAG);
|
|
}
|
|
}
|
|
|
|
if (!album_cover_path.empty())
|
|
{
|
|
ByteVector pic_data;
|
|
FileToByteVector(pic_data, album_cover_path);
|
|
MP4::CoverArt::Format format = MP4::CoverArt::Format::Unknown;
|
|
wstring ext = CFilePathHelper(album_cover_path).GetFileExtension();
|
|
if (ext == L"jpg" || ext == L"jpeg")
|
|
format = MP4::CoverArt::Format::JPEG;
|
|
else if (ext == L"png")
|
|
format = MP4::CoverArt::Format::PNG;
|
|
else if (ext == L"gif")
|
|
format = MP4::CoverArt::Format::GIF;
|
|
else if (ext == L"bmp")
|
|
format = MP4::CoverArt::Format::BMP;
|
|
MP4::CoverArt cover_item(format, pic_data);
|
|
|
|
auto cover_item_list = tag->item(STR_MP4_COVER_TAG).toCoverArtList();
|
|
cover_item_list.append(cover_item);
|
|
tag->setItem(STR_MP4_COVER_TAG, cover_item_list);
|
|
}
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteAsfAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist /*= true*/)
|
|
{
|
|
ASF::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
auto tag = file.tag();
|
|
if (tag == nullptr)
|
|
return false;
|
|
|
|
if (remove_exist)
|
|
{
|
|
if (tag->contains(STR_ASF_COVER_TAG))
|
|
{
|
|
tag->removeItem(STR_ASF_COVER_TAG);
|
|
}
|
|
}
|
|
|
|
if (!album_cover_path.empty())
|
|
{
|
|
ByteVector pic_data;
|
|
FileToByteVector(pic_data, album_cover_path);
|
|
|
|
ASF::Picture picture;
|
|
wstring str_mine_type = L"image/" + CFilePathHelper(album_cover_path).GetFileExtension();
|
|
picture.setMimeType(str_mine_type);
|
|
picture.setType(ASF::Picture::FrontCover);
|
|
picture.setPicture(pic_data);
|
|
tag->setAttribute(STR_ASF_COVER_TAG, picture);
|
|
}
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteWavAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist /*= true*/)
|
|
{
|
|
RIFF::WAV::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
//先删除专辑封面
|
|
auto id3v2tag = file.ID3v2Tag();
|
|
if (remove_exist)
|
|
{
|
|
DeleteId3v2AlbumCover(id3v2tag);
|
|
}
|
|
if (!album_cover_path.empty())
|
|
{
|
|
WriteId3v2AlbumCover(id3v2tag, album_cover_path);
|
|
}
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteTtaAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist /*= true*/)
|
|
{
|
|
TrueAudio::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
if (remove_exist)
|
|
{
|
|
auto id3v2tag = file.ID3v2Tag();
|
|
DeleteId3v2AlbumCover(id3v2tag);
|
|
}
|
|
if (!album_cover_path.empty())
|
|
{
|
|
auto id3v2tag = file.ID3v2Tag(true);
|
|
WriteId3v2AlbumCover(id3v2tag, album_cover_path);
|
|
}
|
|
bool saved = file.save();
|
|
return saved;
|
|
return false;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteApeAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist /*= true*/)
|
|
{
|
|
APE::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
auto tag = file.APETag(true);
|
|
WriteApeTagAlbumCover(tag, album_cover_path, remove_exist);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteOggAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist /*= true*/)
|
|
{
|
|
Ogg::Vorbis::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
WriteXiphCommentAlbumCover(tag, album_cover_path, remove_exist);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteOpusAlbumCover(const wstring & file_path, const wstring & album_cover_path, bool remove_exist)
|
|
{
|
|
Ogg::Opus::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
WriteXiphCommentAlbumCover(tag, album_cover_path, remove_exist);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteSpxAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist /*= true*/)
|
|
{
|
|
Ogg::Speex::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
auto tag = file.tag();
|
|
if (tag != nullptr)
|
|
{
|
|
WriteXiphCommentAlbumCover(tag, album_cover_path, remove_exist);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteAiffAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist /*= true*/)
|
|
{
|
|
RIFF::AIFF::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
//先删除专辑封面
|
|
auto id3v2tag = file.tag();
|
|
if (remove_exist)
|
|
{
|
|
DeleteId3v2AlbumCover(id3v2tag);
|
|
}
|
|
if (!album_cover_path.empty())
|
|
{
|
|
WriteId3v2AlbumCover(id3v2tag, album_cover_path);
|
|
}
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteMpcAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist /*= true*/)
|
|
{
|
|
MPC::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
auto tag = file.APETag(true);
|
|
WriteApeTagAlbumCover(tag, album_cover_path, remove_exist);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteWavePackAlbumCover(const wstring& file_path, const wstring& album_cover_path, bool remove_exist /*= true*/)
|
|
{
|
|
WavPack::File file(file_path.c_str());
|
|
if (!file.isValid())
|
|
return false;
|
|
|
|
auto tag = file.APETag(true);
|
|
WriteApeTagAlbumCover(tag, album_cover_path, remove_exist);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteMpegTag(SongInfo & song_info)
|
|
{
|
|
MPEG::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
int tags = MPEG::File::ID3v2;
|
|
//if (file.hasID3v1Tag())
|
|
// tags |= MPEG::File::ID3v1;
|
|
if (file.hasAPETag())
|
|
tags |= MPEG::File::APE;
|
|
bool saved = file.save(tags);
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteFlacTag(SongInfo& song_info)
|
|
{
|
|
FLAC::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteM4aTag(SongInfo & song_info)
|
|
{
|
|
MP4::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteWavTag(SongInfo & song_info)
|
|
{
|
|
RIFF::WAV::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteOggTag(SongInfo & song_info)
|
|
{
|
|
Vorbis::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteApeTag(SongInfo& song_info)
|
|
{
|
|
APE::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteMpcTag(SongInfo& song_info)
|
|
{
|
|
MPC::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteOpusTag(SongInfo & song_info)
|
|
{
|
|
Ogg::Opus::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteWavPackTag(SongInfo& song_info)
|
|
{
|
|
WavPack::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteTtaTag(SongInfo& song_info)
|
|
{
|
|
TrueAudio::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteAiffTag(SongInfo & song_info)
|
|
{
|
|
RIFF::AIFF::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteAsfTag(SongInfo & song_info)
|
|
{
|
|
ASF::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
bool CTagLibHelper::WriteSpxTag(SongInfo& song_info)
|
|
{
|
|
Ogg::Speex::File file(song_info.file_path.c_str());
|
|
auto tag = file.tag();
|
|
SongInfoToTag(song_info, tag);
|
|
bool saved = file.save();
|
|
return saved;
|
|
}
|
|
|
|
wstring CTagLibHelper::GetApeCue(const wstring& file_path)
|
|
{
|
|
wstring cue_contents;
|
|
APE::File file(file_path.c_str());
|
|
auto tag = file.APETag();
|
|
if (tag != nullptr)
|
|
{
|
|
auto item_list_map = tag->itemListMap();
|
|
auto cue_item = item_list_map[STR_APE_CUE_TAG];
|
|
cue_contents = cue_item.toString().toWString();
|
|
}
|
|
return cue_contents;
|
|
}
|