示例#1
0
int CDVDInputStreamHTSP::GetTime()
{
  CDateTimeSpan time;
  time  = CDateTime::GetUTCDateTime()
        - CDateTime((time_t)m_event.start);

  return time.GetDays()    * 1000 * 60 * 60 * 24
       + time.GetHours()   * 1000 * 60 * 60
       + time.GetMinutes() * 1000 * 60
       + time.GetSeconds() * 1000;
}
示例#2
0
int CDVDInputStreamHTSP::GetTotalTime()
{
    if(m_event.id == 0)
        return 0;

    long duration = (time_t)m_event.stop - (time_t)m_event.start;
    CDateTimeSpan time = CDateTimeSpan(0, 0, duration / 60, duration % 60);

    return time.GetDays()    * 1000 * 60 * 60 * 24
           + time.GetHours()   * 1000 * 60 * 60
           + time.GetMinutes() * 1000 * 60
           + time.GetSeconds() * 1000;
}
示例#3
0
int CPVRTimerInfoTag::Compare(const CPVRTimerInfoTag &timer) const
{
  int iTimerDelta = 0;
  if (StartAsUTC() != timer.StartAsUTC())
  {
    CDateTimeSpan timerDelta = StartAsUTC() - timer.StartAsUTC();
    iTimerDelta = (timerDelta.GetSeconds() + timerDelta.GetMinutes() * 60 + timerDelta.GetHours() * 3600 + timerDelta.GetDays() * 86400);
  }

  /* if the start times are equal, compare the priority of the timers */
  return iTimerDelta == 0 ?
    timer.m_iPriority - m_iPriority :
    iTimerDelta;
}
示例#4
0
int CMythFile::GetStartTime()
{
  if(m_program && m_recorder)
  {
    cmyth_timestamp_t start = m_dll->proginfo_start(m_program);
      
    CDateTimeSpan time;
    time  = CDateTime::GetCurrentDateTime()
          - CDateTime(m_dll->timestamp_to_unixtime(start));

    m_dll->ref_release(start);
    return time.GetDays()    * 1000 * 60 * 60 * 24
         + time.GetHours()   * 1000 * 60 * 60
         + time.GetMinutes() * 1000 * 60
         + time.GetSeconds() * 1000;
  }
  return 0;
}
示例#5
0
int CPVRGUIInfo::GetStartTime(void) const
{
  CSingleLock lock(m_critSection);

  if (m_playingEpgTag)
  {
    /* Calculate here the position we have of the running live TV event.
     * "position in ms" = ("current local time" - "event start local time") * 1000
     */
    CDateTimeSpan time = CDateTime::GetCurrentDateTime() - m_playingEpgTag->StartAsLocalTime();
    return time.GetDays()    * 1000 * 60 * 60 * 24
         + time.GetHours()   * 1000 * 60 * 60
         + time.GetMinutes() * 1000 * 60
         + time.GetSeconds() * 1000;
  }
  else
  {
    return 0;
  }
}
示例#6
0
int CPVRGUIInfo::GetStartTime(void) const
{
  CSingleLock lock(m_critSection);
  if (m_playingEpgTag || m_iTimeshiftStartTime)
  {
    /* Calculate here the position we have of the running live TV event.
     * "position in ms" = ("current UTC" - "event start UTC") * 1000
     */
    CDateTime current = m_iTimeshiftPlayTime;
    CDateTime start = m_playingEpgTag ? m_playingEpgTag->StartAsUTC() : m_iTimeshiftStartTime;
    CDateTimeSpan time = current > start ? current - start : CDateTimeSpan(0, 0, 0, 0);
    return (time.GetDays()   * 60 * 60 * 24
         + time.GetHours()   * 60 * 60
         + time.GetMinutes() * 60
         + time.GetSeconds()) * 1000;
  }
  else
  {
    return 0;
  }
}
示例#7
0
bool CMythDirectory::GetGuideForChannel(const CStdString& base, CFileItemList &items, int channelNumber)
{
  cmyth_database_t database = m_session->GetDatabase();
  if (!database)
  {
    CLog::Log(LOGERROR, "%s - Could not get database", __FUNCTION__);
    return false;
  }

  time_t now;
  time(&now);
  time_t end = now + (24 * 60 * 60); // How many seconds of EPG from now we should grab, 24 hours in seconds

  cmyth_program_t *program = NULL;
  // TODO: See if there is a way to just get the entries for the chosen channel rather than ALL
  int count = m_dll->mysql_get_guide(database, &program, now, end);
  CLog::Log(LOGDEBUG, "%s - %i entries in guide data", __FUNCTION__, count);
  if (count <= 0)
    return false;

  for (int i = 0; i < count; i++)
  {
    if (program[i].channum == channelNumber)
    {
      CFileItemPtr item(new CFileItem("", false)); // No path for guide entries

      /*
       * Set the FileItem meta data.
       */
      CStdString title        = program[i].title; // e.g. Mythbusters
      CStdString subtitle     = program[i].subtitle; // e.g. The Pirate Special
      CDateTime localstart;
      if (program[i].starttime)
        localstart = CTimeUtils::GetLocalTime(program[i].starttime);
      item->m_strTitle = StringUtils::Format("%s - %s",
                                             localstart.GetAsLocalizedTime("HH:mm", false).c_str(),
                                             title.c_str()); // e.g. 20:30 - Mythbusters
      if (!subtitle.empty())
        item->m_strTitle     += " - \"" + subtitle + "\""; // e.g. 20:30 - Mythbusters - "The Pirate Special"
      item->m_dateTime        = localstart;

      /*
       * Set the VideoInfoTag meta data so it matches the FileItem meta data where possible.
       */
      CVideoInfoTag* tag      = item->GetVideoInfoTag();
      tag->m_strTitle         = title;
      if (!subtitle.empty())
        tag->m_strTitle      += " - \"" + subtitle + "\""; // e.g. Mythbusters - "The Pirate Special"
      tag->m_strShowTitle     = title;
      tag->m_strOriginalTitle = title;
      tag->m_strPlotOutline   = subtitle;
      tag->m_strPlot          = program[i].description;
      // TODO: Strip out the subtitle from the description if it is present at the start?
      // TODO: Do we need to add the subtitle to the start of the plot if not already as it used to? Seems strange, should be handled by skin?
      tag->m_genre            = StringUtils::Split(program[i].category, g_advancedSettings.m_videoItemSeparator); // e.g. Sports
      tag->m_strAlbum         = program[i].callsign; // e.g. TV3

      CDateTime start(program[i].starttime);
      CDateTime end(program[i].endtime);
      CDateTimeSpan runtime = end - start;
      tag->m_duration         = runtime.GetSeconds() + runtime.GetMinutes() * 60 + runtime.GetHours() * 3600;
      tag->m_iSeason          = 0; // So XBMC treats the content as an episode and displays tag information.
      tag->m_iEpisode         = 0;

      items.Add(item);
    }
  }

  /*
   * Items are sorted as added to the list (in ascending date order). Specifying sorting by date can
   * result in the guide being shown in the wrong order for skins that sort by date in descending
   * order by default with no option to change to ascending, e.g. Confluence.
   */
  items.AddSortMethod(SortByNone, 552 /* Date */, LABEL_MASKS("%K", "%J")); // Still leave the date label

  m_dll->ref_release(program);
  return true;
}
示例#8
0
void CGUIEPGGridContainerModel::Initialize(const std::unique_ptr<CFileItemList> &items, const CDateTime &gridStart, const CDateTime &gridEnd, int iRulerUnit, int iBlocksPerPage, float fBlockSize)
{
  if (!m_channelItems.empty())
  {
    CLog::LogF(LOGERROR, "Already initialized!");
    return;
  }

  ////////////////////////////////////////////////////////////////////////
  // Create programme & channel items
  m_programmeItems.reserve(items->Size());
  CFileItemPtr fileItem;
  int iLastChannelID = -1;
  ItemsPtr itemsPointer;
  itemsPointer.start = 0;
  CPVRChannelPtr channel;
  int j = 0;
  for (int i = 0; i < items->Size(); ++i)
  {
    fileItem = items->Get(i);
    if (!fileItem->HasEPGInfoTag() || !fileItem->GetEPGInfoTag()->HasChannel())
      continue;

    m_programmeItems.emplace_back(fileItem);

    channel = fileItem->GetEPGInfoTag()->Channel();
    if (!channel)
      continue;

    int iCurrentChannelID = channel->ChannelID();
    if (iCurrentChannelID != iLastChannelID)
    {
      if (j > 0)
      {
        itemsPointer.stop = j - 1;
        m_epgItemsPtr.emplace_back(itemsPointer);
        itemsPointer.start = j;
      }
      iLastChannelID = iCurrentChannelID;
      m_channelItems.emplace_back(CFileItemPtr(new CFileItem(channel)));
    }
    ++j;
  }
  if (!m_programmeItems.empty())
  {
    itemsPointer.stop = m_programmeItems.size() - 1;
    m_epgItemsPtr.emplace_back(itemsPointer);
  }

  /* check for invalid start and end time */
  if (gridStart >= gridEnd)
  {
    // default to start "now minus GRID_START_PADDING minutes" and end "start plus one page".
    m_gridStart = CDateTime::GetUTCDateTime() - CDateTimeSpan(0, 0, GetGridStartPadding(), 0);
    m_gridEnd = m_gridStart + CDateTimeSpan(0, 0, iBlocksPerPage * MINSPERBLOCK, 0);
  }
  else if (gridStart > (CDateTime::GetUTCDateTime() - CDateTimeSpan(0, 0, GetGridStartPadding(), 0)))
  {
    // adjust to start "now minus GRID_START_PADDING minutes".
    m_gridStart = CDateTime::GetUTCDateTime() - CDateTimeSpan(0, 0, GetGridStartPadding(), 0);
    m_gridEnd = gridEnd;
  }
  else
  {
    m_gridStart = gridStart;
    m_gridEnd = gridEnd;
  }

  // roundup
  m_gridStart = CDateTime(m_gridStart.GetYear(), m_gridStart.GetMonth(), m_gridStart.GetDay(), m_gridStart.GetHour(), m_gridStart.GetMinute() >= 30 ? 30 : 0, 0);
  m_gridEnd = CDateTime(m_gridEnd.GetYear(), m_gridEnd.GetMonth(), m_gridEnd.GetDay(), m_gridEnd.GetHour(), m_gridEnd.GetMinute() >= 30 ? 30 : 0, 0);

  ////////////////////////////////////////////////////////////////////////
  // Create ruler items
  CDateTime ruler;
  ruler.SetFromUTCDateTime(m_gridStart);
  CDateTime rulerEnd;
  rulerEnd.SetFromUTCDateTime(m_gridEnd);
  CFileItemPtr rulerItem(new CFileItem(ruler.GetAsLocalizedDate(true)));
  rulerItem->SetProperty("DateLabel", true);
  m_rulerItems.emplace_back(rulerItem);

  const CDateTimeSpan unit(0, 0, iRulerUnit * MINSPERBLOCK, 0);
  for (; ruler < rulerEnd; ruler += unit)
  {
    rulerItem.reset(new CFileItem(ruler.GetAsLocalizedTime("", false)));
    rulerItem->SetLabel2(ruler.GetAsLocalizedDate(true));
    m_rulerItems.emplace_back(rulerItem);
  }

  FreeItemsMemory();

  ////////////////////////////////////////////////////////////////////////
  // Create epg grid
  const CDateTimeSpan blockDuration(0, 0, MINSPERBLOCK, 0);
  const CDateTimeSpan gridDuration(m_gridEnd - m_gridStart);
  m_blocks = (gridDuration.GetDays() * 24 * 60 + gridDuration.GetHours() * 60 + gridDuration.GetMinutes()) / MINSPERBLOCK;
  if (m_blocks >= MAXBLOCKS)
    m_blocks = MAXBLOCKS;
  else if (m_blocks < iBlocksPerPage)
    m_blocks = iBlocksPerPage;

  m_gridIndex.reserve(m_channelItems.size());
  const std::vector<GridItem> blocks(m_blocks);

  for (size_t channel = 0; channel < m_channelItems.size(); ++channel)
  {
    m_gridIndex.emplace_back(blocks);

    CDateTime gridCursor(m_gridStart); //reset cursor for new channel
    unsigned long progIdx = m_epgItemsPtr[channel].start;
    unsigned long lastIdx = m_epgItemsPtr[channel].stop;
    int iEpgId            = m_programmeItems[progIdx]->GetEPGInfoTag()->EpgID();
    int itemSize          = 1; // size of the programme in blocks
    int savedBlock        = 0;
    CFileItemPtr item;
    CPVREpgInfoTagPtr tag;

    for (int block = 0; block < m_blocks; ++block)
    {
      while (progIdx <= lastIdx)
      {
        item = m_programmeItems[progIdx];
        tag = item->GetEPGInfoTag();

        // Note: Start block of an event is start-time-based calculated block + 1,
        //       unless start times matches exactly the begin of a block.

        if (tag->EpgID() != iEpgId || gridCursor < tag->StartAsUTC() || m_gridEnd <= tag->StartAsUTC())
          break;

        if (gridCursor < tag->EndAsUTC())
        {
          m_gridIndex[channel][block].item = item;
          m_gridIndex[channel][block].progIndex = progIdx;
          break;
        }

        progIdx++;
      }

      gridCursor += blockDuration;

      if (block == 0)
        continue;

      const CFileItemPtr prevItem(m_gridIndex[channel][block - 1].item);
      const CFileItemPtr currItem(m_gridIndex[channel][block].item);

      if (block == m_blocks - 1 || prevItem != currItem)
      {
        // special handling for last block.
        int blockDelta = -1;
        int sizeDelta = 0;
        if (block == m_blocks - 1 && prevItem == currItem)
        {
          itemSize++;
          blockDelta = 0;
          sizeDelta = 1;
        }

        if (prevItem)
        {
          m_gridIndex[channel][savedBlock].item->SetProperty("GenreType", prevItem->GetEPGInfoTag()->GenreType());
        }
        else
        {
          CPVREpgInfoTagPtr gapTag(CPVREpgInfoTag::CreateDefaultTag());
          gapTag->SetChannel(m_channelItems[channel]->GetPVRChannelInfoTag());
          CFileItemPtr gapItem(new CFileItem(gapTag));
          for (int i = block + blockDelta; i >= block - itemSize + sizeDelta; --i)
          {
            m_gridIndex[channel][i].item = gapItem;
          }
        }

        float fItemWidth = itemSize * fBlockSize;
        m_gridIndex[channel][savedBlock].originWidth = fItemWidth;
        m_gridIndex[channel][savedBlock].width = fItemWidth;

        itemSize = 1;
        savedBlock = block;

        // special handling for last block.
        if (block == m_blocks - 1 && prevItem != currItem)
        {
          if (currItem)
          {
            m_gridIndex[channel][savedBlock].item->SetProperty("GenreType", currItem->GetEPGInfoTag()->GenreType());
          }
          else
          {
            CPVREpgInfoTagPtr gapTag(CPVREpgInfoTag::CreateDefaultTag());
            gapTag->SetChannel(m_channelItems[channel]->GetPVRChannelInfoTag());
            CFileItemPtr gapItem(new CFileItem(gapTag));
            m_gridIndex[channel][block].item = gapItem;
          }

          m_gridIndex[channel][savedBlock].originWidth = fBlockSize; // size always 1 block here
          m_gridIndex[channel][savedBlock].width = fBlockSize;
        }
      }
      else
      {
        itemSize++;
      }
    }
  }
}
示例#9
0
bool CCMythSession::UpdateItem(CFileItem &item, cmyth_proginfo_t info)
{
  if(!info)
    return false;

  CVideoInfoTag* tag = item.GetVideoInfoTag();

  tag->m_strAlbum       = GetValue(m_dll->proginfo_chansign(info));
  tag->m_strShowTitle   = GetValue(m_dll->proginfo_title(info));
  tag->m_strPlotOutline = GetValue(m_dll->proginfo_subtitle(info));
  tag->m_strPlot        = GetValue(m_dll->proginfo_description(info));
  tag->m_strGenre       = GetValue(m_dll->proginfo_category(info));

  if(tag->m_strPlot.Left(tag->m_strPlotOutline.length()) != tag->m_strPlotOutline && !tag->m_strPlotOutline.IsEmpty())
      tag->m_strPlot = tag->m_strPlotOutline + '\n' + tag->m_strPlot;

  tag->m_strOriginalTitle = tag->m_strShowTitle;

  tag->m_strTitle = tag->m_strAlbum;
  if(tag->m_strShowTitle.length() > 0)
    tag->m_strTitle += " : " + tag->m_strShowTitle;

  CDateTimeSpan span = GetValue(m_dll->proginfo_rec_start(info)) - GetValue(m_dll->proginfo_rec_end(info));
  StringUtils::SecondsToTimeString(span.GetSeconds() +
                                   span.GetMinutes() * 60 +
                                   span.GetHours() * 3600, tag->m_strRuntime, TIME_FORMAT_GUESS);

  tag->m_iSeason  = 0; /* set this so xbmc knows it's a tv show */
  tag->m_iEpisode = 0;

  item.m_strTitle = GetValue(m_dll->proginfo_chanstr(info));
  item.m_dateTime = GetValue(m_dll->proginfo_rec_start(info));
  item.m_dwSize   = m_dll->proginfo_length(info);

  if(m_dll->proginfo_rec_status(info) == RS_RECORDING)
  {
    tag->m_strStatus = "livetv";

    CStdString temp;

    temp = GetValue(m_dll->proginfo_chanicon(info));
    if(temp.length() > 0)
    {
      CURI url(item.m_strPath);
      url.SetFileName("files/channels/" + temp);
      temp = url.Get();
      item.SetThumbnailImage(temp);
    }

    temp = GetValue(m_dll->proginfo_chanstr(info));
    if(temp.length() > 0)
    {
      CURI url(item.m_strPath);
      url.SetFileName("channels/" + temp + ".ts");
      temp = url.Get();
      if(item.m_strPath != temp)
        item.m_strPath = temp;
    }
    item.SetCachedVideoThumb();
  }

  return true;
}
示例#10
0
static int GetTotalSeconds(const CDateTimeSpan& ts)
{
  int hours = ts.GetHours() + ts.GetDays() * 24;
  int minutes = ts.GetMinutes() + hours * 60;
  return ts.GetSeconds() + minutes * 60;
}
示例#11
0
bool CCMythDirectory::GetGuideForChannel(const CStdString& base, CFileItemList &items, int channelNumber)
{
  cmyth_database_t database = m_session->GetDatabase();
  if (!database)
  {
    CLog::Log(LOGERROR, "%s - Could not get database", __FUNCTION__);
    return false;
  }

  time_t now;
  time(&now);
  // this sets how many seconds of EPG from now we should grab
  time_t end = now + (1 * 24 * 60 * 60);

  cmyth_program_t *program = NULL;

  int count = m_dll->mysql_get_guide(database, &program, now, end);
  CLog::Log(LOGDEBUG, "%s - %i entries of guide data", __FUNCTION__, count);
  if (count <= 0)
    return false;

  for (int i = 0; i < count; i++)
  {
    if (program[i].channum == channelNumber)
    {
      CStdString path;
      path.Format("%s%s", base.c_str(), program[i].title);

      CDateTime starttime(program[i].starttime);
      CDateTime endtime(program[i].endtime);

      CStdString title;
      title.Format("%s - %s", starttime.GetAsLocalizedTime("HH:mm", false), program[i].title);

      CFileItemPtr item(new CFileItem(title, false));
      item->SetLabel(title);
      item->m_dateTime = starttime;

      CVideoInfoTag* tag = item->GetVideoInfoTag();

      tag->m_strAlbum       = GetValue(program[i].callsign);
      tag->m_strShowTitle   = GetValue(program[i].title);
      tag->m_strPlotOutline = GetValue(program[i].subtitle);
      tag->m_strPlot        = GetValue(program[i].description);
      tag->m_strGenre       = GetValue(program[i].category);

      if(tag->m_strPlot.Left(tag->m_strPlotOutline.length()) != tag->m_strPlotOutline && !tag->m_strPlotOutline.IsEmpty())
          tag->m_strPlot = tag->m_strPlotOutline + '\n' + tag->m_strPlot;
      tag->m_strOriginalTitle = tag->m_strShowTitle;

      tag->m_strTitle = tag->m_strAlbum;
      if(tag->m_strShowTitle.length() > 0)
        tag->m_strTitle += " : " + tag->m_strShowTitle;

      CDateTimeSpan runtime = endtime - starttime;
      StringUtils::SecondsToTimeString( runtime.GetSeconds()
                                      + runtime.GetMinutes() * 60
                                      + runtime.GetHours() * 3600, tag->m_strRuntime);

      tag->m_iSeason  = 0; /* set this so xbmc knows it's a tv show */
      tag->m_iEpisode = 0;
      tag->m_strStatus = program[i].rec_status;
      items.Add(item);
    }
  }

  // Sort by date only.
  items.AddSortMethod(SORT_METHOD_DATE, 552 /* Date */, LABEL_MASKS("%L", "%J", "%L", ""));

  m_dll->ref_release(program);
  return true;
}