NowPlayingPlugin: Improved handling of cached album art and fixed that some tracks don't display metadata with Winamp.

This commit is contained in:
Birunthan Mohanathas 2011-05-22 11:05:23 +00:00
parent ef97fb2435
commit 3ba7d39bc4
8 changed files with 91 additions and 98 deletions

View File

@ -17,7 +17,6 @@
*/ */
#include "StdAfx.h" #include "StdAfx.h"
#include "../../Library/Export.h"
#include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point
#include "NowPlaying.h" #include "NowPlaying.h"
#include "PlayerAIMP.h" #include "PlayerAIMP.h"
@ -163,13 +162,12 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
} }
else else
{ {
std::wstring error = L"PlayerName="; std::wstring error = L"NowPlayingPlugin: PlayerName=";
error += str; error += str;
error += L" is not valid in section ["; error += L" is not valid in section [";
error += section; error += section;
error += L"] of the following file: \n\n"; error += L"].";
error += iniFile; LSLog(LOG_ERROR, L"Rainmeter", error.c_str());
MessageBox(NULL, error.c_str(), L"Rainmeter", MB_OK | MB_ICONERROR | MB_TOPMOST);
delete data; delete data;
return maxValue; return maxValue;
} }
@ -311,11 +309,13 @@ UINT Update(UINT id)
case MEASURE_VOLUME: case MEASURE_VOLUME:
return player->GetVolume(); return player->GetVolume();
} }
}
return 0; return 0;
} }
return 1;
}
/* /*
** GetString ** GetString
** **

View File

@ -97,17 +97,17 @@ void CPlayer::ClearInfo()
} }
/* /*
** CreateCoverArtPath ** GetCachedArt
** **
** Determines the path to save cover art. ** Checks if cover art is in cache.
** **
*/ */
std::wstring CPlayer::CreateCoverArtPath() bool CPlayer::GetCachedArt()
{ {
std::wstring targetPath = g_CachePath; m_CoverPath = g_CachePath;
if (m_Artist.empty() || m_Title.empty()) if (m_Artist.empty() || m_Title.empty())
{ {
targetPath += L"temp.art"; m_CoverPath += L"temp.art";
} }
else else
{ {
@ -120,15 +120,20 @@ std::wstring CPlayer::CreateCoverArtPath()
std::wstring::size_type pos = 0; std::wstring::size_type pos = 0;
while ((pos = name.find_first_of(L"\\/:*?\"<>|", pos)) != std::wstring::npos) name[pos] = L'_'; while ((pos = name.find_first_of(L"\\/:*?\"<>|", pos)) != std::wstring::npos) name[pos] = L'_';
targetPath += name; m_CoverPath += name;
targetPath += L".art"; m_CoverPath += L".art";
if (_waccess(m_CoverPath.c_str(), 0) == 0)
{
// Art found in cache
return true;
}
} }
return targetPath; return false;
} }
/* /*
** GetArtLocal ** GetLocalArt
** **
** Attemps to find local cover art in various formats. ** Attemps to find local cover art in various formats.
** **
@ -162,12 +167,12 @@ bool CPlayer::GetLocalArt(std::wstring& folder, std::wstring filename)
} }
/* /*
** GetEmbeddedCover ** GetEmbeddedArt
** **
** Attempts to extract cover art from audio files. ** Attempts to extract cover art from audio files.
** **
*/ */
bool CPlayer::GetEmbeddedArt(const TagLib::FileRef& fr, std::wstring& path) bool CPlayer::GetEmbeddedArt(const TagLib::FileRef& fr)
{ {
bool found = false; bool found = false;
@ -175,60 +180,55 @@ bool CPlayer::GetEmbeddedArt(const TagLib::FileRef& fr, std::wstring& path)
{ {
if (file->ID3v2Tag()) if (file->ID3v2Tag())
{ {
found = GetArtID3(file->ID3v2Tag(), path); found = GetArtID3(file->ID3v2Tag());
} }
if (!found && file->APETag()) if (!found && file->APETag())
{ {
found = GetArtAPE(file->APETag(), path); found = GetArtAPE(file->APETag());
} }
} }
else if (TagLib::MP4::File* file = dynamic_cast<TagLib::MP4::File*>(fr.file())) else if (TagLib::MP4::File* file = dynamic_cast<TagLib::MP4::File*>(fr.file()))
{ {
if (file->tag()) if (file->tag())
{ {
found = GetArtMP4(file, path); found = GetArtMP4(file);
} }
} }
else if (TagLib::FLAC::File* file = dynamic_cast<TagLib::FLAC::File*>(fr.file())) else if (TagLib::FLAC::File* file = dynamic_cast<TagLib::FLAC::File*>(fr.file()))
{ {
found = GetArtFLAC(file, path); found = GetArtFLAC(file);
if (!found && file->ID3v2Tag()) if (!found && file->ID3v2Tag())
{ {
found = GetArtID3(file->ID3v2Tag(), path); found = GetArtID3(file->ID3v2Tag());
} }
} }
else if (TagLib::ASF::File* file = dynamic_cast<TagLib::ASF::File*>(fr.file())) else if (TagLib::ASF::File* file = dynamic_cast<TagLib::ASF::File*>(fr.file()))
{ {
found = GetArtASF(file, path); found = GetArtASF(file);
} }
else if (TagLib::APE::File* file = dynamic_cast<TagLib::APE::File*>(fr.file())) else if (TagLib::APE::File* file = dynamic_cast<TagLib::APE::File*>(fr.file()))
{ {
if (file->APETag()) if (file->APETag())
{ {
found = GetArtAPE(file->APETag(), path); found = GetArtAPE(file->APETag());
} }
} }
else if (TagLib::MPC::File* file = dynamic_cast<TagLib::MPC::File*>(fr.file())) else if (TagLib::MPC::File* file = dynamic_cast<TagLib::MPC::File*>(fr.file()))
{ {
if (file->APETag()) if (file->APETag())
{ {
found = GetArtAPE(file->APETag(), path); found = GetArtAPE(file->APETag());
} }
} }
else if (TagLib::WavPack::File* file = dynamic_cast<TagLib::WavPack::File*>(fr.file())) else if (TagLib::WavPack::File* file = dynamic_cast<TagLib::WavPack::File*>(fr.file()))
{ {
if (file->APETag()) if (file->APETag())
{ {
found = GetArtAPE(file->APETag(), path); found = GetArtAPE(file->APETag());
} }
} }
if (found)
{
m_CoverPath = path;
}
return found; return found;
} }
@ -238,7 +238,7 @@ bool CPlayer::GetEmbeddedArt(const TagLib::FileRef& fr, std::wstring& path)
** Extracts cover art embedded in APE tags. ** Extracts cover art embedded in APE tags.
** **
*/ */
bool CPlayer::GetArtAPE(TagLib::APE::Tag* tag, std::wstring& path) bool CPlayer::GetArtAPE(TagLib::APE::Tag* tag)
{ {
bool ret = false; bool ret = false;
const TagLib::APE::ItemListMap& listMap = tag->itemListMap(); const TagLib::APE::ItemListMap& listMap = tag->itemListMap();
@ -254,7 +254,7 @@ bool CPlayer::GetArtAPE(TagLib::APE::Tag* tag, std::wstring& path)
{ {
const TagLib::ByteVector& pic = item.mid(pos); const TagLib::ByteVector& pic = item.mid(pos);
FILE* f = _wfopen(path.c_str(), L"wb"); FILE* f = _wfopen(m_CoverPath.c_str(), L"wb");
if (f) if (f)
{ {
ret = (fwrite(pic.data(), 1, pic.size(), f) == pic.size()); ret = (fwrite(pic.data(), 1, pic.size(), f) == pic.size());
@ -272,7 +272,7 @@ bool CPlayer::GetArtAPE(TagLib::APE::Tag* tag, std::wstring& path)
** Extracts cover art embedded in ID3v2 tags. ** Extracts cover art embedded in ID3v2 tags.
** **
*/ */
bool CPlayer::GetArtID3(TagLib::ID3v2::Tag* tag, std::wstring& path) bool CPlayer::GetArtID3(TagLib::ID3v2::Tag* tag)
{ {
bool ret = false; bool ret = false;
@ -285,7 +285,7 @@ bool CPlayer::GetArtID3(TagLib::ID3v2::Tag* tag, std::wstring& path)
if (size > 0) if (size > 0)
{ {
FILE* f = _wfopen(path.c_str(), L"wb"); FILE* f = _wfopen(m_CoverPath.c_str(), L"wb");
if (f) if (f)
{ {
ret = (fwrite(frame->picture().data(), 1, size, f) == size); ret = (fwrite(frame->picture().data(), 1, size, f) == size);
@ -303,7 +303,7 @@ bool CPlayer::GetArtID3(TagLib::ID3v2::Tag* tag, std::wstring& path)
** Extracts cover art embedded in ASF/WMA files. ** Extracts cover art embedded in ASF/WMA files.
** **
*/ */
bool CPlayer::GetArtASF(TagLib::ASF::File* file, std::wstring& path) bool CPlayer::GetArtASF(TagLib::ASF::File* file)
{ {
bool ret = false; bool ret = false;
@ -320,7 +320,7 @@ bool CPlayer::GetArtASF(TagLib::ASF::File* file, std::wstring& path)
if (wmpic.isValid()) if (wmpic.isValid())
{ {
FILE* f = _wfopen(path.c_str(), L"wb"); FILE* f = _wfopen(m_CoverPath.c_str(), L"wb");
if (f) if (f)
{ {
ret = (fwrite(wmpic.picture().data(), 1, wmpic.picture().size(), f) == wmpic.picture().size()); ret = (fwrite(wmpic.picture().data(), 1, wmpic.picture().size(), f) == wmpic.picture().size());
@ -339,7 +339,7 @@ bool CPlayer::GetArtASF(TagLib::ASF::File* file, std::wstring& path)
** Extracts cover art embedded in FLAC files. ** Extracts cover art embedded in FLAC files.
** **
*/ */
bool CPlayer::GetArtFLAC(TagLib::FLAC::File* file, std::wstring& path) bool CPlayer::GetArtFLAC(TagLib::FLAC::File* file)
{ {
bool ret = false; bool ret = false;
@ -349,7 +349,7 @@ bool CPlayer::GetArtFLAC(TagLib::FLAC::File* file, std::wstring& path)
// Let's grab the first image // Let's grab the first image
TagLib::FLAC::Picture* pic = picList[0]; TagLib::FLAC::Picture* pic = picList[0];
FILE* f = _wfopen(path.c_str(), L"wb"); FILE* f = _wfopen(m_CoverPath.c_str(), L"wb");
if (f) if (f)
{ {
ret = (fwrite(pic->data().data(), 1, pic->data().size(), f) == pic->data().size()); ret = (fwrite(pic->data().data(), 1, pic->data().size(), f) == pic->data().size());
@ -366,7 +366,7 @@ bool CPlayer::GetArtFLAC(TagLib::FLAC::File* file, std::wstring& path)
** Extracts cover art embedded in MP4-like files. ** Extracts cover art embedded in MP4-like files.
** **
*/ */
bool CPlayer::GetArtMP4(TagLib::MP4::File* file, std::wstring& path) bool CPlayer::GetArtMP4(TagLib::MP4::File* file)
{ {
bool ret = false; bool ret = false;
@ -378,7 +378,7 @@ bool CPlayer::GetArtMP4(TagLib::MP4::File* file, std::wstring& path)
if (size > 0) if (size > 0)
{ {
FILE* f = _wfopen(path.c_str(), L"wb"); FILE* f = _wfopen(m_CoverPath.c_str(), L"wb");
if (f) if (f)
{ {
ret = (fwrite(coverList[0].data().data(), 1, size, f) == size); ret = (fwrite(coverList[0].data().data(), 1, size, f) == size);

View File

@ -107,14 +107,14 @@ public:
void ExecuteTrackChangeAction(); void ExecuteTrackChangeAction();
void ClearInfo(); void ClearInfo();
std::wstring CreateCoverArtPath(); bool GetCachedArt();
bool GetLocalArt(std::wstring& folder, std::wstring filename); bool GetLocalArt(std::wstring& folder, std::wstring filename);
bool GetEmbeddedArt(const TagLib::FileRef& fr, std::wstring& path); bool GetEmbeddedArt(const TagLib::FileRef& fr);
bool GetArtAPE(TagLib::APE::Tag* tag, std::wstring& path); bool GetArtAPE(TagLib::APE::Tag* tag);
bool GetArtID3(TagLib::ID3v2::Tag* tag, std::wstring& path); bool GetArtID3(TagLib::ID3v2::Tag* tag);
bool GetArtASF(TagLib::ASF::File* file, std::wstring& path); bool GetArtASF(TagLib::ASF::File* file);
bool GetArtFLAC(TagLib::FLAC::File* file, std::wstring& path); bool GetArtFLAC(TagLib::FLAC::File* file);
bool GetArtMP4(TagLib::MP4::File* file, std::wstring& path); bool GetArtMP4(TagLib::MP4::File* file);
protected: protected:
int m_InstanceCount; int m_InstanceCount;

View File

@ -206,16 +206,14 @@ void CPlayerAIMP::UpdateData()
if (m_HasCoverMeasure) if (m_HasCoverMeasure)
{ {
std::wstring cover = CreateCoverArtPath(); if (GetCachedArt())
if (_waccess(cover.c_str(), 0) == 0)
{ {
// Cover is in cache, lets use the that // Cover is in cache, lets use the that
m_CoverPath = cover;
return; return;
} }
TagLib::FileRef fr(m_FilePath.c_str()); TagLib::FileRef fr(m_FilePath.c_str());
if (!fr.isNull() && fr.tag() && GetEmbeddedArt(fr, cover)) if (!fr.isNull() && fr.tag() && GetEmbeddedArt(fr))
{ {
// Embedded art found // Embedded art found
return; return;

View File

@ -271,16 +271,14 @@ void CPlayerFoobar::GetCoverArt(LPTSTR filename)
// TODO: Fix temp solution // TODO: Fix temp solution
if (m_HasCoverMeasure || m_InstanceCount == 0) if (m_HasCoverMeasure || m_InstanceCount == 0)
{ {
std::wstring cover = CreateCoverArtPath(); if (GetCachedArt())
if (_waccess(cover.c_str(), 0) == 0)
{ {
// Cover is in cache, lets use the that // Cover is in cache, lets use the that
m_CoverPath = cover;
return; return;
} }
TagLib::FileRef fr(filename); TagLib::FileRef fr(filename);
if (!fr.isNull() && fr.tag() && GetEmbeddedArt(fr, cover)) if (!fr.isNull() && fr.tag() && GetEmbeddedArt(fr))
{ {
// Embedded art found // Embedded art found
return; return;

View File

@ -371,15 +371,9 @@ void CPlayerITunes::OnTrackChange()
if (m_HasCoverMeasure) if (m_HasCoverMeasure)
{ {
// Check if MP3 file contains embedded art if (!GetCachedArt())
std::wstring cover = CreateCoverArtPath();
if (_waccess(cover.c_str(), 0) == 0)
{
// Cover is in cache, lets use the that
m_CoverPath = cover;
}
else
{ {
// Art not in cache, check for embedded art
IITArtworkCollection* artworkCollection; IITArtworkCollection* artworkCollection;
hr = track->get_Artwork(&artworkCollection); hr = track->get_Artwork(&artworkCollection);
@ -395,9 +389,12 @@ void CPlayerITunes::OnTrackChange()
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
tmpStr = cover.c_str(); tmpStr = m_CoverPath.c_str();
hr = artwork->SaveArtworkToFile(tmpStr); hr = artwork->SaveArtworkToFile(tmpStr);
SUCCEEDED(hr) ? m_CoverPath = cover : m_CoverPath.clear(); if (FAILED(hr))
{
m_CoverPath.clear();
}
artwork->Release(); artwork->Release();
} }
@ -409,6 +406,10 @@ void CPlayerITunes::OnTrackChange()
artworkCollection->Release(); artworkCollection->Release();
} }
else
{
m_CoverPath.clear();
}
} }
} }
} }

View File

@ -471,16 +471,14 @@ void CPlayerWMP::UpdateData()
} }
else else
{ {
std::wstring cover = CreateCoverArtPath(); if (GetCachedArt())
if (_waccess(cover.c_str(), 0) == 0)
{ {
// Cover is in cache, lets use the that // Cover is in cache, lets use the that
m_CoverPath = cover;
return; return;
} }
TagLib::FileRef fr(url.m_str); TagLib::FileRef fr(url.m_str);
if (!fr.isNull() && fr.tag() && GetEmbeddedArt(fr, cover)) if (!fr.isNull() && fr.tag() && GetEmbeddedArt(fr))
{ {
// Embedded art found // Embedded art found
return; return;

View File

@ -193,43 +193,41 @@ void CPlayerWinamp::UpdateData()
} }
else else
{ {
ClearInfo(); // TagLib couldn't parse the file, try title instead
int pos = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETLISTPOS);
/*LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETPLAYLISTTITLEW); LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, pos, IPC_GETPLAYLISTTITLEW);
if (ReadProcessMemory(m_WinampHandle, m_WinampAddress, &buffer, MAX_PATH, NULL)) if (ReadProcessMemory(m_WinampHandle, address, &buffer, MAX_PATH, NULL))
{ {
std::wstring title = buffer; std::wstring title = buffer;
std::wstring::size_type pos = title.find(L" - "); std::wstring::size_type pos = title.find(L". ");
if (pos != std::wstring::npos && pos < 5)
{
pos += 2; // Skip ". "
title.erase(0, pos);
}
pos = title.find(L" - ");
if (pos != std::wstring::npos) if (pos != std::wstring::npos)
{ {
std::wstring artist = title.substr(0, pos); m_Title = title.substr(0, pos);
std::wstring track = title.substr(pos + 3); pos += 3; // Skip " - "
m_Artist = title.substr(pos);
if (track != m_Title && artist != m_Artist)
{
m_Title = track;
m_Artist = artist;
m_Album.clear(); m_Album.clear();
} }
} else
}*/ {
ClearInfo();
return; return;
} }
}
}
if (m_HasCoverMeasure) if (m_HasCoverMeasure)
{ {
std::wstring cover = CreateCoverArtPath(); if (GetCachedArt() || GetEmbeddedArt(fr))
if (_waccess(cover.c_str(), 0) == 0)
{ {
// Cover is in cache, lets use the that // Art found in cache or embedded in file
m_CoverPath = cover;
return;
}
if (GetEmbeddedArt(fr, cover))
{
// Embedded art found
return; return;
} }