From a8108ba2d3ee49111d7a09668fa127f1f860c0d5 Mon Sep 17 00:00:00 2001 From: Kai Sommerfeld Date: Thu, 31 Jan 2019 15:25:42 +0100 Subject: [PATCH] [PVR][videoplayer] Fix PVR input stream creation for pvr file items only containing a path and no recording/channel tag. Fixes broken recording playback using official Kodi Remote iOS app. --- xbmc/addons/PVRClient.cpp | 32 +++++++++++++++++-- xbmc/addons/PVRClient.h | 8 ++--- .../DVDInputStreams/DVDFactoryInputStream.cpp | 4 +-- .../DVDInputStreams/InputStreamPVRChannel.cpp | 2 +- .../InputStreamPVRRecording.cpp | 2 +- xbmc/pvr/PVRManager.cpp | 14 +++++++- 6 files changed, 51 insertions(+), 11 deletions(-) diff --git a/xbmc/addons/PVRClient.cpp b/xbmc/addons/PVRClient.cpp index 46fcf66687b60..c5b3fae92eea9 100644 --- a/xbmc/addons/PVRClient.cpp +++ b/xbmc/addons/PVRClient.cpp @@ -1218,8 +1218,22 @@ bool CPVRClient::CanPlayChannel(const CPVRChannelPtr &channel) const (m_clientCapabilities.SupportsRadio() && channel->IsRadio()))); } -PVR_ERROR CPVRClient::OpenLiveStream(const CPVRChannelPtr &channel) +PVR_ERROR CPVRClient::OpenLiveStream(const CFileItem& channelItem) { + std::shared_ptr channel = channelItem.GetPVRChannelInfoTag(); + if (!channel) + { + const std::shared_ptr item = CServiceBroker::GetPVRManager().ChannelGroups()->GetByPath(channelItem.GetPath()); + if (item) + channel = item->GetPVRChannelInfoTag(); + } + + if (!channel) + { + CLog::LogFC(LOGERROR, LOGPVR, "Unable to obtain channel for path '%s'", channelItem.GetPath().c_str()); + return PVR_ERROR_INVALID_PARAMETERS; + } + return DoAddonCall(__FUNCTION__, [this, channel](const AddonInstance* addon) { CloseLiveStream(); @@ -1238,8 +1252,22 @@ PVR_ERROR CPVRClient::OpenLiveStream(const CPVRChannelPtr &channel) }); } -PVR_ERROR CPVRClient::OpenRecordedStream(const CPVRRecordingPtr &recording) +PVR_ERROR CPVRClient::OpenRecordedStream(const CFileItem& recordingItem) { + std::shared_ptr recording = recordingItem.GetPVRRecordingInfoTag(); + if (!recording) + { + const std::shared_ptr item = CServiceBroker::GetPVRManager().Recordings()->GetByPath(recordingItem.GetPath()); + if (item) + recording = item->GetPVRRecordingInfoTag(); + } + + if (!recording) + { + CLog::LogFC(LOGERROR, LOGPVR, "Unable to obtain recording for path '%s'", recordingItem.GetPath().c_str()); + return PVR_ERROR_INVALID_PARAMETERS; + } + return DoAddonCall(__FUNCTION__, [this, recording](const AddonInstance* addon) { CloseRecordedStream(); diff --git a/xbmc/addons/PVRClient.h b/xbmc/addons/PVRClient.h index 5a5670cdd1b8c..e88362618e82c 100644 --- a/xbmc/addons/PVRClient.h +++ b/xbmc/addons/PVRClient.h @@ -609,10 +609,10 @@ namespace PVR /*! * @brief Open a live stream on the server. - * @param channel The channel to stream. + * @param channelItem The channel to stream. * @return PVR_ERROR_NO_ERROR on success, respective error code otherwise. */ - PVR_ERROR OpenLiveStream(const CPVRChannelPtr &channel); + PVR_ERROR OpenLiveStream(const CFileItem& channelItem); /*! * @brief Close an open live stream. @@ -711,10 +711,10 @@ namespace PVR /*! * @brief Open a recording on the server. - * @param recording The recording to open. + * @param recordingItem The recording to open. * @return PVR_ERROR_NO_ERROR on success, respective error code otherwise. */ - PVR_ERROR OpenRecordedStream(const CPVRRecordingPtr &recording); + PVR_ERROR OpenRecordedStream(const CFileItem& recordingItem); /*! * @brief Close an open recording stream. diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp index 7d3656af00552..ec6be719764a9 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp @@ -84,9 +84,9 @@ std::shared_ptr CDVDFactoryInputStream::CreateInputStream(IVide if (fileitem.IsDVDFile(false, true)) return std::shared_ptr(new CDVDInputStreamNavigator(pPlayer, fileitem)); - else if (fileitem.IsPVRChannel() && StringUtils::StartsWithNoCase(file, "pvr://")) + else if (URIUtils::IsPVRChannel(file)) return std::shared_ptr(new CInputStreamPVRChannel(pPlayer, fileitem)); - else if (fileitem.IsUsablePVRRecording() && StringUtils::StartsWithNoCase(file, "pvr://")) + else if (URIUtils::IsPVRRecording(file)) return std::shared_ptr(new CInputStreamPVRRecording(pPlayer, fileitem)); #ifdef HAVE_LIBBLURAY else if (fileitem.IsType(".bdmv") || fileitem.IsType(".mpls") || StringUtils::StartsWithNoCase(file, "bluray:")) diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRChannel.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRChannel.cpp index c3f8023040056..52cf0e785904e 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRChannel.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRChannel.cpp @@ -32,7 +32,7 @@ CDVDInputStream::IDemux* CInputStreamPVRChannel::GetIDemux() bool CInputStreamPVRChannel::OpenPVRStream() { - if (m_client && (m_client->OpenLiveStream(m_item.GetPVRChannelInfoTag()) == PVR_ERROR_NO_ERROR)) + if (m_client && (m_client->OpenLiveStream(m_item) == PVR_ERROR_NO_ERROR)) { m_bDemuxActive = m_client->GetClientCapabilities().HandlesDemuxing(); CLog::Log(LOGDEBUG, "CInputStreamPVRChannel - %s - opened channel stream %s", __FUNCTION__, m_item.GetPath().c_str()); diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRRecording.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRRecording.cpp index f02652ea6ff1f..8b9b5959a9053 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRRecording.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRRecording.cpp @@ -23,7 +23,7 @@ CInputStreamPVRRecording::~CInputStreamPVRRecording() bool CInputStreamPVRRecording::OpenPVRStream() { - if (m_client && (m_client->OpenRecordedStream(m_item.GetPVRRecordingInfoTag()) == PVR_ERROR_NO_ERROR)) + if (m_client && (m_client->OpenRecordedStream(m_item) == PVR_ERROR_NO_ERROR)) { CLog::Log(LOGDEBUG, "CInputStreamPVRRecording - %s - opened recording stream %s", __FUNCTION__, m_item.GetPath().c_str()); return true; diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index b482fb773884c..42a394d41bb45 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -21,6 +21,7 @@ #include "utils/JobManager.h" #include "utils/Stopwatch.h" #include "utils/StringUtils.h" +#include "utils/URIUtils.h" #include "utils/Variant.h" #include "utils/log.h" @@ -203,7 +204,18 @@ CPVRClientPtr CPVRManager::GetClient(const CFileItem &item) const iClientID = item.GetPVRTimerInfoTag()->m_iClientId; else if (item.HasEPGInfoTag()) iClientID = item.GetEPGInfoTag()->ClientID(); - + else if (URIUtils::IsPVRChannel(item.GetPath())) + { + const std::shared_ptr channelItem = m_channelGroups->GetByPath(item.GetPath()); + if (channelItem) + iClientID = channelItem->GetPVRChannelInfoTag()->ClientID(); + } + else if (URIUtils::IsPVRRecording(item.GetPath())) + { + const std::shared_ptr recordingItem = m_recordings->GetByPath(item.GetPath()); + if (recordingItem) + iClientID = recordingItem->GetPVRRecordingInfoTag()->ClientID(); + } return GetClient(iClientID); }