CSong::CSong(CFileItem& item) { CMusicInfoTag& tag = *item.GetMusicInfoTag(); SYSTEMTIME stTime; tag.GetReleaseDate(stTime); strTitle = tag.GetTitle(); genre = tag.GetGenre(); artist = tag.GetArtist(); strAlbum = tag.GetAlbum(); albumArtist = tag.GetAlbumArtist(); strMusicBrainzTrackID = tag.GetMusicBrainzTrackID(); strComment = tag.GetComment(); rating = tag.GetRating(); iYear = stTime.wYear; iTrack = tag.GetTrackAndDiskNumber(); iDuration = tag.GetDuration(); bCompilation = tag.GetCompilation(); embeddedArt = tag.GetCoverArtInfo(); strFileName = tag.GetURL().IsEmpty() ? item.GetPath() : tag.GetURL(); strThumb = item.GetUserMusicThumb(true); iStartOffset = item.m_lStartOffset; iEndOffset = item.m_lEndOffset; idSong = -1; iTimesPlayed = 0; iKaraokeNumber = 0; iKaraokeDelay = 0; //! Karaoke song lyrics-music delay in 1/10 seconds. idAlbum = -1; }
CSong::CSong(CFileItem& item) { CMusicInfoTag& tag = *item.GetMusicInfoTag(); SYSTEMTIME stTime; tag.GetReleaseDate(stTime); strTitle = tag.GetTitle(); genre = tag.GetGenre(); std::vector<std::string> artist = tag.GetArtist(); strArtistDesc = tag.GetArtistString(); //Set sort string before processing artist credits strArtistSort = tag.GetArtistSort(); m_strComposerSort = tag.GetComposerSort(); // Determine artist credits from various tag arrays SetArtistCredits(tag.GetArtist(), tag.GetMusicBrainzArtistHints(), tag.GetMusicBrainzArtistID()); strAlbum = tag.GetAlbum(); m_albumArtist = tag.GetAlbumArtist(); // Separate album artist names further, if possible, and trim blank space. if (tag.GetMusicBrainzAlbumArtistHints().size() > m_albumArtist.size()) // Make use of hints (ALBUMARTISTS tag), when present, to separate artist names m_albumArtist = tag.GetMusicBrainzAlbumArtistHints(); else // Split album artist names further using multiple possible delimiters, over single separator applied in Tag loader m_albumArtist = StringUtils::SplitMulti(m_albumArtist, g_advancedSettings.m_musicArtistSeparators); for (auto artistname : m_albumArtist) StringUtils::Trim(artistname); m_strAlbumArtistSort = tag.GetAlbumArtistSort(); strMusicBrainzTrackID = tag.GetMusicBrainzTrackID(); m_musicRoles = tag.GetContributors(); strComment = tag.GetComment(); strCueSheet = tag.GetCueSheet(); strMood = tag.GetMood(); rating = tag.GetRating(); userrating = tag.GetUserrating(); votes = tag.GetVotes(); iYear = stTime.wYear; iTrack = tag.GetTrackAndDiscNumber(); iDuration = tag.GetDuration(); strRecordLabel = tag.GetRecordLabel(); strAlbumType = tag.GetMusicBrainzReleaseType(); bCompilation = tag.GetCompilation(); embeddedArt = tag.GetCoverArtInfo(); strFileName = tag.GetURL().empty() ? item.GetPath() : tag.GetURL(); dateAdded = tag.GetDateAdded(); replayGain = tag.GetReplayGain(); strThumb = item.GetUserMusicThumb(true); iStartOffset = item.m_lStartOffset; iEndOffset = item.m_lEndOffset; idSong = -1; iTimesPlayed = 0; idAlbum = -1; }
bool CMusicThumbLoader::FillThumb(CFileItem &item, bool folderThumbs /* = true */) { if (item.HasArt("thumb")) return true; CStdString thumb = GetCachedImage(item, "thumb"); if (thumb.empty()) { thumb = item.GetUserMusicThumb(false, folderThumbs); if (!thumb.empty()) SetCachedImage(item, "thumb", thumb); } item.SetArt("thumb", thumb); return !thumb.empty(); }
bool CMusicThumbLoader::FillThumb(CFileItem &item) { if (item.HasArt("thumb")) return true; CStdString thumb = GetCachedImage(item, "thumb"); if (thumb.IsEmpty()) { thumb = item.GetUserMusicThumb(); if (!thumb.IsEmpty()) SetCachedImage(item, "thumb", thumb); } item.SetArt("thumb", thumb); return !thumb.IsEmpty(); }
CSong::CSong(CFileItem& item) { CMusicInfoTag& tag = *item.GetMusicInfoTag(); SYSTEMTIME stTime; tag.GetReleaseDate(stTime); strTitle = tag.GetTitle(); genre = tag.GetGenre(); std::vector<std::string> artist = tag.GetArtist(); std::vector<std::string> musicBrainArtistHints = tag.GetMusicBrainzArtistHints(); strArtistDesc = tag.GetArtistString(); if (!tag.GetMusicBrainzArtistID().empty()) { // have musicbrainz artist info, so use it for (size_t i = 0; i < tag.GetMusicBrainzArtistID().size(); i++) { std::string artistId = tag.GetMusicBrainzArtistID()[i]; std::string artistName; /* We try and get the corresponding artist name from the hints list. If the hints list is missing or the wrong length, it will try the artist list. We match on the same index, and if that fails just use the first name we have. */ if (i < musicBrainArtistHints.size()) artistName = musicBrainArtistHints[i]; else if (!artist.empty()) artistName = (i < artist.size()) ? artist[i] : artist[0]; if (artistName.empty()) artistName = artistId; std::string strJoinPhrase = (i == tag.GetMusicBrainzArtistID().size()-1) ? "" : g_advancedSettings.m_musicItemSeparator; CArtistCredit artistCredit(artistName, artistId, strJoinPhrase); artistCredits.push_back(artistCredit); } } else { // no musicbrainz info, so fill in directly for (std::vector<std::string>::const_iterator it = tag.GetArtist().begin(); it != tag.GetArtist().end(); ++it) { std::string strJoinPhrase = (it == --tag.GetArtist().end() ? "" : g_advancedSettings.m_musicItemSeparator); CArtistCredit artistCredit(*it, "", strJoinPhrase); artistCredits.push_back(artistCredit); } } strAlbum = tag.GetAlbum(); m_albumArtist = tag.GetAlbumArtist(); strMusicBrainzTrackID = tag.GetMusicBrainzTrackID(); strComment = tag.GetComment(); strCueSheet = tag.GetCueSheet(); strMood = tag.GetMood(); rating = tag.GetRating(); userrating = tag.GetUserrating(); votes = tag.GetVotes(); iYear = stTime.wYear; iTrack = tag.GetTrackAndDiscNumber(); iDuration = tag.GetDuration(); bCompilation = tag.GetCompilation(); embeddedArt = tag.GetCoverArtInfo(); strFileName = tag.GetURL().empty() ? item.GetPath() : tag.GetURL(); dateAdded = tag.GetDateAdded(); strThumb = item.GetUserMusicThumb(true); iStartOffset = item.m_lStartOffset; iEndOffset = item.m_lEndOffset; idSong = -1; iTimesPlayed = 0; idAlbum = -1; }
CSong::CSong(CFileItem& item) { CMusicInfoTag& tag = *item.GetMusicInfoTag(); SYSTEMTIME stTime; tag.GetReleaseDate(stTime); strTitle = tag.GetTitle(); genre = tag.GetGenre(); std::vector<std::string> artist = tag.GetArtist(); std::vector<std::string> musicBrainzArtistHints = tag.GetMusicBrainzArtistHints(); strArtistDesc = tag.GetArtistString(); if (!tag.GetMusicBrainzArtistID().empty()) { // Have musicbrainz artist info, so use it // Vector of possible separators in the order least likely to be part of artist name const std::vector<std::string> separators{ " feat. ", " ft. ", " Feat. "," Ft. ", ";", ":", "|", "#", "/", " with ", ",", "&" }; // Establish tag consistency - do the number of musicbrainz ids and number of names in hints or artist match if (tag.GetMusicBrainzArtistID().size() != musicBrainzArtistHints.size() && tag.GetMusicBrainzArtistID().size() != artist.size()) { // Tags mis-match - report it and then try to fix CLog::Log(LOGDEBUG, "Mis-match in song file tags: %i mbid %i names %s %s", (int)tag.GetMusicBrainzArtistID().size(), (int)artist.size(), strTitle.c_str(), strArtistDesc.c_str()); /* Most likey we have no hints and a single artist name like "Artist1 feat. Artist2" or "Composer; Conductor, Orchestra, Soloist" or "Artist1/Artist2" where the expected single item separator (default = space-slash-space) as not been used. Ampersand (&), comma and slash (no spaces) are poor delimiters as could be in name e.g. "AC/DC", "Earth, Wind & Fire", but here treat them as such in attempt to find artist names. When there are hints but count not match mbid they could be poorly formatted using unexpected separators so attempt to split them. Or we could have more hints or artist names than musicbrainz id so ingore them but raise warning. */ // Do hints exist yet mis-match if (musicBrainzArtistHints.size() > 0 && musicBrainzArtistHints.size() != tag.GetMusicBrainzArtistID().size()) { if (artist.size() == tag.GetMusicBrainzArtistID().size()) // Artist name count matches, use that as hints musicBrainzArtistHints = artist; else if (musicBrainzArtistHints.size() < tag.GetMusicBrainzArtistID().size()) { // Try splitting the hints until have matching number musicBrainzArtistHints = StringUtils::SplitMulti(musicBrainzArtistHints, separators, tag.GetMusicBrainzArtistID().size()); } else // Extra hints, discard them. musicBrainzArtistHints.resize(tag.GetMusicBrainzArtistID().size()); } // Do hints not exist or still mis-match, try artists if (musicBrainzArtistHints.size() != tag.GetMusicBrainzArtistID().size()) musicBrainzArtistHints = artist; // Still mis-match, try splitting the hints (now artists) until have matching number if (musicBrainzArtistHints.size() < tag.GetMusicBrainzArtistID().size()) { musicBrainzArtistHints = StringUtils::SplitMulti(musicBrainzArtistHints, separators, tag.GetMusicBrainzArtistID().size()); } } else { // Either hints or artist names (or both) matches number of musicbrainz id // If hints mis-match, use artists if (musicBrainzArtistHints.size() != tag.GetMusicBrainzArtistID().size()) musicBrainzArtistHints = tag.GetArtist(); } for (size_t i = 0; i < tag.GetMusicBrainzArtistID().size(); i++) { std::string artistId = tag.GetMusicBrainzArtistID()[i]; std::string artistName; /* We try and get the corresponding artist name from the hints list. Having already attempted to make the number of hints match, if they still don't then use musicbrainz id as the name and hope later on we can update that entry. */ if (i < musicBrainzArtistHints.size()) artistName = musicBrainzArtistHints[i]; else artistName = artistId; artistCredits.emplace_back(StringUtils::Trim(artistName), artistId); } } else { // No musicbrainz artist ids, so fill in directly // Separate artist names further, if possible, and trim blank space. if (musicBrainzArtistHints.size() > tag.GetArtist().size()) // Make use of hints (ARTISTS tag), when present, to separate artist names artist = musicBrainzArtistHints; else // Split artist names further using multiple possible delimiters, over single separator applied in Tag loader artist = StringUtils::SplitMulti(artist, g_advancedSettings.m_musicArtistSeparators); for (auto artistname: artist) { artistCredits.emplace_back(StringUtils::Trim(artistname)); } } strAlbum = tag.GetAlbum(); m_albumArtist = tag.GetAlbumArtist(); // Separate album artist names further, if possible, and trim blank space. if (tag.GetMusicBrainzAlbumArtistHints().size() > m_albumArtist.size()) // Make use of hints (ALBUMARTISTS tag), when present, to separate artist names m_albumArtist = tag.GetMusicBrainzAlbumArtistHints(); else // Split album artist names further using multiple possible delimiters, over single separator applied in Tag loader m_albumArtist = StringUtils::SplitMulti(m_albumArtist, g_advancedSettings.m_musicArtistSeparators); for (auto artistname : m_albumArtist) StringUtils::Trim(artistname); strMusicBrainzTrackID = tag.GetMusicBrainzTrackID(); m_musicRoles = tag.GetContributors(); strComment = tag.GetComment(); strCueSheet = tag.GetCueSheet(); strMood = tag.GetMood(); rating = tag.GetRating(); userrating = tag.GetUserrating(); votes = tag.GetVotes(); iYear = stTime.wYear; iTrack = tag.GetTrackAndDiscNumber(); iDuration = tag.GetDuration(); strRecordLabel = tag.GetRecordLabel(); strAlbumType = tag.GetMusicBrainzReleaseType(); bCompilation = tag.GetCompilation(); embeddedArt = tag.GetCoverArtInfo(); strFileName = tag.GetURL().empty() ? item.GetPath() : tag.GetURL(); dateAdded = tag.GetDateAdded(); strThumb = item.GetUserMusicThumb(true); iStartOffset = item.m_lStartOffset; iEndOffset = item.m_lEndOffset; idSong = -1; iTimesPlayed = 0; idAlbum = -1; }