void CTagLoaderTagLib::SetArtist(CMusicInfoTag &tag, const std::vector<std::string> &values) { if (values.size() == 1) tag.SetArtist(values[0]); else tag.SetArtist(values); }
void CTagLoaderTagLib::SetArtist(CMusicInfoTag &tag, const std::vector<std::string> &values) { if (values.size() == 1) tag.SetArtist(values[0]); else // Fill both artist vector and artist desc from tag value. // Note desc may not be empty as it could have been set by previous parsing of ID3v2 before APE tag.SetArtist(values, true); }
bool CMusicInfoTagLoaderNSF::Load(const CStdString& strFileName, CMusicInfoTag& tag) { tag.SetLoaded(false); if (!m_dll.Load()) return false; m_nsf = m_dll.LoadNSF(strFileName.c_str()); if (!m_nsf) { CLog::Log(LOGERROR,"MusicInfoTagLoaderNSF: failed to open NSF %s",strFileName.c_str()); return false; } tag.SetURL(strFileName); tag.SetLoaded(false); char* szTitle = (char*)m_dll.GetTitle(m_nsf); // no alloc if( szTitle && strcmp(szTitle,"<?>") ) { tag.SetTitle(szTitle); tag.SetLoaded(true); } char* szArtist = (char*)m_dll.GetArtist(m_nsf); // no alloc if( szArtist && strcmp(szArtist,"<?>") && tag.Loaded() ) tag.SetArtist(szArtist); m_dll.FreeNSF(m_nsf); m_nsf = 0; return tag.Loaded(); }
bool CMusicInfoTagLoaderSPC::Load(const CStdString& strFileName, CMusicInfoTag& tag) { tag.SetLoaded(false); CFile file; if (!file.Open(strFileName)) { CLog::Log(LOGERROR,"MusicInfoTagLoaderSPC: failed to open SPC %s",strFileName.c_str()); return false; } tag.SetURL(strFileName); tag.SetLoaded(false); SPC_ID666* spc = SPC_get_id666FP(file); if (!spc) return false; if( strcmp(spc->songname,"") ) { tag.SetTitle(spc->songname); tag.SetLoaded(true); } if( strcmp(spc->author,"") && tag.Loaded() ) tag.SetArtist(spc->author); if (spc->playtime) tag.SetDuration(spc->playtime); else tag.SetDuration(4*60); // 4 mins free(spc); return tag.Loaded(); }
bool CTagLoaderTagLib::ParseASF(ASF::Tag *asf, EmbeddedArt *art, CMusicInfoTag& tag) { if (!asf) return false; tag.SetTitle(asf->title().to8Bit(true)); const ASF::AttributeListMap& attributeListMap = asf->attributeListMap(); for (ASF::AttributeListMap::ConstIterator it = attributeListMap.begin(); it != attributeListMap.end(); ++it) { if (it->first == "Author") SetArtist(tag, GetASFStringList(it->second)); else if (it->first == "WM/AlbumArtist") SetAlbumArtist(tag, GetASFStringList(it->second)); else if (it->first == "WM/AlbumTitle") tag.SetAlbum(it->second.front().toString().to8Bit(true)); else if (it->first == "WM/TrackNumber" || it->first == "WM/Track") { if (it->second.front().type() == ASF::Attribute::DWordType) tag.SetTrackNumber(it->second.front().toUInt()); else tag.SetTrackNumber(atoi(it->second.front().toString().toCString(true))); } else if (it->first == "WM/PartOfSet") tag.SetPartOfSet(atoi(it->second.front().toString().toCString(true))); else if (it->first == "WM/Genre") SetGenre(tag, GetASFStringList(it->second)); else if (it->first == "WM/AlbumArtistSortOrder") {} // Known unsupported, supress warnings else if (it->first == "WM/ArtistSortOrder") {} // Known unsupported, supress warnings else if (it->first == "WM/Script") {} // Known unsupported, supress warnings else if (it->first == "WM/Year") tag.SetYear(atoi(it->second.front().toString().toCString(true))); else if (it->first == "MusicBrainz/Artist Id") tag.SetMusicBrainzArtistID(GetASFStringList(it->second)); else if (it->first == "MusicBrainz/Album Id") tag.SetMusicBrainzAlbumID(it->second.front().toString().to8Bit(true)); else if (it->first == "MusicBrainz/Album Artist") SetAlbumArtist(tag, GetASFStringList(it->second)); else if (it->first == "MusicBrainz/Album Artist Id") tag.SetMusicBrainzAlbumArtistID(GetASFStringList(it->second)); else if (it->first == "MusicBrainz/Track Id") tag.SetMusicBrainzTrackID(it->second.front().toString().to8Bit(true)); else if (it->first == "MusicBrainz/Album Status") {} else if (it->first == "MusicBrainz/Album Type") {} else if (it->first == "MusicIP/PUID") {} else if (it->first == "replaygain_track_gain") tag.SetReplayGainTrackGain((int)(atof(it->second.front().toString().toCString(true)) * 100 + 0.5)); else if (it->first == "replaygain_album_gain") tag.SetReplayGainAlbumGain((int)(atof(it->second.front().toString().toCString(true)) * 100 + 0.5)); else if (it->first == "replaygain_track_peak") tag.SetReplayGainTrackPeak((float)atof(it->second.front().toString().toCString(true))); else if (it->first == "replaygain_album_peak") tag.SetReplayGainAlbumPeak((float)atof(it->second.front().toString().toCString(true))); else if (it->first == "WM/Picture") { // picture ASF::Picture pic = it->second.front().toPicture(); tag.SetCoverArtInfo(pic.picture().size(), pic.mimeType().toCString()); if (art) art->set((const uint8_t *)pic.picture().data(), pic.picture().size(), pic.mimeType().toCString()); } else if (g_advancedSettings.m_logLevel == LOG_LEVEL_MAX) CLog::Log(LOGDEBUG, "unrecognized ASF tag name: %s", it->first.toCString(true)); } // artist may be specified in the ContentDescription block rather than using the 'Author' attribute. if (tag.GetArtist().empty()) tag.SetArtist(asf->artist().toCString(true)); tag.SetLoaded(true); return true; }
bool CTagLoaderTagLib::ParseTag(ID3v1::Tag *id3v1, EmbeddedArt *art, CMusicInfoTag& tag) { if (!id3v1) return false; tag.SetTitle(id3v1->title().to8Bit(true)); tag.SetArtist(id3v1->artist().to8Bit(true)); tag.SetAlbum(id3v1->album().to8Bit(true)); tag.SetComment(id3v1->comment().to8Bit(true)); tag.SetGenre(id3v1->genre().to8Bit(true)); tag.SetYear(id3v1->year()); tag.SetTrackNumber(id3v1->track()); return true; }
bool CMusicInfoTagLoaderMod::Load(const CStdString& strFileName, CMusicInfoTag& tag, EmbeddedArt *art) { tag.SetURL(strFileName); // first, does the module have a .mdz? CStdString strMDZ(URIUtils::ReplaceExtension(strFileName,".mdz")); if (CFile::Exists(strMDZ)) { if (!getFile(strMDZ,strMDZ)) { tag.SetLoaded(false); return( false ); } ifstream inMDZ(CSpecialProtocol::TranslatePath(strMDZ.c_str())); char temp[8192]; char temp2[8192]; while (!inMDZ.eof()) { inMDZ.getline(temp,8191); if (strstr(temp,"COMPOSER")) { strcpy(temp2,temp+strlen("COMPOSER ")); tag.SetArtist(temp2); } else if (strstr(temp,"TITLE")) { strcpy(temp2,temp+strlen("TITLE ")); tag.SetTitle(temp2); tag.SetLoaded(true); } else if (strstr(temp,"PLAYTIME")) { char* temp3 = strtok(temp+strlen("PLAYTIME "),":"); int iSecs = atoi(temp3)*60; temp3 = strtok(NULL,":"); iSecs += atoi(temp3); tag.SetDuration(iSecs); } else if (strstr(temp,"STYLE")) { strcpy(temp2,temp+strlen("STYLE ")); tag.SetGenre(temp2); } } return( tag.Loaded() ); } else { // TODO: no, then try to atleast fetch the title } return tag.Loaded(); }
bool CEncoderLame::Close() { // may return one more mp3 frames int iBytes = m_dll.lame_encode_flush(m_pGlobalFlags, m_buffer, sizeof(m_buffer)); if (iBytes < 0) { CLog::Log(LOGERROR, "Internal Lame error: %i", iBytes); return false; } WriteStream(m_buffer, iBytes); FlushStream(); FileClose(); // open again, but now the old way, lame only accepts FILE pointers FILE* file = fopen_utf8(m_strFile.c_str(), "rb+"); if (!file) { CLog::Log(LOGERROR, "Error: Cannot open file for writing tags: %s", m_strFile.c_str()); return false; } m_dll.lame_mp3_tags_fid(m_pGlobalFlags, file); /* add VBR tags to mp3 file */ fclose(file); m_dll.lame_close(m_pGlobalFlags); // unload the lame dll m_dll.Unload(); // Store a id3 tag in the ripped file CID3Tag id3tag; CMusicInfoTag tag; tag.SetAlbum(m_strAlbum); tag.SetAlbumArtist(m_strAlbumArtist); tag.SetArtist(m_strArtist); tag.SetGenre(m_strGenre); tag.SetTitle(m_strTitle); tag.SetTrackNumber(atoi(m_strTrack.c_str())); SYSTEMTIME time; time.wYear=atoi(m_strYear.c_str()); tag.SetReleaseDate(time); id3tag.SetMusicInfoTag(tag); id3tag.Write(m_strFile); return true; }
bool CMusicInfoTagLoaderApe::Load(const CStdString& strFileName, CMusicInfoTag& tag, EmbeddedArt *art) { try { // retrieve the APE Tag info from strFileName // and put it in tag tag.SetURL(strFileName); DVDPlayerCodec codec; if (codec.Init(strFileName, 4096)) { tag.SetDuration((int)(codec.m_TotalTime/1000)); codec.DeInit(); } CAPEv2Tag myTag; if (myTag.ReadTag((char*)strFileName.c_str())) // true to check ID3 tag as well { tag.SetTitle(myTag.GetTitle()); tag.SetAlbum(myTag.GetAlbum()); tag.SetArtist(myTag.GetArtist()); tag.SetAlbumArtist(myTag.GetAlbumArtist()); tag.SetGenre(myTag.GetGenre()); tag.SetTrackNumber(myTag.GetTrackNum()); tag.SetPartOfSet(myTag.GetDiscNum()); tag.SetComment(myTag.GetComment()); tag.SetLyrics(myTag.GetLyrics()); tag.SetMusicBrainzAlbumArtistID(myTag.GetMusicBrainzAlbumArtistID()); tag.SetMusicBrainzAlbumID(myTag.GetMusicBrainzAlbumID()); tag.SetMusicBrainzArtistID(myTag.GetMusicBrainzArtistID()); tag.SetMusicBrainzTrackID(myTag.GetMusicBrainzTrackID()); tag.SetMusicBrainzTRMID(myTag.GetMusicBrainzTRMID()); SYSTEMTIME dateTime; ZeroMemory(&dateTime, sizeof(SYSTEMTIME)); dateTime.wYear = atoi(myTag.GetYear()); tag.SetRating(myTag.GetRating()); tag.SetReleaseDate(dateTime); tag.SetLoaded(); return true; } } catch (...) { CLog::Log(LOGERROR, "Tag loader ape: exception in file %s", strFileName.c_str()); } tag.SetLoaded(false); return false; }
bool CMusicInfoTagLoaderASAP::Load(const CStdString &strFile, CMusicInfoTag &tag, EmbeddedArt *art) { tag.SetLoaded(false); if (!m_dll.Load()) return false; CStdString strFileToLoad = strFile; int song = -1; CStdString strExtension; URIUtils::GetExtension(strFile, strExtension); strExtension.MakeLower(); if (strExtension == ".asapstream") { CStdString strFileName = URIUtils::GetFileName(strFile); int iStart = strFileName.ReverseFind('-') + 1; song = atoi(strFileName.substr(iStart, strFileName.size() - iStart - 11).c_str()) - 1; CStdString strPath = strFile; URIUtils::GetDirectory(strPath, strFileToLoad); URIUtils::RemoveSlashAtEnd(strFileToLoad); } ASAP_SongInfo songInfo; if (!m_dll.asapGetInfo(strFileToLoad.c_str(), song, &songInfo)) return false; tag.SetURL(strFileToLoad); if (songInfo.name[0] != '\0') tag.SetTitle(songInfo.name); if (songInfo.author[0] != '\0') tag.SetArtist(songInfo.author); if (song >= 0) tag.SetTrackNumber(song + 1); if (songInfo.duration >= 0) tag.SetDuration(songInfo.duration / 1000); if (songInfo.year > 0) { SYSTEMTIME dateTime = { (WORD)songInfo.year, (WORD)songInfo.month, 0, (WORD)songInfo.day, 0, 0, 0, 0 }; tag.SetReleaseDate(dateTime); } tag.SetLoaded(true); return true; }
int CPVRChannels::GetChannels(CFileItemList* results, int iGroupID /* = -1 */, bool bHidden /* = false */) { int iAmount = 0; SortByChannelNumber(); for (unsigned int ptr = 0; ptr < size(); ptr++) { CPVRChannel *channel = at(ptr); if (channel->IsHidden() != bHidden) continue; if (iGroupID != -1 && channel->GroupID() != iGroupID) continue; CFileItemPtr channelFile(new CFileItem(*channel)); if (channel->IsRadio()) { CMusicInfoTag* musictag = channelFile->GetMusicInfoTag(); if (musictag) { const CPVREpgInfoTag *epgNow = channel->GetEPGNow(); musictag->SetURL(channel->Path()); musictag->SetTitle(epgNow->Title()); musictag->SetArtist(channel->ChannelName()); musictag->SetAlbumArtist(channel->ChannelName()); musictag->SetGenre(epgNow->Genre()); musictag->SetDuration(epgNow->GetDuration()); musictag->SetLoaded(true); musictag->SetComment(""); musictag->SetLyrics(""); } } results->Add(channelFile); iAmount++; } return iAmount; }
// There is no reliable tag information in MIDI files. There is a 'title' field (@T), but it looks // like everyone puts there song title, artist name, the name of the person who created the lyrics and // greetings to their friends and family. Therefore we return the song title as file name, and the // song artist as parent directory. // A good intention of creating a pattern-based artist/song recognition engine failed greatly. Simple formats // like %A-%T fail greatly with artists like A-HA and songs like "Ob-la-Di ob-la-Da.mid". So if anyone has // a good idea which would include cases from above, I'd be happy to hear about it. bool CMusicInfoTagLoaderMidi::Load(const CStdString & strFileName, CMusicInfoTag & tag, EmbeddedArt *art) { tag.SetURL(strFileName); CStdString path, title; URIUtils::Split( strFileName, path, title); URIUtils::RemoveExtension( title ); tag.SetTitle( title ); URIUtils::RemoveSlashAtEnd(path ); if ( !path.IsEmpty() ) { CStdString artist = URIUtils::GetFileName( path ); if ( !artist.IsEmpty() ) tag.SetArtist( artist ); } tag.SetLoaded(true); return true; }
bool CMusicInfoTagLoaderGYM::Load(const CStdString& strFileName, CMusicInfoTag& tag) { tag.SetLoaded(false); if (!m_dll.Load()) return false; m_dll.Init(); m_gym = m_dll.LoadGYM(strFileName.c_str()); if (!m_gym) { CLog::Log(LOGERROR,"MusicInfoTagLoaderGYM: failed to open GYM %s",strFileName.c_str()); return false; } tag.SetURL(strFileName); tag.SetLoaded(false); char* szTitle = (char*)m_dll.GetTitle(m_gym); // no alloc if (szTitle) if( strcmp(szTitle,"") ) { tag.SetTitle(szTitle); tag.SetLoaded(true); } char* szArtist = (char*)m_dll.GetArtist(m_gym); // no alloc if (szArtist) if( strcmp(szArtist,"") && tag.Loaded() ) tag.SetArtist(szArtist); m_dll.FreeGYM(m_gym); m_gym = 0; return tag.Loaded(); }
bool CMusicInfoTagLoaderAdplug::Load(const CStdString& strFileName, CMusicInfoTag& tag) { tag.SetLoaded(false); if (!m_dll.Load()) return false; m_adl = m_dll.LoadADL(strFileName.c_str()); if (!m_adl) { CLog::Log(LOGERROR,"MusicInfoTagLoaderAdplug: failed to open %s",strFileName.c_str()); return false; } tag.SetURL(strFileName); tag.SetLoaded(false); const char* szTitle = m_dll.GetTitle(m_adl); // no alloc if (szTitle) if( strcmp(szTitle,"") ) { tag.SetTitle(szTitle); tag.SetLoaded(true); } const char* szArtist = m_dll.GetArtist(m_adl); // no alloc if( strcmp(szArtist,"") && tag.Loaded() ) tag.SetArtist(szArtist); tag.SetDuration(m_dll.GetLength(m_adl)/1000); m_dll.FreeADL(m_adl); m_adl = 0; return tag.Loaded(); }
bool CMusicInfoTagLoaderApe::Load(const CStdString& strFileName, CMusicInfoTag& tag) { try { // retrieve the APE Tag info from strFileName // and put it in tag tag.SetURL(strFileName); CAPEv2Tag myTag; if (myTag.ReadTag((char*)strFileName.c_str())) // true to check ID3 tag as well { tag.SetTitle(myTag.GetTitle()); tag.SetAlbum(myTag.GetAlbum()); tag.SetArtist(myTag.GetArtist()); tag.SetAlbumArtist(myTag.GetAlbumArtist()); tag.SetGenre(myTag.GetGenre()); tag.SetTrackNumber(myTag.GetTrackNum()); tag.SetPartOfSet(myTag.GetDiscNum()); tag.SetComment(myTag.GetComment()); tag.SetLyrics(myTag.GetLyrics()); SYSTEMTIME dateTime; ZeroMemory(&dateTime, sizeof(SYSTEMTIME)); dateTime.wYear = atoi(myTag.GetYear()); tag.SetRating(myTag.GetRating()); tag.SetReleaseDate(dateTime); tag.SetLoaded(); return true; } } catch (...) { CLog::Log(LOGERROR, "Tag loader ape: exception in file %s", strFileName.c_str()); } tag.SetLoaded(false); return false; }
bool CPVRManager::UpdateItem(CFileItem& item) { /* Don't update if a recording is played */ if (item.IsPVRRecording()) return false; if (!item.IsPVRChannel()) { CLog::Log(LOGERROR, "CPVRManager - %s - no channel tag provided", __FUNCTION__); return false; } CSingleLock lock(m_critSection); if (!m_currentFile || *m_currentFile->GetPVRChannelInfoTag() == *item.GetPVRChannelInfoTag()) return false; g_application.CurrentFileItem() = *m_currentFile; g_infoManager.SetCurrentItem(*m_currentFile); CPVRChannel* channelTag = item.GetPVRChannelInfoTag(); CEpgInfoTag epgTagNow; bool bHasTagNow = channelTag->GetEPGNow(epgTagNow); if (channelTag->IsRadio()) { CMusicInfoTag* musictag = item.GetMusicInfoTag(); if (musictag) { musictag->SetTitle(bHasTagNow ? epgTagNow.Title() : g_localizeStrings.Get(19055)); if (bHasTagNow) musictag->SetGenre(epgTagNow.Genre()); musictag->SetDuration(bHasTagNow ? epgTagNow.GetDuration() : 3600); musictag->SetURL(channelTag->Path()); musictag->SetArtist(channelTag->ChannelName()); musictag->SetAlbumArtist(channelTag->ChannelName()); musictag->SetLoaded(true); musictag->SetComment(StringUtils::EmptyString); musictag->SetLyrics(StringUtils::EmptyString); } } else { CVideoInfoTag *videotag = item.GetVideoInfoTag(); if (videotag) { videotag->m_strTitle = bHasTagNow ? epgTagNow.Title() : g_localizeStrings.Get(19055); if (bHasTagNow) videotag->m_genre = epgTagNow.Genre(); videotag->m_strPath = channelTag->Path(); videotag->m_strFileNameAndPath = channelTag->Path(); videotag->m_strPlot = bHasTagNow ? epgTagNow.Plot() : StringUtils::EmptyString; videotag->m_strPlotOutline = bHasTagNow ? epgTagNow.PlotOutline() : StringUtils::EmptyString; videotag->m_iEpisode = bHasTagNow ? epgTagNow.EpisodeNum() : 0; } } CPVRChannel* tagPrev = item.GetPVRChannelInfoTag(); if (tagPrev && tagPrev->ChannelNumber() != m_LastChannel) { m_LastChannel = tagPrev->ChannelNumber(); m_LastChannelChanged = XbmcThreads::SystemClockMillis(); } if (XbmcThreads::SystemClockMillis() - m_LastChannelChanged >= (unsigned int) g_guiSettings.GetInt("pvrplayback.channelentrytimeout") && m_LastChannel != m_PreviousChannel[m_PreviousChannelIndex]) m_PreviousChannel[m_PreviousChannelIndex ^= 1] = m_LastChannel; else m_LastChannelChanged = XbmcThreads::SystemClockMillis(); return false; }
bool CTagLoaderTagLib::ParseTag(ASF::Tag *asf, EmbeddedArt *art, CMusicInfoTag& tag) { if (!asf) return false; ReplayGain replayGainInfo; tag.SetTitle(asf->title().to8Bit(true)); const ASF::AttributeListMap& attributeListMap = asf->attributeListMap(); for (ASF::AttributeListMap::ConstIterator it = attributeListMap.begin(); it != attributeListMap.end(); ++it) { if (it->first == "Author") SetArtist(tag, GetASFStringList(it->second)); else if (it->first == "WM/AlbumArtist") SetAlbumArtist(tag, GetASFStringList(it->second)); else if (it->first == "WM/AlbumTitle") tag.SetAlbum(it->second.front().toString().to8Bit(true)); else if (it->first == "WM/TrackNumber" || it->first == "WM/Track") { if (it->second.front().type() == ASF::Attribute::DWordType) tag.SetTrackNumber(it->second.front().toUInt()); else tag.SetTrackNumber(atoi(it->second.front().toString().toCString(true))); } else if (it->first == "WM/PartOfSet") tag.SetDiscNumber(atoi(it->second.front().toString().toCString(true))); else if (it->first == "WM/Genre") SetGenre(tag, GetASFStringList(it->second)); else if (it->first == "WM/Mood") tag.SetMood(it->second.front().toString().to8Bit(true)); else if (it->first == "WM/Composer") AddArtistRole(tag, "Composer", GetASFStringList(it->second)); else if (it->first == "WM/Conductor") AddArtistRole(tag, "Conductor", GetASFStringList(it->second)); //No ASF/WMA tag from Taglib for "ensemble" else if (it->first == "WM/Writer") AddArtistRole(tag, "Lyricist", GetASFStringList(it->second)); else if (it->first == "WM/ModifiedBy") AddArtistRole(tag, "Remixer", GetASFStringList(it->second)); else if (it->first == "WM/Engineer") AddArtistRole(tag, "Engineer", GetASFStringList(it->second)); else if (it->first == "WM/Producer") AddArtistRole(tag, "Producer", GetASFStringList(it->second)); else if (it->first == "WM/DJMixer") AddArtistRole(tag, "DJMixer", GetASFStringList(it->second)); else if (it->first == "WM/Mixer") AddArtistRole(tag, "mixer", GetASFStringList(it->second)); else if (it->first == "WM/Publisher") {} // Known unsupported, supress warnings else if (it->first == "WM/AlbumArtistSortOrder") {} // Known unsupported, supress warnings else if (it->first == "WM/ArtistSortOrder") {} // Known unsupported, supress warnings else if (it->first == "WM/Script") {} // Known unsupported, supress warnings else if (it->first == "WM/Year") tag.SetYear(atoi(it->second.front().toString().toCString(true))); else if (it->first == "MusicBrainz/Artist Id") tag.SetMusicBrainzArtistID(SplitMBID(GetASFStringList(it->second))); else if (it->first == "MusicBrainz/Album Id") tag.SetMusicBrainzAlbumID(it->second.front().toString().to8Bit(true)); else if (it->first == "MusicBrainz/Album Artist") SetAlbumArtist(tag, GetASFStringList(it->second)); else if (it->first == "MusicBrainz/Album Artist Id") tag.SetMusicBrainzAlbumArtistID(SplitMBID(GetASFStringList(it->second))); else if (it->first == "MusicBrainz/Track Id") tag.SetMusicBrainzTrackID(it->second.front().toString().to8Bit(true)); else if (it->first == "MusicBrainz/Album Status") {} else if (it->first == "MusicBrainz/Album Type") {} else if (it->first == "MusicIP/PUID") {} else if (it->first == "replaygain_track_gain") replayGainInfo.ParseGain(ReplayGain::TRACK, it->second.front().toString().toCString(true)); else if (it->first == "replaygain_album_gain") replayGainInfo.ParseGain(ReplayGain::ALBUM, it->second.front().toString().toCString(true)); else if (it->first == "replaygain_track_peak") replayGainInfo.ParsePeak(ReplayGain::TRACK, it->second.front().toString().toCString(true)); else if (it->first == "replaygain_album_peak") replayGainInfo.ParsePeak(ReplayGain::ALBUM, it->second.front().toString().toCString(true)); else if (it->first == "WM/Picture") { // picture ASF::Picture pic = it->second.front().toPicture(); tag.SetCoverArtInfo(pic.picture().size(), pic.mimeType().toCString()); if (art) art->set(reinterpret_cast<const uint8_t *>(pic.picture().data()), pic.picture().size(), pic.mimeType().toCString()); } else if (g_advancedSettings.m_logLevel == LOG_LEVEL_MAX) CLog::Log(LOGDEBUG, "unrecognized ASF tag name: %s", it->first.toCString(true)); } // artist may be specified in the ContentDescription block rather than using the 'Author' attribute. if (tag.GetArtist().empty()) tag.SetArtist(asf->artist().toCString(true)); if (asf->comment() != String::null) tag.SetComment(asf->comment().toCString(true)); tag.SetReplayGain(replayGainInfo); tag.SetLoaded(true); return true; }
void CLastFMDirectory::AddListEntry(const char *name, const char *artist, const char *count, const char *date, const char *icon, CStdString strPath, CFileItemList &items) { CStdString strName; CStdString strCount; CFileItemPtr pItem(new CFileItem); CMusicInfoTag* musicinfotag = pItem->GetMusicInfoTag(); musicinfotag->SetTitle(name); if (artist) { strName.Format("%s - %s", artist, name); musicinfotag->SetArtist(artist); } else { strName = name; } if (count) { pItem->SetLabel2(count); pItem->m_dwSize = _atoi64(count) * 100000000; const char *dot; if ((dot = (const char *)strstr(count, "."))) pItem->m_dwSize += _atoi64(dot + 1); } pItem->SetLabel(strName); pItem->m_strPath = strPath; pItem->m_bIsFolder = true; pItem->SetLabelPreformated(true); if (date) { LONGLONG ll = Int32x32To64(atoi(date), 10000000) + 116444736000000000LL; FILETIME ft; ft.dwLowDateTime = (DWORD)(ll & 0xFFFFFFFF); ft.dwHighDateTime = (DWORD)(ll >> 32); pItem->m_dateTime=ft; } pItem->SetCanQueue(false); //the extra info is used in the mediawindows to determine which items are needed in the contextmenu if (m_objname.Equals(g_guiSettings.GetString("lastfm.username"))) { if (m_objrequest.Equals("recentbannedtracks")) { pItem->SetExtraInfo("lastfmbanned"); } else if (m_objrequest.Equals("recentlovedtracks")) { pItem->SetExtraInfo("lastfmloved"); } } if (pItem->GetExtraInfo().IsEmpty() && strPath.Find("lastfm://xbmc") >= 0) { pItem->SetExtraInfo("lastfmitem"); } // icons? would probably take too long to retrieve them all items.Add(pItem); }
void CMusicInfoTagLoaderMP4::ParseTag( unsigned int metaKey, const char* pMetaData, int metaSize, CMusicInfoTag& tag) { switch ( metaKey ) { case g_TitleAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; // we use utf8 internally tag.SetLoaded( true ); tag.SetTitle( dataWorkspace.get() ); break; } case g_ArtistAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetArtist( dataWorkspace.get() ); break; } case g_AlbumAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetAlbum( dataWorkspace.get() ); break; } case g_AlbumArtistAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetAlbumArtist( dataWorkspace.get() ); break; } case g_DayAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; SYSTEMTIME dateTime; dateTime.wYear = atoi( dataWorkspace.get() ); tag.SetReleaseDate( dateTime ); break; } case g_GenreAtomName: { // When a genre number is specified, we need to translate to a string for display.. // Note that AAC/iTunes genre numbers are the same as ID3 numbers, but are offset by 1. const char* pGenre = ID3_V1GENRE2DESCRIPTION( (unsigned char)pMetaData[ 1 ] - 1 ); if ( pGenre ) { tag.SetGenre( pGenre ); } break; } case g_CompilationAtomName: { if (metaSize == 1) m_isCompilation = *pMetaData == 1; break; } case g_CommentAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetComment( dataWorkspace.get() ); break; } case g_LyricsAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetLyrics( dataWorkspace.get() ); break; } case g_CustomGenreAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetGenre( dataWorkspace.get() ); break; } case g_TrackNumberAtomName: { tag.SetTrackNumber( pMetaData[ 3 ] ); break; } case g_DiscNumberAtomName: { tag.SetPartOfSet( pMetaData[ 3 ] ); break; } case g_CoverArtAtomName: { // This cover-art handling is pretty much what was in the old MP4 tag processing code.. // note that according to http://atomicparsley.sourceforge.net/mpeg-4files.html the type // of image (PNG=14 or JPG=13) is contained in pMetadata[-5] but we currently don't use this. m_thumbSize = metaSize; delete[] m_thumbData; m_thumbData = new BYTE[m_thumbSize]; if (m_thumbData) memcpy(m_thumbData, pMetaData, metaSize); break; } default: break; } }
bool CPVRManager::UpdateItem(CFileItem& item) { /* Don't update if a recording is played */ if (item.IsPVRRecording()) return false; if (!item.IsPVRChannel()) { CLog::Log(LOGERROR, "CPVRManager - %s - no channel tag provided", __FUNCTION__); return false; } CSingleLock lock(m_critSection); if (!m_currentFile || *m_currentFile->GetPVRChannelInfoTag() == *item.GetPVRChannelInfoTag()) return false; g_application.CurrentFileItem() = *m_currentFile; g_infoManager.SetCurrentItem(*m_currentFile); CPVRChannel* channelTag = item.GetPVRChannelInfoTag(); CEpgInfoTag epgTagNow; bool bHasTagNow = channelTag->GetEPGNow(epgTagNow); if (channelTag->IsRadio()) { CMusicInfoTag* musictag = item.GetMusicInfoTag(); if (musictag) { musictag->SetTitle(bHasTagNow ? epgTagNow.Title() : g_guiSettings.GetBool("epg.hidenoinfoavailable") ? StringUtils::EmptyString : g_localizeStrings.Get(19055)); // no information available if (bHasTagNow) musictag->SetGenre(epgTagNow.Genre()); musictag->SetDuration(bHasTagNow ? epgTagNow.GetDuration() : 3600); musictag->SetURL(channelTag->Path()); musictag->SetArtist(channelTag->ChannelName()); musictag->SetAlbumArtist(channelTag->ChannelName()); musictag->SetLoaded(true); musictag->SetComment(StringUtils::EmptyString); musictag->SetLyrics(StringUtils::EmptyString); } } else { CVideoInfoTag *videotag = item.GetVideoInfoTag(); if (videotag) { videotag->m_strTitle = bHasTagNow ? epgTagNow.Title() : g_guiSettings.GetBool("epg.hidenoinfoavailable") ? StringUtils::EmptyString : g_localizeStrings.Get(19055); // no information available if (bHasTagNow) videotag->m_genre = epgTagNow.Genre(); videotag->m_strPath = channelTag->Path(); videotag->m_strFileNameAndPath = channelTag->Path(); videotag->m_strPlot = bHasTagNow ? epgTagNow.Plot() : StringUtils::EmptyString; videotag->m_strPlotOutline = bHasTagNow ? epgTagNow.PlotOutline() : StringUtils::EmptyString; videotag->m_iEpisode = bHasTagNow ? epgTagNow.EpisodeNum() : 0; } } return false; }
bool CMusicInfoTagLoaderCDDA::Load(const std::string& strFileName, CMusicInfoTag& tag, EmbeddedArt *art) { #ifdef HAS_DVD_DRIVE try { tag.SetURL(strFileName); bool bResult = false; // Get information for the inserted disc CCdInfo* pCdInfo = g_mediaManager.GetCdInfo(); if (pCdInfo == NULL) return bResult; // Prepare cddb Xcddb cddb; cddb.setCacheDir(CProfilesManager::GetInstance().GetCDDBFolder()); int iTrack = atoi(strFileName.substr(13, strFileName.size() - 13 - 5).c_str()); // duration is always available tag.SetDuration( ( pCdInfo->GetTrackInformation(iTrack).nMins * 60 ) + pCdInfo->GetTrackInformation(iTrack).nSecs ); // Only load cached cddb info in this tag loader, the internet database query is made in CCDDADirectory if (pCdInfo->HasCDDBInfo() && cddb.isCDCached(pCdInfo)) { // get cddb information if (cddb.queryCDinfo(pCdInfo)) { // Fill the fileitems music tag with cddb information, if available std::string strTitle = cddb.getTrackTitle(iTrack); if (!strTitle.empty()) { // Tracknumber tag.SetTrackNumber(iTrack); // Title tag.SetTitle(strTitle); // Artist: Use track artist or disc artist std::string strArtist = cddb.getTrackArtist(iTrack); if (strArtist.empty()) cddb.getDiskArtist(strArtist); tag.SetArtist(strArtist); // Album std::string strAlbum; cddb.getDiskTitle( strAlbum ); tag.SetAlbum(strAlbum); // Album Artist std::string strAlbumArtist; cddb.getDiskArtist(strAlbumArtist); tag.SetAlbumArtist(strAlbumArtist); // Year SYSTEMTIME dateTime; dateTime.wYear = atoi(cddb.getYear().c_str()); tag.SetReleaseDate( dateTime ); // Genre tag.SetGenre( cddb.getGenre() ); tag.SetLoaded(true); bResult = true; } } } else { // No cddb info, maybe we have CD-Text trackinfo ti = pCdInfo->GetTrackInformation(iTrack); // Fill the fileitems music tag with CD-Text information, if available std::string strTitle = ti.cdtext[CDTEXT_TITLE]; if (!strTitle.empty()) { // Tracknumber tag.SetTrackNumber(iTrack); // Title tag.SetTitle(strTitle); // Get info for track zero, as we may have and need CD-Text Album info xbmc_cdtext_t discCDText = pCdInfo->GetDiscCDTextInformation(); // Artist: Use track artist or disc artist std::string strArtist = ti.cdtext[CDTEXT_PERFORMER]; if (strArtist.empty()) strArtist = discCDText[CDTEXT_PERFORMER]; tag.SetArtist(strArtist); // Album std::string strAlbum; strAlbum = discCDText[CDTEXT_TITLE]; tag.SetAlbum(strAlbum); // Genre: use track or disc genre std::string strGenre = ti.cdtext[CDTEXT_GENRE]; if (strGenre.empty()) strGenre = discCDText[CDTEXT_GENRE]; tag.SetGenre( strGenre ); tag.SetLoaded(true); bResult = true; } } return bResult; } catch (...) { CLog::Log(LOGERROR, "Tag loader CDDB: exception in file %s", strFileName.c_str()); } #endif tag.SetLoaded(false); return false; }
void CShoutcastRipFile::GetMusicInfoTag(CMusicInfoTag& tag) { if ( m_recState.bFilenameSet && m_recState.bStreamSet ) { tag.Clear(); //now distinguish between if ( m_recState.bHasMetaData ) { //The filename of RM will be something like "Oasis - Champagne Supernova", thus //So, we will make a file i.e "f:music\Record\Limbik Frequencies\Oasis - Champagne Supernova.mp3" //get the artist and trackname char szArtist[1124]; char szTrackName[1124]; char szTokens[1024]; char* cursor; bool tokenUsed = false; bool foundArtist = false; bool foundTrackName = false; strcpy( szTokens, m_szFileName ); cursor = strtok(szTokens, "-"); if (!cursor) cursor = strtok(szTokens, ","); while (cursor != NULL) { tokenUsed = false; //we will look for two strings, //sometimes there's a track number, wich we will throw away if ( !foundArtist ) { if ( atoi( cursor ) == 0 ) { //its a string strcpy(szArtist, cursor ); foundArtist = true; tokenUsed = true; } } if ( !foundTrackName && !tokenUsed ) { if ( atoi( cursor ) == 0 ) { //its a string strcpy(szTrackName, cursor ); foundTrackName = true; tokenUsed = true; } } cursor = strtok (NULL, "-"); //if (!cursor) cursor=strtok(NULL,","); } if ( foundTrackName ) //lets hope we found a track name, else it will be unknown tag.SetTitle(szTrackName); else tag.SetTitle(m_szStreamName); if ( foundArtist ) //lets hope we found an artist, else it will be unknown tag.SetArtist(szArtist); tag.SetAlbum(m_szStreamName); //Jazzmusique (Album is like Directory) } else { tag.Clear(); tag.SetTitle(m_szStreamName); } } }
// Based on MediaInfo // by J�r�me Martinez, [email protected] // http://sourceforge.net/projects/mediainfo/ bool CMusicInfoTagLoaderWMA::Load(const CStdString& strFileName, CMusicInfoTag& tag) { try { tag.SetLoaded(false); CFile file; if (!file.Open(strFileName)) return false; tag.SetURL(strFileName); // Note that we're reading in a bit more than the buffer size, because the 'peek'ing // below is dealing with integers and reads off the end. Rather than change // all the checks below, I've simply allocated a bigger buffer. const unsigned int bufferSize = 256*1024; auto_aptr<unsigned char> pData(new unsigned char[bufferSize+32]); file.Read(pData.get(), bufferSize+32); file.Close(); unsigned int iOffset; unsigned int* pDataI; CStdString16 utf16String; //Play time iOffset = 0; pDataI = (unsigned int*)pData.get(); while (!(pDataI[0] == 0x75B22630 && pDataI[1] == 0x11CF668E && pDataI[2] == 0xAA00D9A6 && pDataI[3] == 0x6CCE6200) && iOffset <= bufferSize - 4) { iOffset++; pDataI = (unsigned int*)(pData.get() + iOffset); } if (iOffset > bufferSize - 4) return false; //Play time iOffset = 0; pDataI = (unsigned int*)pData.get(); while (!(pDataI[0] == 0x8CABDCA1 && pDataI[1] == 0x11CFA947 && pDataI[2] == 0xC000E48E && pDataI[3] == 0x6553200C) && iOffset <= bufferSize - 4) { iOffset++; pDataI = (unsigned int*)(pData.get() + iOffset); } if (iOffset <= bufferSize - 4) { iOffset += 64; pDataI = (unsigned int*)(pData.get() + iOffset); float F1 = (float)pDataI[1]; F1 = F1 * 0x10000 * 0x10000 + pDataI[0]; tag.SetDuration((long)((F1 / 10000) / 1000)); // from milliseconds to seconds } //Description Title iOffset = 0; pDataI = (unsigned int*)pData.get(); while (!(pDataI[0] == 0x75B22633 && pDataI[1] == 0x11CF668E && pDataI[2] == 0xAA00D9A6 && pDataI[3] == 0x6CCE6200) && iOffset <= bufferSize - 4) { iOffset++; pDataI = (unsigned int*)(pData.get() + iOffset); } if (iOffset <= bufferSize - 4) { iOffset += 24; int nTitleSize = pData[iOffset + 0] + pData[iOffset + 1] * 0x100; int nAuthorSize = pData[iOffset + 2] + pData[iOffset + 3] * 0x100; //int nCopyrightSize = pData[iOffset + 4] + pData[iOffset + 5] * 0x100; //int nCommentsSize = pData[iOffset + 6] + pData[iOffset + 7] * 0x100; iOffset += 10; CStdString utf8String; if (nTitleSize) { // TODO: UTF-8 Do we need to "fixString" these strings at all? utf16String = (uint16_t*)(pData.get()+iOffset); g_charsetConverter.utf16LEtoUTF8(utf16String, utf8String); tag.SetTitle(utf8String); } if (nAuthorSize) { utf8String = ""; utf16String = (uint16_t*)(pData.get() + iOffset + nTitleSize); g_charsetConverter.utf16LEtoUTF8(utf16String, utf8String); tag.SetArtist(utf8String); } //General(ZT("Copyright"))=(LPWSTR)(pData.get()+iOffset+(nTitleSize+nAuthorSize)); //General(ZT("Comments"))=(LPWSTR)(pData.get()+iOffset+(nTitleSize+nAuthorSize+nCopyrightSize)); } // Maybe these information can be usefull in the future //Info audio //iOffset=0; //pDataI=(unsigned int*)pData; //while (!(pDataI[0]==0xF8699E40 && pDataI[1]==0x11CF5B4D && pDataI[2]==0x8000FDA8 && pDataI[3]==0x2B445C5F) && iOffset<=bufferSize-4) //{ //iOffset++; //pDataI=(unsigned int*)(pData+iOffset); //} //if (iOffset<=bufferSize-4) //{ //iOffset+=54; ////Codec //TCHAR C1[30]; //_itoa(pData[iOffset]+pData[iOffset+1]*0x100, C1, 16); //CStdString Codec=C1; //while (Codec.size()<4) // Codec='0'+Codec; //Audio[0](ZT("Codec"))=Codec; //Audio[0](ZT("Channels"))=pData[iOffset+2]; //2 octets //pDataI=(unsigned int*)(pData+iOffset); //Audio[0](ZT("SamplingRate"))=pDataI[1]; //Audio[0](ZT("BitRate"))=pDataI[2]*8; //} //Info video //iOffset=0; //pDataI=(unsigned int*)pData; //while (!(pDataI[0]==0xBC19EFC0 && pDataI[1]==0x11CF5B4D && pDataI[2]==0x8000FDA8 && pDataI[3]==0x2B445C5F) && iOffset<=bufferSize-4) //{ //iOffset++; //pDataI=(unsigned int*)(pData+iOffset); //} //if (iOffset<=bufferSize-4) //{ //iOffset+=54; //iOffset+=15; //pDataI=(unsigned int*)(pData+iOffset); //Video[0](ZT("Width"))=pDataI[0]; //Video[0](ZT("Height"))=pDataI[1]; //Codec //unsigned char C1[5]; C1[4]='\0'; //C1[0]=pData[iOffset+12+0]; C1[1]=pData[iOffset+12+1]; C1[2]=pData[iOffset+12+2]; C1[3]=pData[iOffset+12+3]; //Video[0](ZT("Codec"))=wxString((char*)C1,wxConvUTF8).c_str(); //} //Read extended metadata iOffset = 0; pDataI = (unsigned int*)pData.get(); while (!(pDataI[0] == 0xD2D0A440 && pDataI[1] == 0x11D2E307 && pDataI[2] == 0xA000F097 && pDataI[3] == 0x50A85EC9) && iOffset <= bufferSize - 4) { iOffset++; pDataI = (unsigned int*)(pData.get() + iOffset); } if (iOffset <= bufferSize - 4) { iOffset += 24; // Walk through all frames in the file int iNumOfFrames = pData[iOffset] + pData[iOffset + 1] * 0x100; iOffset += 2; for (int Pos = 0; Pos < iNumOfFrames; Pos++) { int iFrameNameSize = pData[iOffset] + (pData[iOffset + 1] * 0x100); iOffset += 2; // Get frame name CStdString strFrameName; CStdStringW wString = ""; utf16String = (uint16_t*)(pData.get() + iOffset); g_charsetConverter.utf16LEtoUTF8(utf16String, strFrameName); iOffset += iFrameNameSize; // Get datatype of frame int iFrameType = pData[iOffset] + pData[iOffset + 1]; iOffset += 2; // Size of frame value unsigned int iValueSize = pData[iOffset] + (pData[iOffset + 1] * 0x100); iOffset += 2; // Sanity check for buffer size if (iValueSize + iOffset > bufferSize) { CLog::Log(LOGWARNING, "%s(%s) failed due to tag being larger than %ul", __FUNCTION__, strFileName.c_str(), bufferSize); break; } // Parse frame value and fill // tag with extended metadata if (iFrameType == WMT_TYPE_STRING && iValueSize > 0) { // TODO: UTF-8: Do we need to "fixString" these utf8 strings? CStdString utf8String; utf16String = (uint16_t*)(pData.get() + iOffset); g_charsetConverter.utf16LEtoUTF8(utf16String, utf8String); SetTagValueString(strFrameName, utf8String, tag); } else if (iFrameType == WMT_TYPE_BINARY && iValueSize > 0) { unsigned char* pValue = (unsigned char*)(pData.get() + iOffset); // Raw data SetTagValueBinary(strFrameName, pValue, tag); } else if (iFrameType == WMT_TYPE_BOOL && iValueSize > 0) { SetTagValueBool(strFrameName, pData[iOffset] != 0, tag); } else if (iFrameType == WMT_TYPE_DWORD && iValueSize > 0) { uint32_t value = pData[iOffset] + pData[iOffset + 1] * 0x100 + pData[iOffset + 2] * 0x10000 + pData[iOffset + 3] * 0x1000000; SetTagValueUnsigned(strFrameName, value, tag); } else if (iFrameType == WMT_TYPE_QWORD && iValueSize > 0) { //DWORD qwValue = pData[iOffset] + pData[iOffset + 1] * 0x100 + pData[iOffset + 2] * 0x10000 + pData[iOffset + 3] * 0x1000000; } else if (iFrameType == WMT_TYPE_WORD && iValueSize > 0) { //WORD wValue = pData[iOffset] + pData[iOffset + 1] * 0x100; } // parse next frame iOffset += iValueSize; } } //Read extended metadata 2 iOffset = 0; pDataI = (unsigned int*)pData.get(); while (!(pDataI[0] == 0x44231C94 && pDataI[1] == 0x49D19498 && pDataI[2] == 0x131D41A1 && pDataI[3] == 0x5470454E) && iOffset <= bufferSize - 4) { iOffset++; pDataI = (unsigned int*)(pData.get() + iOffset); } if (iOffset <= bufferSize - 4) { iOffset += 24; // Walk through all frames in the file int iNumOfFrames = pData[iOffset] + pData[iOffset + 1] * 0x100; iOffset += 6; for (int Pos = 0; Pos < iNumOfFrames; Pos++) { int iFrameNameSize = pData[iOffset] + (pData[iOffset + 1] * 0x100); iOffset += 2; // Get datatype of frame int iFrameType = pData[iOffset] + pData[iOffset + 1]; iOffset += 2; // Size of frame value unsigned int iValueSize = pData[iOffset] + (pData[iOffset + 1] * 0x100) + (pData[iOffset + 2] * 0x10000); iOffset += 4; // Get frame name CStdString strFrameName = ""; CStdStringW wString = ""; utf16String = (uint16_t*)(pData.get() + iOffset); g_charsetConverter.utf16LEtoUTF8(utf16String, strFrameName); iOffset += iFrameNameSize; // Sanity check for buffer size if (iValueSize + iOffset > bufferSize) { CLog::Log(LOGWARNING, "%s(%s) failed due to tag being larger than %ul", __FUNCTION__, strFileName.c_str(), bufferSize); break; } // Parse frame value and fill // tag with extended metadata if (iFrameType == WMT_TYPE_STRING && iValueSize > 0) { // TODO: UTF-8: Do we need to "fixString" these utf8 strings? CStdString utf8String; utf16String = (uint16_t*)(pData.get() + iOffset); g_charsetConverter.utf16LEtoUTF8(utf16String, utf8String); SetTagValueString(strFrameName, utf8String, tag); } else if (iFrameType == WMT_TYPE_BINARY && iValueSize > 0) { unsigned char* pValue = (unsigned char*)(pData.get() + iOffset); // Raw data SetTagValueBinary(strFrameName, pValue, tag); } else if (iFrameType == WMT_TYPE_BOOL && iValueSize > 0) { SetTagValueBool(strFrameName, pData[iOffset] != 0, tag); } else if (iFrameType == WMT_TYPE_DWORD && iValueSize > 0) { uint32_t value = pData[iOffset] + pData[iOffset + 1] * 0x100 + pData[iOffset + 2] * 0x10000 + pData[iOffset + 3] * 0x1000000; SetTagValueUnsigned(strFrameName, value, tag); } else if (iFrameType == WMT_TYPE_QWORD && iValueSize > 0) { //DWORD qwValue = pData[iOffset] + pData[iOffset + 1] * 0x100 + pData[iOffset + 2] * 0x10000 + pData[iOffset + 3] * 0x1000000; } else if (iFrameType == WMT_TYPE_WORD && iValueSize > 0) { //WORD wValue = pData[iOffset] + pData[iOffset + 1] * 0x100; } // parse next frame iOffset += iValueSize + 4; } } tag.SetLoaded(true); return true; } catch (...) { CLog::Log(LOGERROR, "Tag loader wma: exception in file %s", strFileName.c_str()); } tag.SetLoaded(false); return false; }
void CMusicInfoTagLoaderWMA::SetTagValueString(const CStdString& strFrameName, const CStdString& strValue, CMusicInfoTag& tag) { if (strFrameName == "WM/AlbumTitle") { tag.SetAlbum(strValue); } else if (strFrameName == "WM/AlbumArtist") { if (tag.GetAlbumArtist().IsEmpty()) tag.SetAlbumArtist(strValue); } else if (strFrameName == "Author") { // Multiple artists are stored in multiple "Author" tags we have get them // separatly and merge them to our system if (tag.GetArtist().IsEmpty()) tag.SetArtist(strValue); else tag.SetArtist(tag.GetArtist() + g_advancedSettings.m_musicItemSeparator + strValue); } else if (strFrameName == "WM/TrackNumber") { if (tag.GetTrackNumber() <= 0) tag.SetTrackNumber(atoi(strValue.c_str())); } else if (strFrameName == "WM/PartOfSet") { tag.SetPartOfSet(atoi(strValue.c_str())); } //else if (strFrameName=="WM/Track") // Old Tracknumber, should not be used anymore else if (strFrameName == "WM/Year") { SYSTEMTIME dateTime; dateTime.wYear = atoi(strValue.c_str()); tag.SetReleaseDate(dateTime); } else if (strFrameName == "WM/Genre") { // Multiple genres are stared in multiple "WM/Genre" tags we have to get them // separatly and merge them to our system if (tag.GetGenre().IsEmpty()) tag.SetGenre(strValue); else tag.SetGenre(tag.GetGenre() + g_advancedSettings.m_musicItemSeparator + strValue); } else if (strFrameName == "WM/Lyrics") { tag.SetLyrics(strValue); } //else if (strFrameName=="WM/DRM") //{ // // File is DRM protected // pwszValue; //} //else if (strFrameName=="WM/Codec") //{ // pwszValue; //} //else if (strFrameName=="WM/BeatsPerMinute") //{ // pwszValue; //} //else if (strFrameName=="WM/Mood") //{ // pwszValue; //} //else if (strFrameName=="WM/RadioStationName") //{ // pwszValue; //} //else if (strFrameName=="WM/RadioStationOwner") //{ // pwszValue; //} }
void CMusicInfoTagLoaderMP4::ParseTag( unsigned int metaKey, const char* pMetaData, int metaSize, CMusicInfoTag& tag, EmbeddedArt *art) { switch ( metaKey ) { case g_TitleAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; // we use utf8 internally tag.SetLoaded( true ); tag.SetTitle( dataWorkspace.get() ); break; } case g_ArtistAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetArtist( dataWorkspace.get() ); break; } case g_AlbumAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetAlbum( dataWorkspace.get() ); break; } case g_AlbumArtistAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetAlbumArtist( dataWorkspace.get() ); break; } case g_DayAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; SYSTEMTIME dateTime; dateTime.wYear = atoi( dataWorkspace.get() ); tag.SetReleaseDate( dateTime ); break; } case g_GenreAtomName: { // When a genre number is specified, we need to translate to a string for display.. // Note that AAC/iTunes genre numbers are the same as ID3 numbers, but are offset by 1. const char* pGenre = ID3_V1GENRE2DESCRIPTION( (unsigned char)pMetaData[ 1 ] - 1 ); if ( pGenre ) { tag.SetGenre( pGenre ); } break; } case g_CompilationAtomName: { if (metaSize == 1) tag.SetCompilation(*pMetaData == 1); break; } case g_CommentAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetComment( dataWorkspace.get() ); break; } case g_LyricsAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetLyrics( dataWorkspace.get() ); break; } case g_CustomGenreAtomName: { // We need to zero-terminate the string, which needs workspace.. auto_aptr<char> dataWorkspace( new char[ metaSize + 1 ] ); memcpy( dataWorkspace.get(), pMetaData, metaSize ); dataWorkspace[ metaSize ] = '\0'; tag.SetGenre( dataWorkspace.get() ); break; } case g_TrackNumberAtomName: { tag.SetTrackNumber( (unsigned char)pMetaData[ 3 ] ); break; } case g_DiscNumberAtomName: { tag.SetPartOfSet( (unsigned char)pMetaData[ 3 ] ); break; } case g_CoverArtAtomName: { // This cover-art handling is pretty much what was in the old MP4 tag processing code.. // note that according to http://atomicparsley.sourceforge.net/mpeg-4files.html the type // of image (PNG=14 or JPG=13) is contained in pMetadata[-5] std::string mimeType; if (pMetaData[-5] == 13) mimeType = "image/jpeg"; else if (pMetaData[-5] == 14) mimeType = "image/png"; else CLog::Log(LOGDEBUG, "Unknown art mimetype %d", pMetaData[-5]); tag.SetCoverArtInfo(metaSize, mimeType); if (art) art->set((const uint8_t*)pMetaData, metaSize, mimeType); break; } default: break; } }
bool CPVRManager::UpdateItem(CFileItem& item) { /* Don't update if a recording is played */ if (item.IsPVRRecording()) return false; if (!item.IsPVRChannel()) { CLog::Log(LOGERROR, "CPVRManager - %s - no channel tag provided", __FUNCTION__); return false; } CSingleLock lock(m_critSection); if (!m_currentFile || *m_currentFile->GetPVRChannelInfoTag() == *item.GetPVRChannelInfoTag()) return false; g_application.SetCurrentFileItem(*m_currentFile); CFileItemPtr itemptr(new CFileItem(*m_currentFile)); g_infoManager.SetCurrentItem(itemptr); CPVRChannelPtr channelTag(item.GetPVRChannelInfoTag()); CEpgInfoTagPtr epgTagNow(channelTag->GetEPGNow()); if (channelTag->IsRadio()) { CMusicInfoTag* musictag = item.GetMusicInfoTag(); if (musictag) { musictag->SetTitle(epgTagNow ? epgTagNow->Title() : CSettings::GetInstance().GetBool(CSettings::SETTING_EPG_HIDENOINFOAVAILABLE) ? "" : g_localizeStrings.Get(19055)); // no information available if (epgTagNow) musictag->SetGenre(epgTagNow->Genre()); musictag->SetDuration(epgTagNow ? epgTagNow->GetDuration() : 3600); musictag->SetURL(channelTag->Path()); musictag->SetArtist(channelTag->ChannelName()); musictag->SetAlbumArtist(channelTag->ChannelName()); musictag->SetLoaded(true); musictag->SetComment(""); musictag->SetLyrics(""); } } else { CVideoInfoTag *videotag = item.GetVideoInfoTag(); if (videotag) { videotag->m_strTitle = epgTagNow ? epgTagNow->Title() : CSettings::GetInstance().GetBool(CSettings::SETTING_EPG_HIDENOINFOAVAILABLE) ? "" : g_localizeStrings.Get(19055); // no information available if (epgTagNow) videotag->m_genre = epgTagNow->Genre(); videotag->m_strPath = channelTag->Path(); videotag->m_strFileNameAndPath = channelTag->Path(); videotag->m_strPlot = epgTagNow ? epgTagNow->Plot() : ""; videotag->m_strPlotOutline = epgTagNow ? epgTagNow->PlotOutline() : ""; videotag->m_iEpisode = epgTagNow ? epgTagNow->EpisodeNumber() : 0; } } return false; }
bool CMusicInfoTagLoaderSid::Load(const CStdString& strFileName, CMusicInfoTag& tag) { CStdString strFileToLoad = strFileName; int iTrack = 0; CStdString strExtension; CUtil::GetExtension(strFileName,strExtension); strExtension.MakeLower(); if (strExtension==".sidstream") { // Extract the track to play CStdString strFile=CUtil::GetFileName(strFileName); int iStart=strFile.ReverseFind("-")+1; iTrack = atoi(strFile.substr(iStart, strFile.size()-iStart-10).c_str()); // The directory we are in, is the file // that contains the bitstream to play, // so extract it CStdString strPath=strFileName; CUtil::GetDirectory(strPath, strFileToLoad); CUtil::RemoveSlashAtEnd(strFileToLoad); // we want the filename } CStdString strFileNameLower(strFileToLoad); strFileNameLower.MakeLower(); int iHVSC = strFileNameLower.find("hvsc"); // need hvsc in path name since our lookupfile is based on hvsc paths if (iHVSC < 0) { iHVSC = strFileNameLower.find("c64music"); if (iHVSC >= 0) iHVSC += 8; } else iHVSC += 4; if( iHVSC < 0 ) { tag.SetLoaded(false); return( false ); } CStdString strHVSCpath = strFileToLoad.substr(iHVSC,strFileToLoad.length()-1); strHVSCpath.Replace('\\','/'); // unix paths strHVSCpath.MakeLower(); char temp[8192]; CRegExp reg; if (!reg.RegComp("TITLE: ([^\r\n]*)\r?\n[^A]*ARTIST: ([^\r\n]*)\r?\n")) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..): failed to compile regular expression"); tag.SetLoaded(false); return( false ); } sprintf(temp,"%s\\%s",g_settings.GetDatabaseFolder().c_str(),"stil.txt"); // changeme? std::ifstream f(temp); if( !f.good() ) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..) unable to locate stil.txt"); tag.SetLoaded(false); return( false ); } const char* szStart = NULL; const char* szEnd = NULL; char temp2[8191]; char* temp3 = temp2; while( !f.eof() && !szEnd ) { f.read(temp,8191); CStdString strLower = temp; strLower.MakeLower(); if (!szStart) szStart= (char *)strstr(strLower.c_str(),strHVSCpath.c_str()); if (szStart) { szEnd = strstr(szStart+strHVSCpath.size(),".sid"); if (szEnd) { memcpy(temp3,temp+(szStart-strLower.c_str()),szEnd-szStart); temp3 += szEnd-szStart; } else { memcpy(temp3,temp+(szStart-strLower.c_str()),strlen(szStart)); szStart = NULL; temp3 += strlen(szStart); } } } f.close(); if (!f.eof() && szEnd) { temp2[temp3-temp2] = '\0'; temp3 = strstr(temp2,"TITLE:"); } else temp3 = NULL; if (temp3) { for (int i=0;i<iTrack-1;++i) // skip tracks { int iStart = reg.RegFind(temp3); if (!iStart) { tag.SetLoaded(false); return false; } temp3 += iStart; } if(reg.RegFind(temp3) > -1) { char* szTitle = reg.GetReplaceString("\\1"); char* szArtist = reg.GetReplaceString("\\2"); char* szMins = NULL; char* szSecs = NULL; CRegExp reg2; reg2.RegComp("(.*) \\(([0-9]*):([0-9]*)\\)"); if (reg2.RegFind(szTitle) > -1) { szMins = reg2.GetReplaceString("\\2"); szSecs = reg2.GetReplaceString("\\3"); char* szTemp = reg2.GetReplaceString("\\1"); free(szTitle); szTitle = szTemp; } tag.SetLoaded(true); tag.SetURL(strFileToLoad); tag.SetTrackNumber(iTrack); if (szMins && szSecs) tag.SetDuration(atoi(szMins)*60+atoi(szSecs)); tag.SetTitle(szTitle); tag.SetArtist(szArtist); if( szTitle ) free(szTitle); if( szArtist ) free(szArtist); if( szMins ) free(szMins); if( szSecs ) free(szSecs); } } sprintf(temp,"%s\\%s",g_settings.GetDatabaseFolder().c_str(),"sidlist.csv"); // changeme? std::ifstream f2(temp); if( !f2.good() ) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..) unable to locate sidlist.csv"); tag.SetLoaded(false); return( false ); } while( !f2.eof() ) { f2.getline(temp,8191); CStdString strTemp(temp); strTemp.MakeLower(); unsigned int iFind = strTemp.find(strHVSCpath); if (iFind == string::npos) continue; char temp2[1024]; char temp3[1024]; strncpy(temp3,temp+iFind,strlen(strHVSCpath)); temp3[strlen(strHVSCpath)] = '\0'; sprintf(temp2,"\"%s\",\"[^\"]*\",\"[^\"]*\",\"([^\"]*)\",\"([^\"]*)\",\"([0-9]*)[^\"]*\",\"[0-9]*\",\"[0-9]*\",\"",temp3); for (int i=0;i<iTrack-1;++i) strcat(temp2,"[0-9]*:[0-9]* "); strcat(temp2,"([0-9]*):([0-9]*)"); if( !reg.RegComp(temp2) ) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..): failed to compile regular expression"); tag.SetLoaded(false); return( false ); } if( reg.RegFind(temp) >= 0 ) { char* szTitle = reg.GetReplaceString("\\1"); char* szArtist = reg.GetReplaceString("\\2"); char* szYear = reg.GetReplaceString("\\3"); char* szMins = reg.GetReplaceString("\\4"); char* szSecs = reg.GetReplaceString("\\5"); tag.SetLoaded(true); tag.SetTrackNumber(iTrack); if (tag.GetDuration() == 0) tag.SetDuration(atoi(szMins)*60+atoi(szSecs)); if (tag.GetTitle() == "") tag.SetTitle(szTitle); if (tag.GetArtist() == "") tag.SetArtist(szArtist); SYSTEMTIME dateTime; dateTime.wYear = atoi(szYear); tag.SetReleaseDate(dateTime); if( szTitle ) free(szTitle); if( szArtist ) free(szArtist); if( szYear ) free(szYear); if( szMins ) free(szMins); if( szSecs ) free(szSecs); f2.close(); return( true ); } } f2.close(); tag.SetLoaded(false); return( false ); }