Exemplo n.º 1
0
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));
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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()));
  }
}
Exemplo n.º 6
0
void CVideoLibrary::UpdateVideoTag(const CVariant &parameterObject, 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");
    }
}