Skip to content

Commit

Permalink
Merge pull request #1804 from arnova/music_playlist_thumb_fix
Browse files Browse the repository at this point in the history
Music playlist thumb fix
  • Loading branch information
jmarshallnz committed Nov 20, 2012
2 parents 2b74a81 + 97fd66c commit 280ef5a
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 89 deletions.
9 changes: 8 additions & 1 deletion xbmc/FileItem.cpp
Expand Up @@ -2619,7 +2619,7 @@ bool CFileItemList::AlwaysCache() const
return false;
}

CStdString CFileItem::GetUserMusicThumb(bool alwaysCheckRemote /* = false */) const
CStdString CFileItem::GetUserMusicThumb(bool alwaysCheckRemote /* = false */, bool fallbackToFolder /* = false */) const
{
if (m_strPath.IsEmpty()
|| m_bIsShareOrDrive
Expand All @@ -2637,6 +2637,13 @@ CStdString CFileItem::GetUserMusicThumb(bool alwaysCheckRemote /* = false */) co
if (CFile::Exists(fileThumb))
return fileThumb;

// Fall back to folder thumb, if requested
if (!m_bIsFolder && fallbackToFolder)
{
CFileItem item(URIUtils::GetDirectory(m_strPath), true);
return item.GetUserMusicThumb(alwaysCheckRemote);
}

// if a folder, check for folder.jpg
if (m_bIsFolder && !IsFileFolder() && (!IsRemote() || alwaysCheckRemote || g_guiSettings.GetBool("musicfiles.findremotethumbs")))
{
Expand Down
2 changes: 1 addition & 1 deletion xbmc/FileItem.h
Expand Up @@ -307,7 +307,7 @@ class CFileItem :
CStdString GetBaseMoviePath(bool useFolderNames) const;

// Gets the user thumb, if it exists
CStdString GetUserMusicThumb(bool alwaysCheckRemote = false) const;
CStdString GetUserMusicThumb(bool alwaysCheckRemote = false, bool fallbackToFolder = false) const;

/*! \brief Get the path where we expect local metadata to reside.
For a folder, this is just the existing path (eg tvshow folder)
Expand Down
142 changes: 62 additions & 80 deletions xbmc/music/MusicInfoLoader.cpp
Expand Up @@ -34,6 +34,7 @@
#include "utils/log.h"
#include "Artist.h"
#include "Album.h"
#include "MusicThumbLoader.h"

using namespace std;
using namespace XFILE;
Expand All @@ -43,12 +44,15 @@ using namespace MUSIC_INFO;
CMusicInfoLoader::CMusicInfoLoader() : CBackgroundInfoLoader(1)
{
m_mapFileItems = new CFileItemList;

m_thumbLoader = new CMusicThumbLoader();
}

CMusicInfoLoader::~CMusicInfoLoader()
{
StopThread();
delete m_mapFileItems;
delete m_thumbLoader;
}

void CMusicInfoLoader::OnLoaderStart()
Expand All @@ -71,6 +75,9 @@ void CMusicInfoLoader::OnLoaderStart()
m_pProgressCallback->SetProgressMax(m_pVecItems->GetFileCount());

m_musicDatabase.Open();

if (m_thumbLoader)
m_thumbLoader->Initialize();
}

bool CMusicInfoLoader::LoadAdditionalTagInfo(CFileItem* pItem)
Expand Down Expand Up @@ -124,59 +131,64 @@ bool CMusicInfoLoader::LoadItem(CFileItem* pItem)
if (pItem->m_bIsFolder || pItem->IsPlayList() || pItem->IsNFO() || pItem->IsInternetStream())
return false;

if (pItem->HasMusicInfoTag() && pItem->GetMusicInfoTag()->Loaded())
return true;

// first check the cached item
CFileItemPtr mapItem = (*m_mapFileItems)[pItem->GetPath()];
if (mapItem && mapItem->m_dateTime==pItem->m_dateTime && mapItem->HasMusicInfoTag() && mapItem->GetMusicInfoTag()->Loaded())
{ // Query map if we previously cached the file on HD
*pItem->GetMusicInfoTag() = *mapItem->GetMusicInfoTag();
pItem->SetArt("thumb", mapItem->GetArt("thumb"));
return true;
}

CStdString strPath;
URIUtils::GetDirectory(pItem->GetPath(), strPath);
URIUtils::AddSlashAtEnd(strPath);
if (strPath!=m_strPrevPath)
if (!pItem->HasMusicInfoTag() || !pItem->GetMusicInfoTag()->Loaded())
{
// The item is from another directory as the last one,
// query the database for the new directory...
m_musicDatabase.GetSongsByPath(strPath, m_songsMap);
m_databaseHits++;
}
// first check the cached item
CFileItemPtr mapItem = (*m_mapFileItems)[pItem->GetPath()];
if (mapItem && mapItem->m_dateTime==pItem->m_dateTime && mapItem->HasMusicInfoTag() && mapItem->GetMusicInfoTag()->Loaded())
{ // Query map if we previously cached the file on HD
*pItem->GetMusicInfoTag() = *mapItem->GetMusicInfoTag();
pItem->SetArt("thumb", mapItem->GetArt("thumb"));
}
else
{
CStdString strPath;
URIUtils::GetDirectory(pItem->GetPath(), strPath);
URIUtils::AddSlashAtEnd(strPath);
if (strPath!=m_strPrevPath)
{
// The item is from another directory as the last one,
// query the database for the new directory...
m_musicDatabase.GetSongsByPath(strPath, m_songsMap);
m_databaseHits++;
}

CSong *song=NULL;
CSong *song=NULL;

if ((song=m_songsMap.Find(pItem->GetPath()))!=NULL)
{ // Have we loaded this item from database before
pItem->GetMusicInfoTag()->SetSong(*song);
pItem->SetArt("thumb", song->strThumb);
}
else if (pItem->IsMusicDb())
{ // a music db item that doesn't have tag loaded - grab details from the database
XFILE::MUSICDATABASEDIRECTORY::CQueryParams param;
XFILE::MUSICDATABASEDIRECTORY::CDirectoryNode::GetDatabaseInfo(pItem->GetPath(),param);
CSong song;
if (m_musicDatabase.GetSongById(param.GetSongId(), song))
{
pItem->GetMusicInfoTag()->SetSong(song);
pItem->SetArt("thumb", song.strThumb);
if ((song=m_songsMap.Find(pItem->GetPath()))!=NULL)
{ // Have we loaded this item from database before
pItem->GetMusicInfoTag()->SetSong(*song);
pItem->SetArt("thumb", song->strThumb);
}
else if (pItem->IsMusicDb())
{ // a music db item that doesn't have tag loaded - grab details from the database
XFILE::MUSICDATABASEDIRECTORY::CQueryParams param;
XFILE::MUSICDATABASEDIRECTORY::CDirectoryNode::GetDatabaseInfo(pItem->GetPath(),param);
CSong song;
if (m_musicDatabase.GetSongById(param.GetSongId(), song))
{
pItem->GetMusicInfoTag()->SetSong(song);
pItem->SetArt("thumb", song.strThumb);
}
}
else if (g_guiSettings.GetBool("musicfiles.usetags") || pItem->IsCDDA())
{ // Nothing found, load tag from file,
// always try to load cddb info
// get correct tag parser
auto_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(pItem->GetPath()));
if (NULL != pLoader.get())
// get tag
pLoader->Load(pItem->GetPath(), *pItem->GetMusicInfoTag());
m_tagReads++;
}

m_strPrevPath = strPath;
}
}
else if (g_guiSettings.GetBool("musicfiles.usetags") || pItem->IsCDDA())
{ // Nothing found, load tag from file,
// always try to load cddb info
// get correct tag parser
auto_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(pItem->GetPath()));
if (NULL != pLoader.get())
// get tag
pLoader->Load(pItem->GetPath(), *pItem->GetMusicInfoTag());
m_tagReads++;
}

m_strPrevPath = strPath;
// Get thumb for item
m_thumbLoader->LoadItem(pItem);

return true;
}

Expand All @@ -188,46 +200,16 @@ void CMusicInfoLoader::OnLoaderFinish()
// cleanup cache loaded from HD
m_mapFileItems->Clear();

if (!m_bStop)
{ // check for art
VECSONGS songs;
songs.reserve(m_pVecItems->Size());
for (int i = 0; i < m_pVecItems->Size(); ++i)
{
CFileItemPtr pItem = m_pVecItems->Get(i);
if (pItem->m_bIsFolder || pItem->IsPlayList() || pItem->IsNFO() || pItem->IsInternetStream())
continue;
if (pItem->HasMusicInfoTag() && pItem->GetMusicInfoTag()->Loaded())
{
CSong song(*pItem->GetMusicInfoTag());
song.strThumb = pItem->GetArt("thumb");
song.idSong = i; // for the lookup below
songs.push_back(song);
}
}
VECALBUMS albums;
CMusicInfoScanner::CategoriseAlbums(songs, albums);
CMusicInfoScanner::FindArtForAlbums(albums, m_pVecItems->GetPath());
for (VECALBUMS::iterator i = albums.begin(); i != albums.end(); ++i)
{
string albumArt = i->art["thumb"];
for (VECSONGS::iterator j = i->songs.begin(); j != i->songs.end(); ++j)
{
if (!j->strThumb.empty())
m_pVecItems->Get(j->idSong)->SetArt("thumb", j->strThumb);
else
m_pVecItems->Get(j->idSong)->SetArt("thumb", albumArt);
}
}
}

// Save loaded items to HD
if (!m_strCacheFileName.IsEmpty())
SaveCache(m_strCacheFileName, *m_pVecItems);
else if (!m_bStop && (m_databaseHits > 1 || m_tagReads > 0))
m_pVecItems->Save();

m_musicDatabase.Close();

if (m_thumbLoader)
m_thumbLoader->Deinitialize();
}

void CMusicInfoLoader::UseCacheOnHD(const CStdString& strFileName)
Expand Down
2 changes: 2 additions & 0 deletions xbmc/music/MusicInfoLoader.h
Expand Up @@ -22,6 +22,7 @@
#include "MusicDatabase.h"

class CFileItemList;
class CMusicThumbLoader;

namespace MUSIC_INFO
{
Expand All @@ -48,5 +49,6 @@ class CMusicInfoLoader : public CBackgroundInfoLoader
CMusicDatabase m_musicDatabase;
unsigned int m_databaseHits;
unsigned int m_tagReads;
CMusicThumbLoader *m_thumbLoader;
};
}
32 changes: 27 additions & 5 deletions xbmc/music/MusicThumbLoader.cpp
Expand Up @@ -45,15 +45,20 @@ void CMusicThumbLoader::Initialize()
m_albumArt.clear();
}

void CMusicThumbLoader::Deinitialize()
{
m_database->Close();
m_albumArt.clear();
}

void CMusicThumbLoader::OnLoaderStart()
{
Initialize();
}

void CMusicThumbLoader::OnLoaderFinish()
{
m_database->Close();
m_albumArt.clear();
Deinitialize();
}

bool CMusicThumbLoader::LoadItem(CFileItem* pItem)
Expand Down Expand Up @@ -90,19 +95,36 @@ bool CMusicThumbLoader::LoadItem(CFileItem* pItem)
}

if (!pItem->HasArt("thumb"))
FillThumb(*pItem);
{
// Look for embedded art
if (pItem->HasMusicInfoTag() && !pItem->GetMusicInfoTag()->GetCoverArtInfo().empty())
{
// The item has got embedded art but user thumbs overrule, so check for those first
if (!FillThumb(*pItem, false)) // Check for user thumbs but ignore folder thumbs
{
// No user thumb, use embedded art
CStdString thumb = CTextureCache::GetWrappedImageURL(pItem->GetPath(), "music");
pItem->SetArt("thumb", thumb);
}
}
else
{
// Check for user thumbs
FillThumb(*pItem, true);
}
}

return true;
}

bool CMusicThumbLoader::FillThumb(CFileItem &item)
bool CMusicThumbLoader::FillThumb(CFileItem &item, bool folderThumbs /* = true */)
{
if (item.HasArt("thumb"))
return true;
CStdString thumb = GetCachedImage(item, "thumb");
if (thumb.IsEmpty())
{
thumb = item.GetUserMusicThumb();
thumb = item.GetUserMusicThumb(false, folderThumbs);
if (!thumb.IsEmpty())
SetCachedImage(item, "thumb", thumb);
}
Expand Down
6 changes: 4 additions & 2 deletions xbmc/music/MusicThumbLoader.h
Expand Up @@ -37,6 +37,8 @@ class CMusicThumbLoader : public CThumbLoader
virtual ~CMusicThumbLoader();

virtual void Initialize();
virtual void Deinitialize();

virtual bool LoadItem(CFileItem* pItem);

/*! \brief helper function to fill the art for a video library item
Expand All @@ -51,10 +53,10 @@ class CMusicThumbLoader : public CThumbLoader
\param item the CFileItem object to fill
\return true if we fill the thumb, false otherwise
*/
static bool FillThumb(CFileItem &item);
static bool FillThumb(CFileItem &item, bool folderThumbs = true);

static bool GetEmbeddedThumb(const std::string &path, MUSIC_INFO::EmbeddedArt &art);

protected:
virtual void OnLoaderStart();
virtual void OnLoaderFinish();
Expand Down

0 comments on commit 280ef5a

Please sign in to comment.