Example #1
0
bool CPVRClients::SwitchChannel(const CPVRChannelPtr &channel)
{
  assert(channel.get());

  {
    CSingleLock lock(m_critSection);
    if (m_bIsSwitchingChannels)
    {
      CLog::Log(LOGDEBUG, "PVRClients - %s - can't switch to channel '%s'. waiting for the previous switch to complete", __FUNCTION__, channel->ChannelName().c_str());
      return false;
    }
    m_bIsSwitchingChannels = true;
  }

  bool bSwitchSuccessful(false);
  CPVRChannelPtr currentChannel(GetPlayingChannel());
  if (// no channel is currently playing
      !currentChannel ||
      // different backend
      currentChannel->ClientID() != channel->ClientID() ||
      // stream URL should always be opened as a new file
      !channel->StreamURL().empty() || !currentChannel->StreamURL().empty())
  {
    if (channel->StreamURL().empty())
    {
      CloseStream();
      bSwitchSuccessful = OpenStream(channel, true);
    }
    else
    {
      CFileItem m_currentFile(channel);
      CApplicationMessenger::Get().PlayFile(m_currentFile, false);
      bSwitchSuccessful = true;
    }
  }
  // same channel
  else if (currentChannel && currentChannel == channel)
  {
    bSwitchSuccessful = true;
  }
  else
  {
    PVR_CLIENT client;
    if (GetConnectedClient(channel->ClientID(), client))
      bSwitchSuccessful = client->SwitchChannel(channel);
  }

  {
    CSingleLock lock(m_critSection);
    m_bIsSwitchingChannels = false;
  }

  if (!bSwitchSuccessful)
    CLog::Log(LOGERROR, "PVR - %s - cannot switch to channel '%s' on client '%d'",__FUNCTION__, channel->ChannelName().c_str(), channel->ClientID());

  return bSwitchSuccessful;
}
Example #2
0
bool CPVRClient::OpenStream(const CPVRChannelPtr &channel, bool bIsSwitchingChannel)
{
  bool bReturn(false);
  CloseStream();

  if(!CanPlayChannel(channel))
  {
    CLog::Log(LOGDEBUG, "add-on '%s' can not play channel '%s'", GetFriendlyName().c_str(), channel->ChannelName().c_str());
  }
  else if (!channel->StreamURL().empty())
  {
    CLog::Log(LOGDEBUG, "opening live stream on url '%s'", channel->StreamURL().c_str());
    bReturn = true;

    // the Njoy N7 sometimes doesn't switch channels, but opens a stream to the previous channel
    // when not waiting for a short period.
    // added in 1.1.0
    AddonVersion checkVersion("1.1.0");
    if (m_apiVersion >= checkVersion)
    {
      unsigned int iWaitTimeMs = m_pStruct->GetChannelSwitchDelay();
      if (iWaitTimeMs > 0)
        XbmcThreads::ThreadSleep(iWaitTimeMs);
    }
  }
  else
  {
    CLog::Log(LOGDEBUG, "opening live stream for channel '%s'", channel->ChannelName().c_str());
    PVR_CHANNEL tag;
    WriteClientChannelInfo(channel, tag);

    try
    {
      bReturn = m_pStruct->OpenLiveStream(tag);
    }
    catch (std::exception &e) { LogException(e, __FUNCTION__); }
  }

  if (bReturn)
  {
    CPVRChannelPtr currentChannel(g_PVRChannelGroups->GetByUniqueID(channel->UniqueID(), channel->ClientID()));
    CSingleLock lock(m_critSection);
    m_playingChannel      = currentChannel;
    m_bIsPlayingTV        = true;
    m_bIsPlayingRecording = false;
  }

  return bReturn;
}
Example #3
0
bool CPVRChannel::UpdateFromClient(const CPVRChannelPtr &channel)
{
  assert(channel.get());

  SetClientID(channel->ClientID());
  SetStreamURL(channel->StreamURL());

  CSingleLock lock(m_critSection);

  if (m_iClientChannelNumber.channel    != channel->ClientChannelNumber() ||
      m_iClientChannelNumber.subchannel != channel->ClientSubChannelNumber() ||
      m_strInputFormat                  != channel->InputFormat() ||
      m_iClientEncryptionSystem         != channel->EncryptionSystem() ||
      m_strClientChannelName            != channel->ClientChannelName())
  {
    m_iClientChannelNumber.channel    = channel->ClientChannelNumber();
    m_iClientChannelNumber.subchannel = channel->ClientSubChannelNumber();
    m_strInputFormat                  = channel->InputFormat();
    m_iClientEncryptionSystem         = channel->EncryptionSystem();
    m_strClientChannelName            = channel->ClientChannelName();

    UpdateEncryptionName();
    SetChanged();
  }

  // only update the channel name and icon if the user hasn't changed them manually
  if (m_strChannelName.empty() || !IsUserSetName())
    SetChannelName(channel->ClientChannelName());
  if (m_strIconPath.empty() || !IsUserSetIcon())
    SetIconPath(channel->IconPath());

  return m_bChanged;
}
Example #4
0
/*!
 * @brief Copy over channel info from xbmcChannel to addonClient.
 * @param xbmcChannel The channel on XBMC's side.
 * @param addonChannel The channel on the addon's side.
 */
