void CGUIDialogPVRTimerSettings::InitializeChannelsList() { m_channelEntries.clear(); CFileItemList channelsList; g_PVRChannelGroups->GetGroupAll(m_bIsRadio)->GetMembers(channelsList); for (int i = 0; i < channelsList.Size(); ++i) { const CPVRChannelPtr channel(channelsList[i]->GetPVRChannelInfoTag()); std::string channelDescription( StringUtils::Format("%i %s", channel->ChannelNumber(), channel->ChannelName().c_str())); m_channelEntries.insert( std::make_pair(i, ChannelDescriptor(channel->UniqueID(), channel->ClientID(), channelDescription))); } // Add special "any channel" entry (used for epg-based repeating timers). m_channelEntries.insert( std::make_pair( ENTRY_ANY_CHANNEL, ChannelDescriptor(PVR_CHANNEL_INVALID_UID, 0, g_localizeStrings.Get(809)))); }
CPVRTimerInfoTagPtr CPVRTimerInfoTag::CreateFromEpg(const CEpgInfoTagPtr &tag) { /* create a new timer */ CPVRTimerInfoTagPtr newTag(new CPVRTimerInfoTag()); if (!newTag) { CLog::Log(LOGERROR, "%s - couldn't create new timer", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* check if a valid channel is set */ CPVRChannelPtr channel = tag->ChannelTag(); if (!channel) { CLog::Log(LOGERROR, "%s - no channel set", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* check if the epg end date is in the future */ if (tag->EndAsLocalTime() < CDateTime::GetCurrentDateTime()) { CLog::Log(LOGERROR, "%s - end time is in the past", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* set the timer data */ CDateTime newStart = tag->StartAsUTC(); CDateTime newEnd = tag->EndAsUTC(); newTag->m_iClientIndex = -1; newTag->m_strTitle = tag->Title().empty() ? channel->ChannelName() : tag->Title(); newTag->m_iChannelNumber = channel->ChannelNumber(); newTag->m_iClientChannelUid = channel->UniqueID(); newTag->m_iClientId = channel->ClientID(); newTag->m_bIsRadio = channel->IsRadio(); newTag->m_iGenreType = tag->GenreType(); newTag->m_iGenreSubType = tag->GenreSubType(); newTag->m_channel = channel; newTag->SetStartFromUTC(newStart); newTag->SetEndFromUTC(newEnd); if (tag->Plot().empty()) { newTag->m_strSummary= StringUtils::Format("%s %s %s %s %s", newTag->StartAsLocalTime().GetAsLocalizedDate().c_str(), g_localizeStrings.Get(19159).c_str(), newTag->StartAsLocalTime().GetAsLocalizedTime("", false).c_str(), g_localizeStrings.Get(19160).c_str(), newTag->EndAsLocalTime().GetAsLocalizedTime("", false).c_str()); } else { newTag->m_strSummary = tag->Plot(); } newTag->m_epgTag = g_EpgContainer.GetById(tag->EpgID())->GetTag(tag->StartAsUTC()); /* unused only for reference */ newTag->m_strFileNameAndPath = "pvr://timers/new"; return newTag; }
void CGUIDialogPVRChannelManager::Update() { // lock our display, as this window is rendered from the player thread g_graphicsContext.Lock(); m_viewControl.SetCurrentView(CONTROL_LIST_CHANNELS); // empty the lists ready for population Clear(); CPVRChannelGroupPtr channels = g_PVRChannelGroups->GetGroupAll(m_bIsRadio); // No channels available, nothing to do. if(!channels) return; std::vector<PVRChannelGroupMember> groupMembers(channels->GetMembers()); CFileItemPtr channelFile; for (std::vector<PVRChannelGroupMember>::const_iterator it = groupMembers.begin(); it != groupMembers.end(); ++it) { channelFile = CFileItemPtr(new CFileItem((*it).channel)); if (!channelFile || !channelFile->HasPVRChannelInfoTag()) continue; const CPVRChannelPtr channel(channelFile->GetPVRChannelInfoTag()); channelFile->SetProperty("ActiveChannel", !channel->IsHidden()); channelFile->SetProperty("Name", channel->ChannelName()); channelFile->SetProperty("UseEPG", channel->EPGEnabled()); channelFile->SetProperty("Icon", channel->IconPath()); channelFile->SetProperty("EPGSource", (int)0); channelFile->SetProperty("ParentalLocked", channel->IsLocked()); channelFile->SetProperty("Number", StringUtils::Format("%i", channel->ChannelNumber())); std::string clientName; g_PVRClients->GetClientName(channel->ClientID(), clientName); channelFile->SetProperty("ClientName", clientName); channelFile->SetProperty("SupportsSettings", g_PVRClients->SupportsChannelSettings(channel->ClientID())); m_channelItems->Add(channelFile); } { std::vector< std::pair<std::string, int> > labels; labels.push_back(std::make_pair(g_localizeStrings.Get(19210), 0)); /// TODO: Add Labels for EPG scrapers here SET_CONTROL_LABELS(SPIN_EPGSOURCE_SELECTION, 0, &labels); } m_clientsWithSettingsList = g_PVRClients->GetClientsSupportingChannelSettings(m_bIsRadio); if (!m_clientsWithSettingsList.empty()) m_bAllowNewChannel = true; if (m_bAllowNewChannel) SET_CONTROL_VISIBLE(BUTTON_NEW_CHANNEL); else SET_CONTROL_HIDDEN(BUTTON_NEW_CHANNEL); Renumber(); m_viewControl.SetItems(*m_channelItems); m_viewControl.SetSelectedItem(m_iSelected); g_graphicsContext.Unlock(); }
CPVRTimerInfoTagPtr CPVRTimerInfoTag::CreateFromEpg(const CEpgInfoTagPtr &tag, bool bCreateRule /* = false */) { /* create a new timer */ CPVRTimerInfoTagPtr newTag(new CPVRTimerInfoTag()); /* check if a valid channel is set */ CPVRChannelPtr channel = tag->ChannelTag(); if (!channel) { CLog::Log(LOGERROR, "%s - no channel set", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* check if the epg end date is in the future */ if (tag->EndAsLocalTime() < CDateTime::GetCurrentDateTime() && !bCreateRule) { CLog::Log(LOGERROR, "%s - end time is in the past", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* set the timer data */ CDateTime newStart = tag->StartAsUTC(); CDateTime newEnd = tag->EndAsUTC(); newTag->m_iClientIndex = PVR_TIMER_NO_CLIENT_INDEX; newTag->m_iParentClientIndex = PVR_TIMER_NO_PARENT; newTag->m_strTitle = tag->Title().empty() ? channel->ChannelName() : tag->Title(); newTag->m_iChannelNumber = channel->ChannelNumber(); newTag->m_iClientChannelUid = channel->UniqueID(); newTag->m_iClientId = channel->ClientID(); newTag->m_bIsRadio = channel->IsRadio(); newTag->m_channel = channel; newTag->m_iEpgUid = tag->UniqueBroadcastID(); newTag->SetStartFromUTC(newStart); newTag->SetEndFromUTC(newEnd); CPVRTimerTypePtr timerType; if (bCreateRule) { // create epg-based timer rule timerType = CPVRTimerType::CreateFromAttributes( PVR_TIMER_TYPE_IS_REPEATING, PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES, channel->ClientID()); if (timerType) { if (timerType->SupportsEpgTitleMatch()) newTag->m_strEpgSearchString = newTag->m_strTitle; if (timerType->SupportsWeekdays()) newTag->m_iWeekdays = PVR_WEEKDAY_ALLDAYS; if (timerType->SupportsStartAnyTime()) newTag->m_bStartAnyTime = true; if (timerType->SupportsEndAnyTime()) newTag->m_bEndAnyTime = true; } } else { // create one-shot epg-based timer timerType = CPVRTimerType::CreateFromAttributes( PVR_TIMER_TYPE_ATTRIBUTE_NONE, PVR_TIMER_TYPE_IS_REPEATING | PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES, channel->ClientID()); } if (!timerType) { CLog::Log(LOGERROR, "%s - unable to create any epg-based timer type", __FUNCTION__); return CPVRTimerInfoTagPtr(); } newTag->SetTimerType(timerType); newTag->UpdateSummary(); newTag->UpdateEpgInfoTag(); /* unused only for reference */ newTag->m_strFileNameAndPath = CPVRTimersPath::PATH_NEW; return newTag; }
bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPreview) { assert(channel.get()); // check parental lock state if (IsParentalLocked(channel)) return false; // invalid channel if (channel->ClientID() < 0) return false; // check whether we're waiting for a previous switch to complete { CSingleLock lock(m_critSection); if (m_bIsSwitchingChannels) { CLog::Log(LOGDEBUG, "PVRManager - %s - can't switch to channel '%s'. waiting for the previous switch to complete", __FUNCTION__, channel->ChannelName().c_str()); return false; } // no need to do anything except switching m_currentFile if (bPreview) { delete m_currentFile; m_currentFile = new CFileItem(channel); return true; } m_bIsSwitchingChannels = true; } CLog::Log(LOGDEBUG, "PVRManager - %s - switching to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); // will be deleted by CPVRChannelSwitchJob::DoWork() CFileItem* previousFile = m_currentFile; m_currentFile = NULL; bool bSwitched(false); // switch channel if (!m_addons->SwitchChannel(channel)) { // switch failed CSingleLock lock(m_critSection); m_bIsSwitchingChannels = false; CLog::Log(LOGERROR, "PVRManager - %s - failed to switch to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); std::string msg = StringUtils::Format(g_localizeStrings.Get(19035).c_str(), channel->ChannelName().c_str()); // CHANNELNAME could not be played. Check the log for details. CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(19166), // PVR information msg); } else { // switch successful bSwitched = true; // save previous and load new channel's settings (view mode is updated in // the player) g_application.SaveFileState(); g_application.LoadVideoSettings(channel); // set channel as selected item CGUIWindowPVRBase::SetSelectedItemPath(channel->IsRadio(), channel->Path()); UpdateLastWatched(channel); CSingleLock lock(m_critSection); m_currentFile = new CFileItem(channel); m_bIsSwitchingChannels = false; CLog::Log(LOGNOTICE, "PVRManager - %s - switched to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); } // announce OnStop and OnPlay. yes, this ain't pretty { CSingleLock lock(m_critSectionTriggers); m_pendingUpdates.push_back(new CPVRChannelSwitchJob(previousFile, m_currentFile)); } m_triggerEvent.Set(); return bSwitched; }
CPVRTimerInfoTagPtr CPVRTimerInfoTag::CreateInstantTimerTag(const CPVRChannelPtr &channel, int iDuration /* = DEFAULT_PVRRECORD_INSTANTRECORDTIME */) { if (!channel) { CLog::Log(LOGERROR, "%s - no channel set", __FUNCTION__); return CPVRTimerInfoTagPtr(); } CEpgInfoTagPtr epgTag(channel->GetEPGNow()); CPVRTimerInfoTagPtr newTimer; if (epgTag) newTimer = CreateFromEpg(epgTag); if (!newTimer) { newTimer.reset(new CPVRTimerInfoTag); newTimer->m_iClientIndex = PVR_TIMER_NO_CLIENT_INDEX; newTimer->m_iParentClientIndex = PVR_TIMER_NO_PARENT; newTimer->m_channel = channel; newTimer->m_strTitle = channel->ChannelName(); newTimer->m_iChannelNumber = channel->ChannelNumber(); newTimer->m_iClientChannelUid = channel->UniqueID(); newTimer->m_iClientId = channel->ClientID(); newTimer->m_bIsRadio = channel->IsRadio(); // timertype: manual one-shot timer for given client CPVRTimerTypePtr timerType(CPVRTimerType::CreateFromAttributes( PVR_TIMER_TYPE_IS_MANUAL, PVR_TIMER_TYPE_IS_REPEATING | PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES, channel->ClientID())); if (!timerType) { CLog::Log(LOGERROR, "%s - unable to create one shot manual timer type", __FUNCTION__); return CPVRTimerInfoTagPtr(); } newTimer->SetTimerType(timerType); } /* no matter the timer was created from an epg tag, overwrite timer start and end times. */ CDateTime now(CDateTime::GetUTCDateTime()); newTimer->SetStartFromUTC(now); if (iDuration == DEFAULT_PVRRECORD_INSTANTRECORDTIME) iDuration = CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDTIME); CDateTime endTime = now + CDateTimeSpan(0, 0, iDuration ? iDuration : 120, 0); newTimer->SetEndFromUTC(endTime); /* update summary string according to instant recording start/end time */ newTimer->UpdateSummary(); newTimer->m_strSummary = StringUtils::Format(g_localizeStrings.Get(19093).c_str(), newTimer->Summary().c_str()); CDateTime startTime(INSTANT_TIMER_START); newTimer->SetStartFromUTC(startTime); newTimer->m_iMarginStart = 0; newTimer->m_iMarginEnd = 0; /* set epg tag at timer & timer at epg tag */ newTimer->UpdateEpgInfoTag(); /* unused only for reference */ newTimer->m_strFileNameAndPath = CPVRTimersPath::PATH_NEW; return newTimer; }
bool CPVRDatabase::PersistChannels(CPVRChannelGroup &group) { bool bReturn(true); CPVRChannelPtr channel; for (const auto& groupMember : group.m_members) { channel = groupMember.second.channel; if (channel->IsChanged() || channel->IsNew()) { if (Persist(*channel, false)) { groupMember.second.channel->Persisted(); bReturn = true; } } } bReturn &= CommitInsertQueries(); if (bReturn) { std::string strQuery; std::string strValue; for (const auto& groupMember : group.m_members) { channel = groupMember.second.channel; strQuery = PrepareSQL("iUniqueId = %u AND iClientId = %u", channel->UniqueID(), channel->ClientID()); strValue = GetSingleValue("channels", "idChannel", strQuery); if (!strValue.empty() && StringUtils::IsInteger(strValue)) channel->SetChannelID(atoi(strValue.c_str())); } } return bReturn; }
CPVRTimerInfoTagPtr CPVRTimerInfoTag::CreateFromEpg(const CEpgInfoTagPtr &tag, bool bRepeating /* = false */) { /* create a new timer */ CPVRTimerInfoTagPtr newTag(new CPVRTimerInfoTag()); /* check if a valid channel is set */ CPVRChannelPtr channel = tag->ChannelTag(); if (!channel) { CLog::Log(LOGERROR, "%s - no channel set", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* check if the epg end date is in the future */ if (tag->EndAsLocalTime() < CDateTime::GetCurrentDateTime()) { CLog::Log(LOGERROR, "%s - end time is in the past", __FUNCTION__); return CPVRTimerInfoTagPtr(); } /* set the timer data */ CDateTime newStart = tag->StartAsUTC(); CDateTime newEnd = tag->EndAsUTC(); newTag->m_iClientIndex = -1; newTag->m_iParentClientIndex = PVR_TIMER_NO_PARENT; newTag->m_strTitle = tag->Title().empty() ? channel->ChannelName() : tag->Title(); newTag->m_iChannelNumber = channel->ChannelNumber(); newTag->m_iClientChannelUid = channel->UniqueID(); newTag->m_iClientId = channel->ClientID(); newTag->m_bIsRadio = channel->IsRadio(); newTag->m_iGenreType = tag->GenreType(); newTag->m_iGenreSubType = tag->GenreSubType(); newTag->m_channel = channel; newTag->SetStartFromUTC(newStart); newTag->SetEndFromUTC(newEnd); CPVRTimerTypePtr timerType; if (bRepeating) { // create repeating epg-based timer timerType = CPVRTimerType::CreateFromAttributes( PVR_TIMER_TYPE_IS_REPEATING, PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES, channel->ClientID()); } if (!timerType) { // create one-shot epg-based timer timerType = CPVRTimerType::CreateFromAttributes( PVR_TIMER_TYPE_ATTRIBUTE_NONE, PVR_TIMER_TYPE_IS_REPEATING | PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES, channel->ClientID()); } if (!timerType) { CLog::Log(LOGERROR, "%s - unable to create any epg-based timer type", __FUNCTION__); return CPVRTimerInfoTagPtr(); } newTag->SetTimerType(timerType); newTag->UpdateSummary(); newTag->m_epgTag = g_EpgContainer.GetById(tag->EpgID())->GetTag(tag->StartAsUTC()); /* unused only for reference */ newTag->m_strFileNameAndPath = CPVRTimersPath::PATH_NEW; return newTag; }
void CGUIDialogPVRTimerSettings::OnSettingChanged(const CSetting *setting) { if (setting == NULL) return; CGUIDialogSettingsManualBase::OnSettingChanged(setting); CPVRTimerInfoTag* tag = m_timerItem->GetPVRTimerInfoTag(); if (tag == NULL) return; const std::string &settingId = setting->GetId(); if (settingId == SETTING_TMR_ACTIVE) m_bTimerActive = static_cast<const CSettingBool*>(setting)->GetValue(); if (settingId == SETTING_TMR_RADIO || settingId == SETTING_TMR_CHNAME_TV || settingId == SETTING_TMR_CHNAME_RADIO) { if (settingId == SETTING_TMR_RADIO) { tag->m_bIsRadio = static_cast<const CSettingBool*>(setting)->GetValue(); m_selectedChannelEntry = 0; } else m_selectedChannelEntry = static_cast<const CSettingInt*>(setting)->GetValue(); std::map<std::pair<bool, int>, int>::iterator itc = m_channelEntries.find(std::make_pair(tag->m_bIsRadio, m_selectedChannelEntry)); if (itc != m_channelEntries.end()) { CPVRChannelPtr channel = g_PVRChannelGroups->GetChannelById(itc->second); if (channel) { tag->m_iClientChannelUid = channel->UniqueID(); tag->m_iClientId = channel->ClientID(); tag->m_bIsRadio = channel->IsRadio(); tag->m_iChannelNumber = channel->ChannelNumber(); } else { tag->m_iClientChannelUid = PVR_VIRTUAL_CHANNEL_UID; tag->m_iClientId = PVR_VIRTUAL_CLIENT_ID; tag->m_iChannelNumber = 0; } // Update channel pointer from above values tag->UpdateChannel(); } } else if (settingId == SETTING_TMR_DAY) { m_tmp_day = static_cast<const CSettingInt*>(setting)->GetValue(); if (m_tmp_day <= 10) SetTimerFromWeekdaySetting(*tag); else { CDateTime time = CDateTime::GetCurrentDateTime(); CDateTime timestart = m_timerStartTime; CDateTime timestop = m_timerEndTime; int m_tmp_diff; // get diffence of timer in days between today and timer start date tm time_cur; time.GetAsTm(time_cur); tm time_tmr; timestart.GetAsTm(time_tmr); m_tmp_diff = time_tmr.tm_yday - time_cur.tm_yday; if (time_tmr.tm_yday - time_cur.tm_yday < 0) m_tmp_diff = 365; CDateTime newStart = timestart + CDateTimeSpan(m_tmp_day - 11 - m_tmp_diff, 0, 0, 0); CDateTime newEnd = timestop + CDateTimeSpan(m_tmp_day - 11 - m_tmp_diff, 0, 0, 0); // add a day to end time if end time is before start time // TODO: this should be removed after separate end date control was added if (newEnd < newStart) newEnd += CDateTimeSpan(1, 0, 0, 0); tag->SetStartFromLocalTime(newStart); tag->SetEndFromLocalTime(newEnd); tag->m_bIsRepeating = false; tag->m_iWeekdays = 0; } } else if (settingId == SETTING_TMR_PRIORITY) tag->m_iPriority = static_cast<const CSettingInt*>(setting)->GetValue(); else if (settingId == SETTING_TMR_LIFETIME) tag->m_iLifetime = static_cast<const CSettingInt*>(setting)->GetValue(); else if (settingId == SETTING_TMR_FIRST_DAY) { m_tmp_iFirstDay = static_cast<const CSettingInt*>(setting)->GetValue(); CDateTime newFirstDay; if (m_tmp_iFirstDay > 0) newFirstDay = CDateTime::GetCurrentDateTime() + CDateTimeSpan(m_tmp_iFirstDay - 1, 0, 0, 0); tag->SetFirstDayFromLocalTime(newFirstDay); } else if (settingId == SETTING_TMR_NAME) tag->m_strTitle = static_cast<const CSettingString*>(setting)->GetValue(); else if (settingId == SETTING_TMR_DIR) tag->m_strDirectory = static_cast<const CSettingString*>(setting)->GetValue(); tag->UpdateSummary(); }
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; }
bool CPVRClient::SwitchChannel(const CPVRChannelPtr &channel) { bool bSwitched(false); if (IsPlayingLiveStream() && CanPlayChannel(channel)) { PVR_CHANNEL tag; WriteClientChannelInfo(channel, tag); try { bSwitched = m_pStruct->SwitchChannel(tag); } catch (std::exception &e) { LogException(e, __FUNCTION__); } } if (bSwitched) { CPVRChannelPtr currentChannel(g_PVRChannelGroups->GetByUniqueID(channel->UniqueID(), channel->ClientID())); CSingleLock lock(m_critSection); m_playingChannel = currentChannel; } return bSwitched; }
bool CPVRClient::SwitchChannel(const CPVRChannelPtr &channel) { bool bSwitched(false); if (IsPlayingLiveStream() && CanPlayChannel(channel)) { PVR_CHANNEL tag; WriteClientChannelInfo(channel, tag); bSwitched = m_struct.SwitchChannel(tag); } if (bSwitched) { CPVRChannelPtr currentChannel(CServiceBroker::GetPVRManager().ChannelGroups()->GetByUniqueID(channel->UniqueID(), channel->ClientID())); CSingleLock lock(m_critSection); m_playingChannel = currentChannel; } return bSwitched; }
bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPreview) { assert(channel.get()); // check parental lock state if (IsParentalLocked(channel)) return false; // invalid channel if (channel->ClientID() < 0) return false; // check whether we're waiting for a previous switch to complete CFileItemPtr previousFile; { CSingleLock lock(m_critSection); if (m_bIsSwitchingChannels) { CLog::Log(LOGDEBUG, "PVRManager - %s - can't switch to channel '%s'. waiting for the previous switch to complete", __FUNCTION__, channel->ChannelName().c_str()); return false; } if (bPreview) { if (!g_infoManager.GetShowInfo() && m_settings.GetIntValue(CSettings::SETTING_PVRPLAYBACK_CHANNELENTRYTIMEOUT) == 0) { // no need to do anything return true; } m_currentFile.reset(new CFileItem(channel)); if (IsPlayingChannel(channel)) m_isChannelPreview = false; else m_isChannelPreview = true; return true; } m_bIsSwitchingChannels = true; CLog::Log(LOGDEBUG, "PVRManager - %s - switching to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); previousFile = std::move(m_currentFile); } bool bSwitched(false); // switch channel if (!m_addons->SwitchChannel(channel)) { // switch failed CSingleLock lock(m_critSection); m_bIsSwitchingChannels = false; CLog::Log(LOGERROR, "PVRManager - %s - failed to switch to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); std::string msg = StringUtils::Format(g_localizeStrings.Get(19035).c_str(), channel->ChannelName().c_str()); // CHANNELNAME could not be played. Check the log for details. CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(19166), // PVR information msg); } else { // switch successful bSwitched = true; // save previous and load new channel's settings (view mode is updated in // the player) g_application.SaveFileState(); g_application.LoadVideoSettings(channel); // set channel as selected item CGUIWindowPVRBase::SetSelectedItemPath(channel->IsRadio(), channel->Path()); UpdateLastWatched(channel); CSingleLock lock(m_critSection); m_currentFile.reset(new CFileItem(channel)); m_bIsSwitchingChannels = false; CLog::Log(LOGNOTICE, "PVRManager - %s - switched to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); } // announce OnStop if (previousFile) { CVariant data(CVariant::VariantTypeObject); data["end"] = true; ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Player, "xbmc", "OnStop", previousFile, data); } // announce OnPlay if (m_currentFile) { CVariant param; param["player"]["speed"] = 1; param["player"]["playerid"] = CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist(); ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Player, "xbmc", "OnPlay", m_currentFile, param); } return bSwitched; }