NowPlayingPlugin: Fixed that track title didn't update when playing a radio stream with Winamp.

This commit is contained in:
Birunthan Mohanathas 2011-07-24 15:31:33 +00:00
parent 15eba97cba
commit 8954799483
5 changed files with 142 additions and 114 deletions

View File

@ -162,7 +162,7 @@ void CPlayer::FindCover()
if (!CCover::GetCached(m_CoverPath)) if (!CCover::GetCached(m_CoverPath))
{ {
TagLib::FileRef fr(m_FilePath.c_str()); TagLib::FileRef fr(m_FilePath.c_str());
if (fr.isNull() || !fr.tag() || !CCover::GetEmbedded(fr, m_CoverPath)) if (fr.isNull() || !CCover::GetEmbedded(fr, m_CoverPath))
{ {
std::wstring trackFolder = CCover::GetFileFolder(m_FilePath); std::wstring trackFolder = CCover::GetFileFolder(m_FilePath);

View File

@ -202,7 +202,6 @@ void CPlayerITunes::Initialize()
if (m_iTunes) if (m_iTunes)
{ {
//SetTimer(NULL, 0, 1000, QuitCallback);
m_Initialized = true; m_Initialized = true;
// Set up event handler // Set up event handler

View File

@ -34,6 +34,7 @@ CPlayer* CPlayerWinamp::c_Player = NULL;
CPlayerWinamp::CPlayerWinamp(WINAMPTYPE type) : CPlayer(), CPlayerWinamp::CPlayerWinamp(WINAMPTYPE type) : CPlayer(),
m_Window(), m_Window(),
m_UseUnicodeAPI(false), m_UseUnicodeAPI(false),
m_PlayingStream(false),
m_WinampType(type), m_WinampType(type),
m_WinampHandle(), m_WinampHandle(),
m_WinampAddress() m_WinampAddress()
@ -140,153 +141,180 @@ void CPlayerWinamp::UpdateData()
WCHAR wBuffer[MAX_PATH]; WCHAR wBuffer[MAX_PATH];
char cBuffer[MAX_PATH]; char cBuffer[MAX_PATH];
BOOL ret;
if (m_UseUnicodeAPI) if (m_UseUnicodeAPI)
{ {
ret = ReadProcessMemory(m_WinampHandle, m_WinampAddress, &wBuffer, sizeof(wBuffer), NULL); if (!ReadProcessMemory(m_WinampHandle, m_WinampAddress, &wBuffer, sizeof(wBuffer), NULL))
{
// Failed to read memory
return;
}
} }
else else
{ {
// MediaMonkey doesn't support wide IPC messages // MediaMonkey doesn't support wide IPC messages
int pos = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETLISTPOS); int pos = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETLISTPOS);
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, pos, IPC_GETPLAYLISTFILE); LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, pos, IPC_GETPLAYLISTFILE);
ret = ReadProcessMemory(m_WinampHandle, address, &cBuffer, sizeof(cBuffer), NULL);
mbstowcs(wBuffer, cBuffer, MAX_PATH);
}
if (!ret) if (!ReadProcessMemory(m_WinampHandle, address, &cBuffer, sizeof(cBuffer), NULL))
{ {
LSLog(LOG_ERROR, L"Rainmeter", L"NowPlayingPlugin: Failed to read Winamp memory (file)."); // Failed to read memory
return; return;
}
mbstowcs(wBuffer, cBuffer, MAX_PATH);
} }
if (wcscmp(wBuffer, m_FilePath.c_str()) != 0) if (wcscmp(wBuffer, m_FilePath.c_str()) != 0)
{ {
++m_TrackCount; ++m_TrackCount;
m_FilePath = wBuffer; m_FilePath = wBuffer;
m_Rating = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETRATING); m_PlayingStream = (m_FilePath.find(L"://") != std::wstring::npos);
m_Duration = SendMessage(m_Window, WM_WA_IPC, 1, IPC_GETOUTPUTTIME);
TagLib::FileRef fr(wBuffer); if (!m_PlayingStream)
if (!fr.isNull() && fr.tag())
{ {
m_Rating = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETRATING);
m_Duration = SendMessage(m_Window, WM_WA_IPC, 1, IPC_GETOUTPUTTIME);
TagLib::FileRef fr(wBuffer);
TagLib::Tag* tag = fr.tag(); TagLib::Tag* tag = fr.tag();
m_Artist = tag->artist().toWString(); if (tag)
m_Album = tag->album().toWString();
m_Title = tag->title().toWString();
}
else
{
// TagLib couldn't parse the file, try title instead
if (m_UseUnicodeAPI)
{ {
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, 0, IPC_GET_PLAYING_TITLE); m_Artist = tag->artist().toWString();
ret = ReadProcessMemory(m_WinampHandle, address, &wBuffer, sizeof(wBuffer), NULL); m_Album = tag->album().toWString();
} m_Title = tag->title().toWString();
else
{
int pos = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETLISTPOS);
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, pos, IPC_GETPLAYLISTTITLE);
ReadProcessMemory(m_WinampHandle, m_WinampAddress, &cBuffer, sizeof(cBuffer), NULL);
ret = mbstowcs(wBuffer, cBuffer, MAX_PATH);
}
if (!ret) if (m_HasLyricsMeasure)
{
LSLog(LOG_ERROR, L"Rainmeter", L"NowPlayingPlugin: Failed to read Winamp memory (title).");
return;
}
std::wstring title = wBuffer;
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)
{
m_Title.assign(title, 0, pos);
pos += 3; // Skip " - "
m_Artist.assign(title, pos, title.length() - pos);
m_Album.clear();
}
else
{
m_Title = title;
m_Artist.clear();
m_Album.clear();
}
}
if (m_HasLyricsMeasure)
{
FindLyrics();
}
// Find cover if needed
if (m_HasCoverMeasure)
{
m_CoverPath = GetCacheFile();
if (!CCover::GetCached(m_CoverPath) &&
!CCover::GetEmbedded(fr, m_CoverPath))
{
std::wstring trackFolder = CCover::GetFileFolder(m_FilePath);
if (!m_Album.empty())
{ {
// Winamp stores covers usually as %album%.jpg FindLyrics();
std::wstring file = m_Album; }
std::wstring::size_type end = file.length(); }
for (std::wstring::size_type pos = 0; pos < end; ++pos) else if (m_HasLyricsMeasure)
{
m_Lyrics.clear();
}
// Find cover if needed
if (m_HasCoverMeasure)
{
m_CoverPath = GetCacheFile();
if (!CCover::GetCached(m_CoverPath) &&
(tag && !CCover::GetEmbedded(fr, m_CoverPath)))
{
std::wstring trackFolder = CCover::GetFileFolder(m_FilePath);
if (!m_Album.empty())
{ {
// Replace reserved chars according to Winamp specs // Winamp stores covers usually as %album%.jpg
switch (file[pos]) std::wstring file = m_Album;
std::wstring::size_type end = file.length();
for (std::wstring::size_type pos = 0; pos < end; ++pos)
{ {
case L'?': // Replace reserved chars according to Winamp specs
case L'*': switch (file[pos])
case L'|': {
file[pos] = L'_'; case L'?':
break; case L'*':
case L'|':
file[pos] = L'_';
break;
case L'/': case L'/':
case L'\\': case L'\\':
case L':': case L':':
file[pos] = L'-'; file[pos] = L'-';
break; break;
case L'\"': case L'\"':
file[pos] = L'\''; file[pos] = L'\'';
break; break;
case L'<': case L'<':
file[pos] = L'('; file[pos] = L'(';
break; break;
case L'>': case L'>':
file[pos] = L')'; file[pos] = L')';
break; break;
}
}
if (CCover::GetLocal(file, trackFolder, m_CoverPath))
{
// %album% art file found
return;
} }
} }
if (CCover::GetLocal(file, trackFolder, m_CoverPath)) if (!CCover::GetLocal(L"cover", trackFolder, m_CoverPath) &&
!CCover::GetLocal(L"folder", trackFolder, m_CoverPath))
{ {
// %album% art file found // Nothing found
return; m_CoverPath.clear();
} }
} }
}
if (!CCover::GetLocal(L"cover", trackFolder, m_CoverPath) && if (tag)
!CCover::GetLocal(L"folder", trackFolder, m_CoverPath)) {
{ // Got metadata, return
// Nothing found return;
m_CoverPath.clear();
}
} }
} }
else
{
m_Rating = 0;
m_Duration = 0;
if (m_HasCoverMeasure)
{
m_CoverPath.clear();
}
}
}
else if (!m_PlayingStream)
{
return;
}
// TagLib couldn't parse the file or Winamp is playing a stream, try to get title
if (m_UseUnicodeAPI)
{
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, 0, IPC_GET_PLAYING_TITLE);
ReadProcessMemory(m_WinampHandle, address, &wBuffer, sizeof(wBuffer), NULL);
}
else
{
int pos = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETLISTPOS);
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, pos, IPC_GETPLAYLISTTITLE);
ReadProcessMemory(m_WinampHandle, address, &cBuffer, sizeof(cBuffer), NULL);
mbstowcs(wBuffer, cBuffer, MAX_PATH);
}
std::wstring title = wBuffer;
std::wstring::size_type pos = title.find(L" - ");
if (pos != std::wstring::npos)
{
m_Artist.assign(title, 0, pos);
pos += 3; // Skip " - "
m_Title.assign(title, pos, title.length() - pos);
m_Album.clear();
if (m_PlayingStream)
{
// Remove crap from title if playing radio
pos = m_Title.find(L" (");
if (pos != std::wstring::npos)
{
m_Title.resize(pos);
}
}
}
else
{
m_Title = title;
m_Artist.clear();
m_Album.clear();
} }
} }
} }