void CPVRClient::WriteClientChannelInfo(const CPVRChannelPtr &xbmcChannel, PVR_CHANNEL &addonChannel)
{
  assert(xbmcChannel.get());

  memset(&addonChannel, 0, sizeof(addonChannel));

  addonChannel.iUniqueId         = xbmcChannel->UniqueID();
  addonChannel.iChannelNumber    = xbmcChannel->ClientChannelNumber();
  addonChannel.iSubChannelNumber = xbmcChannel->ClientSubChannelNumber();
  strncpy(addonChannel.strChannelName, xbmcChannel->ClientChannelName().c_str(), sizeof(addonChannel.strChannelName) - 1);
  strncpy(addonChannel.strIconPath, xbmcChannel->IconPath().c_str(), sizeof(addonChannel.strIconPath) - 1);
  addonChannel.iEncryptionSystem = xbmcChannel->EncryptionSystem();
  addonChannel.bIsRadio          = xbmcChannel->IsRadio();
  addonChannel.bIsHidden         = xbmcChannel->IsHidden();
  strncpy(addonChannel.strInputFormat, xbmcChannel->InputFormat().c_str(), sizeof(addonChannel.strInputFormat) - 1);
  strncpy(addonChannel.strStreamURL, xbmcChannel->StreamURL().c_str(), sizeof(addonChannel.strStreamURL) - 1);
}
Example #5
0
bool CGUIDialogPVRGuideInfo::OnClickButtonPlay(CGUIMessage &message)
{
  bool bReturn = false;

  if (message.GetSenderId() == CONTROL_BTN_SWITCH || message.GetSenderId() == CONTROL_BTN_PLAY_RECORDING)
  {
    Close();
    PlayBackRet ret = PLAYBACK_CANCELED;
    CEpgInfoTagPtr epgTag(m_progItem->GetEPGInfoTag());

    if (epgTag)
    {
      if (message.GetSenderId() == CONTROL_BTN_PLAY_RECORDING && epgTag->HasRecording())
        ret = g_application.PlayFile(CFileItem(epgTag->Recording()), "videoplayer");
      else if (epgTag->HasPVRChannel())
      {
        CPVRChannelPtr channel = epgTag->ChannelTag();
        // try a fast switch
        bool bSwitchSuccessful = false;
        if ((g_PVRManager.IsPlayingTV() || g_PVRManager.IsPlayingRadio()) &&
            (channel->IsRadio() == g_PVRManager.IsPlayingRadio()))
        {
          if (channel->StreamURL().empty())
            bSwitchSuccessful = g_application.m_pPlayer->SwitchChannel(channel);
        }

        if (!bSwitchSuccessful)
        {
          CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(new CFileItem(channel)), "videoplayer");
        }
      }
    }
    bReturn = true;
  }

  return bReturn;
}
Example #6
0
bool CGUIWindowPVRBase::PlayFile(CFileItem *item, bool bPlayMinimized /* = false */, bool bCheckResume /* = true */)
{
  if (item->m_bIsFolder)
  {
    return false;
  }

  CPVRChannelPtr channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : CPVRChannelPtr();
  if (item->GetPath() == g_application.CurrentFile() ||
      (channel && channel->HasRecording() && channel->GetRecording()->GetPath() == g_application.CurrentFile()))
  {
    CGUIMessage msg(GUI_MSG_FULLSCREEN, 0, GetID());
    g_windowManager.SendMessage(msg);
    return true;
  }

  CMediaSettings::GetInstance().SetVideoStartWindowed(bPlayMinimized);

  if (item->HasPVRRecordingInfoTag())
  {
    return PlayRecording(item, bPlayMinimized, bCheckResume);
  }
  else
  {
    bool bSwitchSuccessful(false);
    CPVRChannelPtr channel(item->GetPVRChannelInfoTag());

    if (channel && g_PVRManager.CheckParentalLock(channel))
    {
      CPVRRecordingPtr recording = channel->GetRecording();
      if (recording)
      {
        CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*) g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
        if (pDialog)
        {
          pDialog->SetHeading(CVariant{19687}); // Play recording
          pDialog->SetLine(0, CVariant{""});
          pDialog->SetLine(1, CVariant{12021}); // Start from beginning
          pDialog->SetLine(2, CVariant{recording->m_strTitle});
          pDialog->Open();

          if (pDialog->IsConfirmed())
          {
            CFileItem recordingItem(recording);
            return PlayRecording(&recordingItem, CSettings::GetInstance().GetBool(CSettings::SETTING_PVRPLAYBACK_PLAYMINIMIZED), bCheckResume);
          }
        }
      }

      /* try a fast switch */
      if ((g_PVRManager.IsPlayingTV() || g_PVRManager.IsPlayingRadio()) &&
         (channel->IsRadio() == g_PVRManager.IsPlayingRadio()))
      {
        if (channel->StreamURL().empty())
          bSwitchSuccessful = g_application.m_pPlayer->SwitchChannel(channel);
      }

      if (!bSwitchSuccessful)
      {
        CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(new CFileItem(*item)));
        return true;
      }
    }

    if (!bSwitchSuccessful)
    {
      std::string channelName = g_localizeStrings.Get(19029); // Channel
      if (channel)
        channelName = channel->ChannelName();
      std::string msg = StringUtils::Format(g_localizeStrings.Get(19035).c_str(), channelName.c_str()); // CHANNELNAME could not be played. Check the log for details.

      CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error,
              g_localizeStrings.Get(19166), // PVR information
              msg);
      return false;
    }
  }

  return true;
}
Example #7
0
  bool CPVRGUIActions::SwitchToChannel(const CFileItemPtr &item, bool bPlayMinimized, bool bCheckResume) const
  {
    if (item->m_bIsFolder)
      return false;

    const CPVRChannelPtr channel(CPVRItem(item).GetChannel());
    if ((channel && g_PVRManager.IsPlayingChannel(channel)) ||
        (channel && channel->HasRecording() && g_PVRManager.IsPlayingRecording(channel->GetRecording())))
    {
      CGUIMessage msg(GUI_MSG_FULLSCREEN, 0, g_windowManager.GetActiveWindow());
      g_windowManager.SendMessage(msg);
      return true;
    }

    CMediaSettings::GetInstance().SetVideoStartWindowed(bPlayMinimized);

    // switch to channel or if recording present, ask whether to switch or play recording...
    bool bSwitchSuccessful(false);

    if (channel && g_PVRManager.CheckParentalLock(channel))
    {
      const CPVRRecordingPtr recording(channel->GetRecording());
      if (recording)
      {
        bool bCancel(false);
        bool bPlayRecording = CGUIDialogYesNo::ShowAndGetInput(CVariant{19687}, // "Play recording"
                                                       CVariant{""},
                                                       CVariant{12021}, // "Play from beginning"
                                                       CVariant{recording->m_strTitle},
                                                       bCancel,
                                                       CVariant{19000}, // "Switch to channel"
                                                       CVariant{19687}, // "Play recording"
                                                       0); // no autoclose
        if (bCancel)
          return false;

        if (bPlayRecording)
        {
          const CFileItemPtr recordingItem(new CFileItem(recording));
          return PlayRecording(recordingItem, CServiceBroker::GetSettings().GetBool(CSettings::SETTING_PVRPLAYBACK_PLAYMINIMIZED), bCheckResume);
        }
      }

      /* try a fast switch */
      if ((g_PVRManager.IsPlayingTV() || g_PVRManager.IsPlayingRadio()) &&
          (channel->IsRadio() == g_PVRManager.IsPlayingRadio()))
      {
        if (channel->StreamURL().empty())
          bSwitchSuccessful = g_application.m_pPlayer->SwitchChannel(channel);
      }

      if (!bSwitchSuccessful)
      {
        CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(new CFileItem(channel)));
        return true;
      }
    }

    if (!bSwitchSuccessful)
    {
      std::string channelName = g_localizeStrings.Get(19029); // Channel
      if (channel)
        channelName = channel->ChannelName();
      std::string msg = StringUtils::Format(g_localizeStrings.Get(19035).c_str(), channelName.c_str()); // CHANNELNAME could not be played. Check the log for details.

      CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(19166), msg); // PVR information
      return false;
    }

    return true;
  }