1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "MusicInfoTagLoaderCDDA.h"
10
11 #include "MusicInfoTag.h"
12 #include "ServiceBroker.h"
13 #include "network/cddb.h"
14 #include "profiles/ProfileManager.h"
15 #include "settings/SettingsComponent.h"
16 #include "storage/MediaManager.h"
17 #include "utils/log.h"
18
19 using namespace MUSIC_INFO;
20
21 #ifdef HAS_DVD_DRIVE
22 using namespace MEDIA_DETECT;
23 using namespace CDDB;
24 #endif
25
26 //! @todo - remove after Ubuntu 16.04 (Xenial) is EOL
27 #if !defined(LIBCDIO_VERSION_NUM) || (LIBCDIO_VERSION_NUM <= 83)
28 #define CDTEXT_FIELD_TITLE CDTEXT_TITLE
29 #define CDTEXT_FIELD_PERFORMER CDTEXT_PERFORMER
30 #define CDTEXT_FIELD_GENRE CDTEXT_GENRE
31 #endif
32
33 CMusicInfoTagLoaderCDDA::CMusicInfoTagLoaderCDDA(void) = default;
34
35 CMusicInfoTagLoaderCDDA::~CMusicInfoTagLoaderCDDA() = default;
36
Load(const std::string & strFileName,CMusicInfoTag & tag,EmbeddedArt * art)37 bool CMusicInfoTagLoaderCDDA::Load(const std::string& strFileName, CMusicInfoTag& tag, EmbeddedArt *art)
38 {
39 #ifdef HAS_DVD_DRIVE
40 try
41 {
42 tag.SetURL(strFileName);
43 bool bResult = false;
44
45 // Get information for the inserted disc
46 CCdInfo* pCdInfo = CServiceBroker::GetMediaManager().GetCdInfo();
47 if (pCdInfo == NULL)
48 return bResult;
49
50 const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
51
52 // Prepare cddb
53 Xcddb cddb;
54 cddb.setCacheDir(profileManager->GetCDDBFolder());
55
56 int iTrack = atoi(strFileName.substr(13, strFileName.size() - 13 - 5).c_str());
57
58 // duration is always available
59 tag.SetDuration( ( pCdInfo->GetTrackInformation(iTrack).nMins * 60 )
60 + pCdInfo->GetTrackInformation(iTrack).nSecs );
61
62 // Only load cached cddb info in this tag loader, the internet database query is made in CCDDADirectory
63 if (pCdInfo->HasCDDBInfo() && cddb.isCDCached(pCdInfo))
64 {
65 // get cddb information
66 if (cddb.queryCDinfo(pCdInfo))
67 {
68 // Fill the fileitems music tag with cddb information, if available
69 const std::string& strTitle = cddb.getTrackTitle(iTrack);
70 if (!strTitle.empty())
71 {
72 // Tracknumber
73 tag.SetTrackNumber(iTrack);
74
75 // Title
76 tag.SetTitle(strTitle);
77
78 // Artist: Use track artist or disc artist
79 std::string strArtist = cddb.getTrackArtist(iTrack);
80 if (strArtist.empty())
81 cddb.getDiskArtist(strArtist);
82 tag.SetArtist(strArtist);
83
84 // Album
85 std::string strAlbum;
86 cddb.getDiskTitle( strAlbum );
87 tag.SetAlbum(strAlbum);
88
89 // Album Artist
90 std::string strAlbumArtist;
91 cddb.getDiskArtist(strAlbumArtist);
92 tag.SetAlbumArtist(strAlbumArtist);
93
94 // Year
95 tag.SetReleaseDate(cddb.getYear());
96
97 // Genre
98 tag.SetGenre( cddb.getGenre() );
99
100 tag.SetLoaded(true);
101 bResult = true;
102 }
103 }
104 }
105 else
106 {
107 // No cddb info, maybe we have CD-Text
108 trackinfo ti = pCdInfo->GetTrackInformation(iTrack);
109
110 // Fill the fileitems music tag with CD-Text information, if available
111 std::string strTitle = ti.cdtext[CDTEXT_FIELD_TITLE];
112 if (!strTitle.empty())
113 {
114 // Tracknumber
115 tag.SetTrackNumber(iTrack);
116
117 // Title
118 tag.SetTitle(strTitle);
119
120 // Get info for track zero, as we may have and need CD-Text Album info
121 xbmc_cdtext_t discCDText = pCdInfo->GetDiscCDTextInformation();
122
123 // Artist: Use track artist or disc artist
124 std::string strArtist = ti.cdtext[CDTEXT_FIELD_PERFORMER];
125 if (strArtist.empty())
126 strArtist = discCDText[CDTEXT_FIELD_PERFORMER];
127 tag.SetArtist(strArtist);
128
129 // Album
130 std::string strAlbum;
131 strAlbum = discCDText[CDTEXT_FIELD_TITLE];
132 tag.SetAlbum(strAlbum);
133
134 // Genre: use track or disc genre
135 std::string strGenre = ti.cdtext[CDTEXT_FIELD_GENRE];
136 if (strGenre.empty())
137 strGenre = discCDText[CDTEXT_FIELD_GENRE];
138 tag.SetGenre( strGenre );
139
140 tag.SetLoaded(true);
141 bResult = true;
142 }
143 }
144 return bResult;
145 }
146 catch (...)
147 {
148 CLog::Log(LOGERROR, "Tag loader CDDB: exception in file %s", strFileName.c_str());
149 }
150
151 #endif
152
153 tag.SetLoaded(false);
154
155 return false;
156 }
157