View File

@ -57,6 +57,7 @@ private:
HWND m_Window; // Winamp window HWND m_Window; // Winamp window
bool m_UseUnicodeAPI; bool m_UseUnicodeAPI;
bool m_PlayingStream;
WINAMPTYPE m_WinampType; WINAMPTYPE m_WinampType;
HANDLE m_WinampHandle; // Handle to Winamp process HANDLE m_WinampHandle; // Handle to Winamp process
LPCVOID m_WinampAddress; LPCVOID m_WinampAddress;

View File

@ -12,7 +12,7 @@
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,1,3,1 FILEVERSION 1,1,3,2
PRODUCTVERSION PRODUCTVER PRODUCTVERSION PRODUCTVER
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
#ifdef _DEBUG #ifdef _DEBUG
@ -29,7 +29,7 @@ BEGIN
BLOCK "040904E4" BLOCK "040904E4"
BEGIN BEGIN
VALUE "FileDescription", "NowPlaying Plugin for Rainmeter" VALUE "FileDescription", "NowPlaying Plugin for Rainmeter"
VALUE "FileVersion", "1.1.3.1" VALUE "FileVersion", "1.1.3.2"
VALUE "InternalName", "NowPlaying" VALUE "InternalName", "NowPlaying"
VALUE "LegalCopyright", "Copyright (C) 2011 - Birunthan Mohanathas" VALUE "LegalCopyright", "Copyright (C) 2011 - Birunthan Mohanathas"
VALUE "OriginalFilename", "NowPlaying.dll" VALUE "OriginalFilename", "NowPlaying.dll"