aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthe-black-eagle <g.moore@gmx.co.uk>2022-02-17 19:59:08 +0000
committerthe-black-eagle <g.moore@gmx.co.uk>2023-09-13 10:23:31 +0100
commit78c00ad9a64bbec208803548939ff089cc183094 (patch)
tree7b82e1641232cce696c5f80f2067c1478b0ff3a0
parent5422ac5f4217b9b3690396a8e2c31bb68d90078a (diff)
[MUSIC] Add, store and process scraped video links for artist songs
-rw-r--r--xbmc/GUIInfoManager.cpp8
-rw-r--r--xbmc/addons/Scraper.cpp17
-rw-r--r--xbmc/guilib/guiinfo/GUIInfoLabels.h1
-rw-r--r--xbmc/guilib/guiinfo/MusicGUIInfo.cpp3
-rw-r--r--xbmc/music/Artist.cpp29
-rw-r--r--xbmc/music/Artist.h10
-rw-r--r--xbmc/music/MusicDatabase.cpp150
-rw-r--r--xbmc/music/MusicDatabase.h9
-rw-r--r--xbmc/music/Song.cpp3
-rw-r--r--xbmc/music/Song.h1
-rw-r--r--xbmc/music/tags/MusicInfoTag.cpp15
-rw-r--r--xbmc/music/tags/MusicInfoTag.h3
12 files changed, 238 insertions, 11 deletions
diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp
index ac4e0f7d41..130204dfc8 100644
--- a/xbmc/GUIInfoManager.cpp
+++ b/xbmc/GUIInfoManager.cpp
@@ -6857,6 +6857,13 @@ const infomap container_str[] = {{ "property", CONTAINER_PROPERTY },
/// <p><hr>
/// @skinning_v20 **[New Infolabel]** \link ListItem_HdrType `ListItem.HdrType`\endlink
/// }
+/// \table_row3{ <b>`ListItem.SongVideoURL`</b>,
+/// \anchor ListItem_SongVideoURL
+/// _string_,
+/// @return Link to a video of a song
+/// <p><hr>
+/// @skinning_v21 **[New Infolabel]** \link ListItem_SongVideoURL `ListItem.SongVideoURL`\endlink
+/// }
/// \table_end
///
/// -----------------------------------------------------------------------------
@@ -7069,6 +7076,7 @@ const infomap listitem_labels[]= {{ "thumb", LISTITEM_THUMB },
{ "albumstatus", LISTITEM_ALBUMSTATUS },
{ "isautoupdateable", LISTITEM_ISAUTOUPDATEABLE },
{ "hdrtype", LISTITEM_VIDEO_HDR_TYPE },
+ { "songvideourl", LISTITEM_SONG_VIDEO_URL },
};
/// \page modules__infolabels_boolean_conditions
diff --git a/xbmc/addons/Scraper.cpp b/xbmc/addons/Scraper.cpp
index 30c22473af..ad7b251052 100644
--- a/xbmc/addons/Scraper.cpp
+++ b/xbmc/addons/Scraper.cpp
@@ -816,6 +816,23 @@ void DetailsFromFileItem<CArtist>(const CFileItem &item, CArtist &artist)
artist.discography.emplace_back(discoAlbum);
}
+ const int numvideolinks = item.GetProperty("artist.videolinks").asInteger32();
+ if (numvideolinks > 0)
+ {
+ artist.videolinks.reserve(numvideolinks);
+ for (int i = 1; i <= numvideolinks; ++i)
+ {
+ std::stringstream prefix;
+ prefix << "artist.videolink" << i;
+ ArtistVideoLinks videoLink;
+ videoLink.title = FromString(item, prefix.str() + ".title");
+ videoLink.mbTrackID = FromString(item, prefix.str() + ".mbtrackid");
+ videoLink.videoURL = FromString(item, prefix.str() + ".url");
+ videoLink.thumbURL = FromString(item, prefix.str() + ".thumb");
+ artist.videolinks.emplace_back(std::move(videoLink));
+ }
+ }
+
int nThumbs = item.GetProperty("artist.thumbs").asInteger32();
ParseThumbs(artist.thumbURL, item, nThumbs, "artist.thumb");
diff --git a/xbmc/guilib/guiinfo/GUIInfoLabels.h b/xbmc/guilib/guiinfo/GUIInfoLabels.h
index 5d186bc2ef..dfb5b7f422 100644
--- a/xbmc/guilib/guiinfo/GUIInfoLabels.h
+++ b/xbmc/guilib/guiinfo/GUIInfoLabels.h
@@ -962,6 +962,7 @@
#define LISTITEM_ALBUMSTATUS (LISTITEM_START + 206)
#define LISTITEM_ISAUTOUPDATEABLE (LISTITEM_START + 207)
#define LISTITEM_VIDEO_HDR_TYPE (LISTITEM_START + 208)
+#define LISTITEM_SONG_VIDEO_URL (LISTITEM_START + 209)
#define LISTITEM_END (LISTITEM_START + 2500)
diff --git a/xbmc/guilib/guiinfo/MusicGUIInfo.cpp b/xbmc/guilib/guiinfo/MusicGUIInfo.cpp
index f58a9ae3c4..ca79c2c8de 100644
--- a/xbmc/guilib/guiinfo/MusicGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/MusicGUIInfo.cpp
@@ -403,6 +403,9 @@ bool CMusicGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
return true;
}
break;
+ case LISTITEM_SONG_VIDEO_URL:
+ value = tag->GetSongVideoURL();
+ return true;
}
}
diff --git a/xbmc/music/Artist.cpp b/xbmc/music/Artist.cpp
index 786f7a737b..c5626c58eb 100644
--- a/xbmc/music/Artist.cpp
+++ b/xbmc/music/Artist.cpp
@@ -62,6 +62,7 @@ void CArtist::MergeScrapedArtist(const CArtist& source, bool override /* = true
art = source.art;
discography = source.discography;
+ videolinks = source.videolinks;
}
@@ -133,6 +134,24 @@ bool CArtist::Load(const TiXmlElement *artist, bool append, bool prioritise)
node = node->NextSiblingElement("album");
}
+ //song video links
+ const TiXmlElement* songurls = artist->FirstChildElement("videourl");
+ if (songurls)
+ videolinks.clear();
+ while (songurls)
+ {
+ if (songurls->FirstChild())
+ {
+ ArtistVideoLinks videoLink;
+ XMLUtils::GetString(songurls, "title", videoLink.title);
+ XMLUtils::GetString(songurls, "musicbrainztrackid", videoLink.mbTrackID);
+ XMLUtils::GetString(songurls, "url", videoLink.videoURL);
+ XMLUtils::GetString(songurls, "thumburl", videoLink.thumbURL);
+ videolinks.emplace_back(std::move(videoLink));
+ }
+ songurls = songurls->NextSiblingElement("videourl");
+ }
+
// Support old style <fanart></fanart> for backwards compatibility of old nfo files and scrapers
const TiXmlElement *fanart2 = artist->FirstChildElement("fanart");
if (fanart2)
@@ -218,6 +237,16 @@ bool CArtist::Save(TiXmlNode *node, const std::string &tag, const std::string& s
XMLUtils::SetString(node, "year", it.strYear);
XMLUtils::SetString(node, "musicbrainzreleasegroupid", it.strReleaseGroupMBID);
}
+ // song video links
+ for (const auto& it : videolinks)
+ {
+ TiXmlElement videolinkElement("videourl");
+ TiXmlNode* node = artist->InsertEndChild(videolinkElement);
+ XMLUtils::SetString(node, "title", it.title);
+ XMLUtils::SetString(node, "musicbrainztrackid", it.mbTrackID);
+ XMLUtils::SetString(node, "url", it.videoURL);
+ XMLUtils::SetString(node, "thumburl", it.thumbURL);
+ }
return true;
}
diff --git a/xbmc/music/Artist.h b/xbmc/music/Artist.h
index 2ec77a8254..8791288f26 100644
--- a/xbmc/music/Artist.h
+++ b/xbmc/music/Artist.h
@@ -29,6 +29,14 @@ public:
std::string strReleaseGroupMBID;
};
+struct ArtistVideoLinks
+{
+ std::string title;
+ std::string mbTrackID;
+ std::string videoURL;
+ std::string thumbURL;
+};
+
class CArtist
{
public:
@@ -76,6 +84,7 @@ public:
dateNew.Reset();
bScrapedMBID = false;
strLastScraped.clear();
+ videolinks.clear();
}
/*! \brief Load artist information from an XML file.
@@ -117,6 +126,7 @@ public:
CDateTime dateNew; // Time db record created
bool bScrapedMBID = false;
std::string strLastScraped;
+ std::vector<ArtistVideoLinks> videolinks;
};
class CArtistCredit
diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp
index 69819a98e4..dd54a6379a 100644
--- a/xbmc/music/MusicDatabase.cpp
+++ b/xbmc/music/MusicDatabase.cpp
@@ -203,6 +203,7 @@ void CMusicDatabase::CreateTables()
" comment text, mood text, iBPM INTEGER NOT NULL DEFAULT 0, "
" iBitRate INTEGER NOT NULL DEFAULT 0, "
" iSampleRate INTEGER NOT NULL DEFAULT 0, iChannels INTEGER NOT NULL DEFAULT 0, "
+ " strVideoURL TEXT, "
" strReplayGain text, "
" dateAdded TEXT, dateNew TEXT, dateModified TEXT)");
CLog::Log(LOGINFO, "create song_artist table");
@@ -452,6 +453,7 @@ void CMusicDatabase::CreateViews()
" iBitRate, "
" iSampleRate, "
" iChannels, "
+ " song.strVideoURL as strVideoURL, "
" album.iAlbumDuration AS iAlbumDuration, "
" album.iDiscTotal as iDiscTotal, "
" song.dateAdded as dateAdded, "
@@ -769,6 +771,7 @@ bool CMusicDatabase::AddAlbum(CAlbum& album, int idSource)
song->userrating, //
song->votes, //
song->iBPM, song->iBitRate, song->iSampleRate, song->iChannels, //
+ song->songVideoURL, //
song->replayGain);
// Song must have at least one artist so set artist to [Missing]
@@ -1019,6 +1022,7 @@ int CMusicDatabase::AddSong(const int idSong,
int iBitRate,
int iSampleRate,
int iChannels,
+ const std::string& songVideoURL,
const ReplayGain& replayGain)
{
int idNew = -1;
@@ -1146,7 +1150,7 @@ int CMusicDatabase::AddSong(const int idSong,
dtLastPlayed, //
rating, userrating, votes, //
replayGain, //
- iBPM, iBitRate, iSampleRate, iChannels);
+ iBPM, iBitRate, iSampleRate, iChannels, songVideoURL);
}
if (!strThumb.empty())
SetArtForItem(idNew, MediaTypeSong, "thumb", strThumb);
@@ -1238,7 +1242,8 @@ bool CMusicDatabase::UpdateSong(CSong& song, bool bArtists /*= true*/, bool bArt
song.lastPlayed, //
song.rating, song.userrating, song.votes, //
song.replayGain, //
- song.iBPM, song.iBitRate, song.iSampleRate, song.iChannels);
+ song.iBPM, song.iBitRate, song.iSampleRate, song.iChannels, //
+ song.songVideoURL);
if (result < 0)
return false;
@@ -1297,7 +1302,8 @@ int CMusicDatabase::UpdateSong(int idSong,
int iBPM,
int iBitRate,
int iSampleRate,
- int iChannels)
+ int iChannels,
+ const std::string& songVideoURL)
{
if (idSong < 0)
return -1;
@@ -1319,7 +1325,7 @@ int CMusicDatabase::UpdateSong(int idSong,
" strTitle = '%s', iTrack = %i, iDuration = %i, "
"strReleaseDate = '%s', strOrigReleaseDate = '%s', strDiscSubtitle = '%s', "
"strFileName = '%s', iBPM = %i, iBitrate = %i, iSampleRate = %i, iChannels = %i, "
- "dateAdded = '%s'",
+ "dateAdded = '%s', strVideoURL = '%s'",
idPath, artistDisp.c_str(),
StringUtils::Join(
genres,
@@ -1327,7 +1333,7 @@ int CMusicDatabase::UpdateSong(int idSong,
.c_str(),
strTitle.c_str(), iTrack, iDuration, strRelease.c_str(), strOriginal.c_str(),
strDiscSubtitle.c_str(), strFileName.c_str(), iBPM, iBitRate, iSampleRate, iChannels,
- strDateMedia.c_str());
+ strDateMedia.c_str(), songVideoURL.c_str());
if (strMusicBrainzTrackID.empty())
strSQL += PrepareSQL(", strMusicBrainzTrackID = NULL");
else
@@ -1756,6 +1762,11 @@ bool CMusicDatabase::UpdateArtist(const CArtist& artist)
AddArtistDiscography(artist.idArtist, disc);
}
+ if (!DeleteArtistVideoLinks(artist.idArtist))
+ CLog::Log(LOGERROR, "MusicDatabase: Error deleting ArtistVideoLinks");
+
+ AddArtistVideoLinks(artist);
+
// Set current artwork (held in art table)
if (!artist.art.empty())
SetArtForItem(artist.idArtist, MediaTypeArtist, artist.art);
@@ -2037,6 +2048,8 @@ bool CMusicDatabase::GetArtist(int idArtist, CArtist& artist, bool fetchAll /* =
return false;
if (nullptr == m_pDS)
return false;
+ if (nullptr == m_pDS2)
+ return false;
if (idArtist == -1)
return false; // not in the database
@@ -2057,7 +2070,7 @@ bool CMusicDatabase::GetArtist(int idArtist, CArtist& artist, bool fetchAll /* =
m_pDS->close();
return false;
}
-
+ std::string debugSQL = strSQL + " - ";
int discographyOffset = artist_enumCount;
artist.discography.clear();
@@ -2077,12 +2090,36 @@ bool CMusicDatabase::GetArtist(int idArtist, CArtist& artist, bool fetchAll /* =
}
m_pDS->close(); // cleanup recordset data
+ artist.videolinks.clear();
+ if (fetchAll)
+ {
+ strSQL = PrepareSQL("SELECT idSong, strTitle, strMusicBrainzTrackID, strVideoURL, url "
+ "FROM song JOIN album_artist ON song.idAlbum = album_artist.idAlbum "
+ "LEFT JOIN art ON art.media_id = song.idSong AND art.type = 'videothumb' "
+ "WHERE album_artist.idArtist = %i AND "
+ "song.strVideoURL is not NULL GROUP by song.strVideoURL ORDER BY idSong",
+ idArtist);
+ debugSQL += strSQL;
+ m_pDS->query(strSQL);
+ while (!m_pDS->eof())
+ {
+ const dbiplus::sql_record* const record = m_pDS->get_sql_record();
+ ArtistVideoLinks videoLink;
+ videoLink.title = record->at(1).get_asString();
+ videoLink.mbTrackID = record->at(2).get_asString();
+ videoLink.videoURL = record->at(3).get_asString();
+ videoLink.thumbURL = record->at(4).get_asString();
+
+ artist.videolinks.emplace_back(std::move(videoLink));
+ m_pDS->next();
+ }
+ m_pDS->close();
+ }
+
auto end = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
- CLog::Log(LOGDEBUG, LOGDATABASE, "{0}({1}) - took {2} ms", __FUNCTION__, strSQL,
- duration.count());
-
+ CLog::LogF(LOGDEBUG, "{} - took {} ms", debugSQL, duration.count());
return true;
}
catch (...)
@@ -2180,6 +2217,92 @@ bool CMusicDatabase::ClearArtistLastScrapedTime(int idArtist)
return ExecuteQuery(strSQL);
}
+bool CMusicDatabase::AddArtistVideoLinks(const CArtist& artist)
+{
+ auto start = std::chrono::steady_clock::now();
+ std::string dbSong;
+
+ try
+ {
+ if (nullptr == m_pDB || nullptr == m_pDS || nullptr == m_pDS2)
+ return false;
+
+ for (const auto& videoURL : artist.videolinks)
+ {
+ dbSong = videoURL.title;
+ std::string strSQL = PrepareSQL(
+ "SELECT idSong, strTitle FROM song WHERE strMusicBrainzTrackID = '%s' OR (EXISTS "
+ "(SELECT 1 FROM album_artist WHERE album_artist.idAlbum = song.idAlbum AND "
+ "album_artist.idArtist = '%i' AND song.strTitle LIKE '%%%s%%'))",
+ videoURL.mbTrackID.c_str(), artist.idArtist, videoURL.title.c_str());
+
+ if (!m_pDS->query(strSQL))
+ return false;
+ if (m_pDS->num_rows() == 0)
+ continue;
+
+ while (!m_pDS->eof())
+ {
+ const int songId = m_pDS->fv(0).get_asInt();
+ std::string strSQL2 = PrepareSQL("UPDATE song SET strVideoURL='%s' WHERE idSong = %i",
+ videoURL.videoURL.c_str(), songId);
+ CLog::Log(LOGDEBUG, "Adding videolink for song {} with id {}", dbSong.c_str(), songId);
+ m_pDS2->exec(strSQL2);
+
+ if (!videoURL.thumbURL.empty())
+ { // already have a videothumb for this song ?
+ strSQL2 = PrepareSQL("SELECT art_id FROM art "
+ "WHERE media_id=%i AND media_type='%s' AND type='videothumb'",
+ songId, MediaTypeSong);
+ m_pDS2->query(strSQL2);
+ if (!m_pDS2->eof())
+ { // update existing thumb
+ const int artId = m_pDS2->fv(0).get_asInt();
+ m_pDS2->close();
+ strSQL2 = PrepareSQL("UPDATE art SET url='%s' where art_id=%d",
+ videoURL.thumbURL.c_str(), artId);
+ m_pDS2->exec(strSQL2);
+ }
+ else
+ { // insert new thumb
+ m_pDS2->close();
+ strSQL2 = PrepareSQL("INSERT INTO art(media_id, media_type, type, url) "
+ "VALUES (%d, '%s', '%s', '%s')",
+ songId, MediaTypeSong, "videothumb", videoURL.thumbURL.c_str());
+ m_pDS2->exec(strSQL2);
+ }
+ m_pDS2->close();
+ }
+ m_pDS->next();
+ }
+ m_pDS->close();
+ }
+ auto end = std::chrono::steady_clock::now();
+ auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
+ CLog::LogF(LOGDEBUG, "Time to store videolinks {}ms ", duration.count());
+ return true;
+ }
+ catch (...)
+ {
+ CLog::Log(LOGERROR, "MusicDatabase: Unable to add videolink for song ({})", dbSong.c_str());
+ return false;
+ }
+}
+
+bool CMusicDatabase::DeleteArtistVideoLinks(const int idArtist)
+{
+ std::string strSQL = PrepareSQL("UPDATE song SET strVideoURL = NULL WHERE idAlbum IN "
+ "(SELECT idAlbum FROM album_artist WHERE idArtist = %i)",
+ idArtist);
+ if (!ExecuteQuery(strSQL))
+ return false;
+ strSQL = PrepareSQL(
+ "DELETE FROM art WHERE art.type = 'videothumb' AND art.media_id IN (SELECT idSong FROM song "
+ "JOIN album_artist ON song.idAlbum = album_artist.idAlbum WHERE album_artist.idArtist = %i)",
+ idArtist);
+ return ExecuteQuery(strSQL);
+}
+
int CMusicDatabase::AddArtistDiscography(int idArtist, const CDiscoAlbum& discoAlbum)
{
std::string strSQL = PrepareSQL("INSERT INTO discography "
@@ -2994,6 +3117,7 @@ CSong CMusicDatabase::GetSongFromDataset(const dbiplus::sql_record* const record
song.iBitRate = record->at(offset + song_iBitRate).get_asInt();
song.iSampleRate = record->at(offset + song_iSampleRate).get_asInt();
song.iChannels = record->at(offset + song_iChannels).get_asInt();
+ song.songVideoURL = record->at(offset + song_songVideoURL).get_asString();
return song;
}
@@ -3056,6 +3180,7 @@ void CMusicDatabase::GetFileItemFromDataset(const dbiplus::sql_record* const rec
replaygain.Set(record->at(song_strReplayGain).get_asString());
item->GetMusicInfoTag()->SetReplayGain(replaygain);
item->GetMusicInfoTag()->SetTotalDiscs(record->at(song_iDiscTotal).get_asInt());
+ item->GetMusicInfoTag()->SetSongVideoURL(record->at(song_songVideoURL).get_asString());
item->GetMusicInfoTag()->SetLoaded(true);
// Get filename with full path
@@ -7578,6 +7703,7 @@ static const translateJSONField JSONtoDBSong[] = {
{ "bitrate", "integer", true, "iBitRate", "" },
{ "samplerate", "integer", true, "iSampleRate", "" },
{ "channels", "integer", true, "iChannels", "" },
+ { "songvideourl", "string", true, "strVideoURL", "" },
// JOIN fields (multivalue), same order as _JoinToSongFields
{ "albumartistid", "array", false, "idAlbumArtist", "album_artist.idArtist AS idAlbumArtist" },
@@ -9288,6 +9414,10 @@ void CMusicDatabase::UpdateTables(int version)
m_pDS->exec("DROP TABLE artist");
m_pDS->exec("ALTER TABLE artist_new RENAME TO artist");
}
+
+ if (version < 83)
+ m_pDS->exec("ALTER TABLE song ADD strVideoURL TEXT");
+
// Set the version of tag scanning required.
// Not every schema change requires the tags to be rescanned, set to the highest schema version
// that needs this. Forced rescanning (of music files that have not changed since they were
@@ -9308,7 +9438,7 @@ void CMusicDatabase::UpdateTables(int version)
int CMusicDatabase::GetSchemaVersion() const
{
- return 82;
+ return 83;
}
int CMusicDatabase::GetMusicNeedsTagScan()
diff --git a/xbmc/music/MusicDatabase.h b/xbmc/music/MusicDatabase.h
index 8544eb297d..791ff3d9cd 100644
--- a/xbmc/music/MusicDatabase.h
+++ b/xbmc/music/MusicDatabase.h
@@ -140,6 +140,7 @@ public:
\param rating [in] a rating for the song
\param userrating [in] a userrating (my rating) for the song
\param votes [in] a vote counter for the song rating
+ \param songVideoURL [in] url to video of the song
\param replayGain [in] album and track replaygain and peak values
\return the id of the song
*/
@@ -171,6 +172,7 @@ public:
int iBitRate,
int iSampleRate,
int iChannels,
+ const std::string& songVideoURL,
const ReplayGain& replayGain);
bool GetSong(int idSong, CSong& song);
@@ -210,6 +212,7 @@ public:
\param iBitRate [in] the bitrate of the song file
\param iSampleRate [in] the sample rate of the song file
\param iChannels [in] the number of audio channels in the song file
+ \param songVideoURL [in] url link to a video of the song
\return the id of the song
*/
int UpdateSong(int idSong,
@@ -238,7 +241,8 @@ public:
int iBPM,
int iBitRate,
int iSampleRate,
- int iChannels);
+ int iChannels,
+ const std::string& songVideoURL);
//// Misc Song
bool GetSongByFileName(const std::string& strFileName, CSong& song, int64_t startOffset = 0);
@@ -405,6 +409,8 @@ public:
int AddArtistDiscography(int idArtist, const CDiscoAlbum& discoAlbum);
bool DeleteArtistDiscography(int idArtist);
bool GetArtistDiscography(int idArtist, CFileItemList& items);
+ bool AddArtistVideoLinks(const CArtist& artist);
+ bool DeleteArtistVideoLinks(const int idArtist);
std::string GetArtistById(int id);
int GetArtistByName(const std::string& strArtist);
@@ -1017,6 +1023,7 @@ private:
song_iBitRate,
song_iSampleRate,
song_iChannels,
+ song_songVideoURL,
song_iAlbumDuration,
song_iDiscTotal,
song_dateAdded,
diff --git a/xbmc/music/Song.cpp b/xbmc/music/Song.cpp
index 165889ca92..93b2156d7b 100644
--- a/xbmc/music/Song.cpp
+++ b/xbmc/music/Song.cpp
@@ -75,6 +75,7 @@ CSong::CSong(CFileItem& item)
iSampleRate = tag.GetSampleRate();
iBitRate = tag.GetBitRate();
iChannels = tag.GetNoOfChannels();
+ songVideoURL = tag.GetSongVideoURL();
}
CSong::CSong()
@@ -239,6 +240,7 @@ void CSong::Serialize(CVariant& value) const
value["bitrate"] = iBitRate;
value["samplerate"] = iSampleRate;
value["channels"] = iChannels;
+ value["songvideourl"] = songVideoURL;
}
void CSong::Clear()
@@ -279,6 +281,7 @@ void CSong::Clear()
iBitRate = 0;
iSampleRate = 0;
iChannels = 0;
+ songVideoURL.clear();
replayGain = ReplayGain();
}
diff --git a/xbmc/music/Song.h b/xbmc/music/Song.h
index 3fc127a60f..737ba46eed 100644
--- a/xbmc/music/Song.h
+++ b/xbmc/music/Song.h
@@ -194,6 +194,7 @@ public:
int iChannels;
std::string strRecordLabel; // Record label from tag for album processing by CMusicInfoScanner::FileItemsToAlbums
std::string strAlbumType; // (Musicbrainz release type) album type from tag for album processing by CMusicInfoScanner::FileItemsToAlbums
+ std::string songVideoURL; // url to song video
ReplayGain replayGain;
private:
diff --git a/xbmc/music/tags/MusicInfoTag.cpp b/xbmc/music/tags/MusicInfoTag.cpp
index 62548bf5d5..50c7ae773b 100644
--- a/xbmc/music/tags/MusicInfoTag.cpp
+++ b/xbmc/music/tags/MusicInfoTag.cpp
@@ -323,6 +323,11 @@ const std::string& CMusicInfoTag::GetStationArt() const
return m_stationArt;
}
+const std::string& CMusicInfoTag::GetSongVideoURL() const
+{
+ return m_songVideoURL;
+}
+
void CMusicInfoTag::SetURL(const std::string& strURL)
{
m_strURL = strURL;
@@ -774,6 +779,11 @@ void CMusicInfoTag::SetStationArt(const std::string& strStationArt)
m_stationArt = strStationArt;
}
+void CMusicInfoTag::SetSongVideoURL(const std::string& songVideoURL)
+{
+ m_songVideoURL = songVideoURL;
+}
+
void CMusicInfoTag::SetArtist(const CArtist& artist)
{
SetArtist(artist.strArtist);
@@ -882,6 +892,7 @@ void CMusicInfoTag::SetSong(const CSong& song)
SetBitRate(song.iBitRate);
SetSampleRate(song.iSampleRate);
SetNoOfChannels(song.iChannels);
+ SetSongVideoURL(song.songVideoURL);
if (song.replayGain.Get(ReplayGain::TRACK).Valid())
m_replayGain.Set(ReplayGain::TRACK, song.replayGain.Get(ReplayGain::TRACK));
@@ -970,6 +981,7 @@ void CMusicInfoTag::Serialize(CVariant& value) const
value["bitrate"] = m_bitrate;
value["samplerate"] = m_samplerate;
value["channels"] = m_channels;
+ value["songvideourl"] = m_songVideoURL;
}
void CMusicInfoTag::ToSortable(SortItem& sortable, Field field) const
@@ -1071,6 +1083,7 @@ void CMusicInfoTag::Archive(CArchive& ar)
ar << m_samplerate;
ar << m_bitrate;
ar << m_channels;
+ ar << m_songVideoURL;
}
else
{
@@ -1138,6 +1151,7 @@ void CMusicInfoTag::Archive(CArchive& ar)
ar >> m_samplerate;
ar >> m_bitrate;
ar >> m_channels;
+ ar >> m_songVideoURL;
}
}
@@ -1193,6 +1207,7 @@ void CMusicInfoTag::Clear()
m_channels = 0;
m_stationName.clear();
m_stationArt.clear();
+ m_songVideoURL.clear();
}
void CMusicInfoTag::AppendArtist(const std::string &artist)
diff --git a/xbmc/music/tags/MusicInfoTag.h b/xbmc/music/tags/MusicInfoTag.h
index 3c1b994425..0b264a9301 100644
--- a/xbmc/music/tags/MusicInfoTag.h
+++ b/xbmc/music/tags/MusicInfoTag.h
@@ -85,6 +85,7 @@ public:
const std::string& GetAlbumReleaseStatus() const;
const std::string& GetStationName() const;
const std::string& GetStationArt() const;
+ const std::string& GetSongVideoURL() const;
const EmbeddedArtInfo &GetCoverArtInfo() const;
const ReplayGain& GetReplayGain() const;
CAlbum::ReleaseType GetAlbumReleaseType() const;
@@ -157,6 +158,7 @@ public:
void SetAlbumReleaseStatus(const std::string& strReleaseStatus);
void SetStationName(const std::string& strStationName); // name of online radio station
void SetStationArt(const std::string& strStationArt);
+ void SetSongVideoURL(const std::string& songVideoURL); // link to video of song
/*! \brief Append a unique artist to the artist list
Checks if we have this artist already added, and if not adds it to the songs artist list.
@@ -255,6 +257,7 @@ protected:
int m_bitrate;
std::string m_stationName;
std::string m_stationArt; // Used to fetch thumb URL for Shoutcasts
+ std::string m_songVideoURL; // link to a video for a song
EmbeddedArtInfo m_coverArt; ///< art information