static void ParseItemZink(CFileItem* item, SResources& resources, TiXmlElement* element, const std::string& name, const std::string& xmlns, const std::string& path) { CVideoInfoTag* vtag = item->GetVideoInfoTag(); std::string text = GetValue(element); if (name == "episode") vtag->m_iEpisode = atoi(text.c_str()); else if(name == "season") vtag->m_iSeason = atoi(text.c_str()); else if(name == "views") vtag->SetPlayCount(atoi(text.c_str())); else if(name == "airdate") vtag->m_firstAired.SetFromDateString(text); else if(name == "userrating") vtag->SetRating((float)atof(text.c_str())); else if(name == "duration") vtag->SetDuration(atoi(text.c_str())); else if(name == "durationstr") vtag->SetDuration(StringUtils::TimeStringToSeconds(text)); }
static void ParseItemBoxee(CFileItem* item, SResources& resources, TiXmlElement* element, const std::string& name, const std::string& xmlns, const std::string& path) { CVideoInfoTag* vtag = item->GetVideoInfoTag(); std::string text = GetValue(element); if (name == "image") item->SetArt("thumb", text); else if(name == "user_agent") item->SetProperty("boxee:user_agent", text); else if(name == "content_type") item->SetMimeType(text); else if(name == "runtime") vtag->SetDuration(StringUtils::TimeStringToSeconds(text)); else if(name == "episode") vtag->m_iEpisode = atoi(text.c_str()); else if(name == "season") vtag->m_iSeason = atoi(text.c_str()); else if(name == "view-count") vtag->SetPlayCount(atoi(text.c_str())); else if(name == "tv-show-title") vtag->m_strShowTitle = text; else if(name == "release-date") item->SetProperty("boxee:releasedate", text); }
static void ParseItemItunes(CFileItem* item, SResources& resources, TiXmlElement* item_child, const std::string& name, const std::string& xmlns, const std::string& path) { CVideoInfoTag* vtag = item->GetVideoInfoTag(); std::string text = GetValue(item_child); if(name == "image") { const char * url = item_child->Attribute("href"); if(url) item->SetArt("thumb", url); else item->SetArt("thumb", text); } else if(name == "summary") vtag->m_strPlot = text; else if(name == "subtitle") vtag->m_strPlotOutline = text; else if(name == "author") vtag->m_writingCredits.push_back(text); else if(name == "duration") vtag->SetDuration(StringUtils::TimeStringToSeconds(text)); else if(name == "keywords") item->SetProperty("keywords", text); }
bool CThumbExtractor::DoWork() { if (m_item.IsLiveTV() // Due to a pvr addon api design flaw (no support for multiple concurrent streams // per addon instance), pvr recording thumbnail extraction does not work (reliably). || URIUtils::IsPVRRecording(m_item.GetDynPath()) || URIUtils::IsUPnP(m_item.GetPath()) || URIUtils::IsBluray(m_item.GetPath()) || m_item.IsBDFile() || m_item.IsDVD() || m_item.IsDiscImage() || m_item.IsDVDFile(false, true) || m_item.IsInternetStream() || m_item.IsDiscStub() || m_item.IsPlayList()) return false; // For HTTP/FTP we only allow extraction when on a LAN if (URIUtils::IsRemote(m_item.GetPath()) && !URIUtils::IsOnLAN(m_item.GetPath()) && (URIUtils::IsFTP(m_item.GetPath()) || URIUtils::IsHTTP(m_item.GetPath()))) return false; bool result=false; if (m_thumb) { CLog::Log(LOGDEBUG,"%s - trying to extract thumb from video file %s", __FUNCTION__, CURL::GetRedacted(m_item.GetPath()).c_str()); // construct the thumb cache file CTextureDetails details; details.file = CTextureCache::GetCacheFile(m_target) + ".jpg"; result = CDVDFileInfo::ExtractThumb(m_item, details, m_fillStreamDetails ? &m_item.GetVideoInfoTag()->m_streamDetails : nullptr, m_pos); if(result) { CTextureCache::GetInstance().AddCachedTexture(m_target, details); m_item.SetProperty("HasAutoThumb", true); m_item.SetProperty("AutoThumbImage", m_target); m_item.SetArt("thumb", m_target); CVideoInfoTag* info = m_item.GetVideoInfoTag(); if (info->m_iDbId > 0 && !info->m_type.empty()) { CVideoDatabase db; if (db.Open()) { db.SetArtForItem(info->m_iDbId, info->m_type, "thumb", m_item.GetArt("thumb")); db.Close(); } } } } else if (!m_item.IsPlugin() && (!m_item.HasVideoInfoTag() || !m_item.GetVideoInfoTag()->HasStreamDetails())) { // No tag or no details set, so extract them CLog::Log(LOGDEBUG,"%s - trying to extract filestream details from video file %s", __FUNCTION__, CURL::GetRedacted(m_item.GetPath()).c_str()); result = CDVDFileInfo::GetFileStreamDetails(&m_item); } if (result) { CVideoInfoTag* info = m_item.GetVideoInfoTag(); CVideoDatabase db; if (db.Open()) { if (URIUtils::IsStack(m_listpath)) { // Don't know the total time of the stack, so set duration to zero to avoid confusion info->m_streamDetails.SetVideoDuration(0, 0); // Restore original stack path m_item.SetPath(m_listpath); } if (info->m_iFileId < 0) db.SetStreamDetailsForFile(info->m_streamDetails, !info->m_strFileNameAndPath.empty() ? info->m_strFileNameAndPath : m_item.GetPath()); else db.SetStreamDetailsForFileId(info->m_streamDetails, info->m_iFileId); // overwrite the runtime value if the one from streamdetails is available if (info->m_iDbId > 0 && info->GetStaticDuration() != info->GetDuration()) { info->SetDuration(info->GetDuration()); // store the updated information in the database db.SetDetailsForItem(info->m_iDbId, info->m_type, *info, m_item.GetArt()); } db.Close(); } return true; } return false; }
static void ParseItem(CFileItem* item, TiXmlElement* root, const std::string& path) { SResources resources; ParseItem(item, resources, root, path); const char* prio[] = { "media:content", "voddler:trailer", "rss:enclosure", "svtplay:broadcasts", "svtplay:xmllink", "rss:link", "rss:guid", NULL }; std::string mime; if (FindMime(resources, "video/")) mime = "video/"; else if(FindMime(resources, "audio/")) mime = "audio/"; else if(FindMime(resources, "application/rss")) mime = "application/rss"; else if(FindMime(resources, "image/")) mime = "image/"; int maxrate = CServiceBroker::GetSettings().GetInt(CSettings::SETTING_NETWORK_BANDWIDTH); if(maxrate == 0) maxrate = INT_MAX; SResources::iterator best = resources.end(); for(const char** type = prio; *type && best == resources.end(); type++) { for(SResources::iterator it = resources.begin(); it != resources.end(); it++) { if(!StringUtils::StartsWith(it->mime, mime)) continue; if(it->tag == *type) { if(best == resources.end()) { best = it; continue; } if(it->bitrate == best->bitrate) { if(it->width*it->height > best->width*best->height) best = it; continue; } if(it->bitrate > maxrate) { if(it->bitrate < best->bitrate) best = it; continue; } if(it->bitrate > best->bitrate) { best = it; continue; } } } } if(best != resources.end()) { item->SetMimeType(best->mime); item->SetPath(best->path); item->m_dwSize = best->size; if(best->duration) item->SetProperty("duration", StringUtils::SecondsToTimeString(best->duration)); /* handling of mimetypes fo directories are sub optimal at best */ if(best->mime == "application/rss+xml" && StringUtils::StartsWithNoCase(item->GetPath(), "http://")) item->SetPath("rss://" + item->GetPath().substr(7)); if(StringUtils::StartsWithNoCase(item->GetPath(), "rss://")) item->m_bIsFolder = true; else item->m_bIsFolder = false; } if(!item->m_strTitle.empty()) item->SetLabel(item->m_strTitle); if(item->HasVideoInfoTag()) { CVideoInfoTag* vtag = item->GetVideoInfoTag(); if(item->HasProperty("duration") && !vtag->GetDuration()) vtag->SetDuration(StringUtils::TimeStringToSeconds(item->GetProperty("duration").asString())); if(item->HasProperty("description") && vtag->m_strPlot.empty()) vtag->m_strPlot = item->GetProperty("description").asString(); if(vtag->m_strPlotOutline.empty() && !vtag->m_strPlot.empty()) { size_t pos = vtag->m_strPlot.find('\n'); if(pos != std::string::npos) vtag->m_strPlotOutline = vtag->m_strPlot.substr(0, pos); else vtag->m_strPlotOutline = vtag->m_strPlot; } if(!vtag->GetDuration()) item->SetLabel2(StringUtils::SecondsToTimeString(vtag->GetDuration())); } }
void CVideoLibrary::UpdateVideoTag(const CVariant ¶meterObject, CVideoInfoTag& details, std::map<std::string, std::string> &artwork, std::set<std::string> &removedArtwork, std::set<std::string> &updatedDetails) { if (ParameterNotNull(parameterObject, "title")) details.SetTitle(parameterObject["title"].asString()); if (ParameterNotNull(parameterObject, "playcount")) details.SetPlayCount(static_cast<int>(parameterObject["playcount"].asInteger())); if (ParameterNotNull(parameterObject, "runtime")) details.SetDuration(static_cast<int>(parameterObject["runtime"].asInteger())); std::vector<std::string> director(details.m_director); UpdateVideoTagField(parameterObject, "director", director, updatedDetails); details.SetDirector(director); std::vector<std::string> studio(details.m_studio); UpdateVideoTagField(parameterObject, "studio", studio, updatedDetails); details.SetStudio(studio); if (ParameterNotNull(parameterObject, "plot")) details.SetPlot(parameterObject["plot"].asString()); if (ParameterNotNull(parameterObject, "album")) details.SetAlbum(parameterObject["album"].asString()); std::vector<std::string> artist(details.m_artist); UpdateVideoTagField(parameterObject, "artist", artist, updatedDetails); details.SetArtist(artist); std::vector<std::string> genre(details.m_genre); UpdateVideoTagField(parameterObject, "genre", genre, updatedDetails); details.SetGenre(genre); if (ParameterNotNull(parameterObject, "track")) details.m_iTrack = (int)parameterObject["track"].asInteger(); if (ParameterNotNull(parameterObject, "rating")) { details.SetRating(parameterObject["rating"].asFloat()); updatedDetails.insert("ratings"); } if (ParameterNotNull(parameterObject, "votes")) { details.SetVotes(StringUtils::ReturnDigits(parameterObject["votes"].asString())); updatedDetails.insert("ratings"); //Votes and ratings both need updates now, this will trigger those } if (ParameterNotNull(parameterObject, "ratings")) { CVariant ratings = parameterObject["ratings"]; for (CVariant::const_iterator_map rIt = ratings.begin_map(); rIt != ratings.end_map(); rIt++) { if (rIt->second.isObject() && ParameterNotNull(rIt->second, "rating")) { const auto& rating = rIt->second; if (ParameterNotNull(rating, "votes")) details.SetRating(rating["rating"].asFloat(), rating["votes"].asFloat(), rIt->first, (ParameterNotNull(rating, "default") && rating["default"].asBoolean())); else details.SetRating(rating["rating"].asFloat(), rIt->first, (ParameterNotNull(rating, "default") && rating["default"].asBoolean())); updatedDetails.insert("ratings"); } else if (rIt->second.isNull()) { details.RemoveRating(rIt->first); updatedDetails.insert("ratings"); } } } if (ParameterNotNull(parameterObject, "userrating")) details.m_iUserRating = parameterObject["userrating"].asInteger(); if (ParameterNotNull(parameterObject, "mpaa")) details.SetMPAARating(parameterObject["mpaa"].asString()); if (ParameterNotNull(parameterObject, "imdbnumber")) { details.SetUniqueID(parameterObject["imdbnumber"].asString()); updatedDetails.insert("uniqueid"); } if (ParameterNotNull(parameterObject, "uniqueid")) { CVariant uniqueids = parameterObject["uniqueid"]; for (CVariant::const_iterator_map idIt = uniqueids.begin_map(); idIt != uniqueids.end_map(); idIt++) { if (idIt->second.isString() && !idIt->second.asString().empty()) { details.SetUniqueID(idIt->second.asString(), idIt->first); updatedDetails.insert("uniqueid"); } else if (idIt->second.isNull() && idIt->first != details.GetDefaultUniqueID()) { details.RemoveUniqueID(idIt->first); updatedDetails.insert("uniqueid"); } } } if (ParameterNotNull(parameterObject, "premiered")) { CDateTime premiered; SetFromDBDate(parameterObject["premiered"], premiered); details.SetPremiered(premiered); } else if (ParameterNotNull(parameterObject, "year")) details.SetYear((int)parameterObject["year"].asInteger()); if (ParameterNotNull(parameterObject, "lastplayed")) SetFromDBDateTime(parameterObject["lastplayed"], details.m_lastPlayed); if (ParameterNotNull(parameterObject, "firstaired")) SetFromDBDate(parameterObject["firstaired"], details.m_firstAired); if (ParameterNotNull(parameterObject, "productioncode")) details.SetProductionCode(parameterObject["productioncode"].asString()); if (ParameterNotNull(parameterObject, "season")) details.m_iSeason = (int)parameterObject["season"].asInteger(); if (ParameterNotNull(parameterObject, "episode")) details.m_iEpisode = (int)parameterObject["episode"].asInteger(); if (ParameterNotNull(parameterObject, "originaltitle")) details.SetOriginalTitle(parameterObject["originaltitle"].asString()); if (ParameterNotNull(parameterObject, "trailer")) details.SetTrailer(parameterObject["trailer"].asString()); if (ParameterNotNull(parameterObject, "tagline")) details.SetTagLine(parameterObject["tagline"].asString()); if (ParameterNotNull(parameterObject, "status")) details.SetStatus(parameterObject["status"].asString()); if (ParameterNotNull(parameterObject, "plotoutline")) details.SetPlotOutline(parameterObject["plotoutline"].asString()); std::vector<std::string> credits(details.m_writingCredits); UpdateVideoTagField(parameterObject, "writer", credits, updatedDetails); details.SetWritingCredits(credits); std::vector<std::string> country(details.m_country); UpdateVideoTagField(parameterObject, "country", country, updatedDetails); details.SetCountry(country); if (ParameterNotNull(parameterObject, "top250")) details.m_iTop250 = (int)parameterObject["top250"].asInteger(); if (ParameterNotNull(parameterObject, "sorttitle")) details.SetSortTitle(parameterObject["sorttitle"].asString()); if (ParameterNotNull(parameterObject, "episodeguide")) details.SetEpisodeGuide(parameterObject["episodeguide"].asString()); if (ParameterNotNull(parameterObject, "set")) { details.SetSet(parameterObject["set"].asString()); updatedDetails.insert("set"); } std::vector<std::string> showLink(details.m_showLink); UpdateVideoTagField(parameterObject, "showlink", showLink, updatedDetails); details.SetShowLink(showLink); std::vector<std::string> tags(details.m_tags); UpdateVideoTagField(parameterObject, "tag", tags, updatedDetails); details.SetTags(tags); if (ParameterNotNull(parameterObject, "thumbnail")) { std::string value = parameterObject["thumbnail"].asString(); artwork["thumb"] = StringUtils::Trim(value); updatedDetails.insert("art.altered"); } if (ParameterNotNull(parameterObject, "fanart")) { std::string value = parameterObject["fanart"].asString(); artwork["fanart"] = StringUtils::Trim(value); updatedDetails.insert("art.altered"); } if (ParameterNotNull(parameterObject, "art")) { CVariant art = parameterObject["art"]; for (CVariant::const_iterator_map artIt = art.begin_map(); artIt != art.end_map(); artIt++) { if (artIt->second.isString() && !artIt->second.asString().empty()) { artwork[artIt->first] = CTextureUtils::UnwrapImageURL(artIt->second.asString()); updatedDetails.insert("art.altered"); } else if (artIt->second.isNull()) { artwork.erase(artIt->first); removedArtwork.insert(artIt->first); } } } if (ParameterNotNull(parameterObject, "dateadded")) { SetFromDBDateTime(parameterObject["dateadded"], details.m_dateAdded); updatedDetails.insert("dateadded"); } }