2 * Copyright (C) 2012-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
23 #include "cores/dvdplayer/DVDInputStreams/DVDInputStream.h"
24 #include "pvr/PVRManager.h"
25 #include "pvr/channels/PVRChannelGroupsContainer.h"
26 #include "pvr/recordings/PVRRecordings.h"
27 #include "pvr/addons/PVRClients.h"
28 #include "utils/log.h"
29 #include "utils/StringUtils.h"
33 using namespace XFILE;
38 m_isPlayRecording = false;
46 bool CPVRFile::Open(const CURL& url)
50 if (!g_PVRManager.IsStarted())
53 CStdString strURL = url.Get();
55 if (strURL.Left(18) == "pvr://channels/tv/" || strURL.Left(21) == "pvr://channels/radio/")
57 CFileItemPtr tag = g_PVRChannelGroups->GetByPath(strURL);
58 if (tag && tag->HasPVRChannelInfoTag())
60 if (!g_PVRManager.OpenLiveStream(*tag))
63 m_isPlayRecording = false;
64 CLog::Log(LOGDEBUG, "PVRFile - %s - playback has started on filename %s", __FUNCTION__, strURL.c_str());
68 CLog::Log(LOGERROR, "PVRFile - %s - channel not found with filename %s", __FUNCTION__, strURL.c_str());
72 else if (strURL.Left(17) == "pvr://recordings/")
74 CFileItemPtr tag = g_PVRRecordings->GetByPath(strURL);
75 if (tag && tag->HasPVRRecordingInfoTag())
77 if (!g_PVRManager.OpenRecordedStream(*tag->GetPVRRecordingInfoTag()))
80 m_isPlayRecording = true;
81 CLog::Log(LOGDEBUG, "%s - Recording has started on filename %s", __FUNCTION__, strURL.c_str());
85 CLog::Log(LOGERROR, "PVRFile - Recording not found with filename %s", strURL.c_str());
91 CLog::Log(LOGERROR, "%s - invalid path specified %s", __FUNCTION__, strURL.c_str());
98 void CPVRFile::Close()
100 g_PVRManager.CloseStream();
103 unsigned int CPVRFile::Read(void* buffer, int64_t size)
105 return g_PVRManager.IsStarted() ? g_PVRClients->ReadStream((BYTE*)buffer, size) : 0;
108 int64_t CPVRFile::GetLength()
110 return g_PVRManager.IsStarted() ? g_PVRClients->GetStreamLength() : 0;
113 int64_t CPVRFile::Seek(int64_t pos, int whence)
115 return g_PVRManager.IsStarted() ? g_PVRClients->SeekStream(pos, whence) : 0;
118 int64_t CPVRFile::GetPosition()
120 return g_PVRManager.IsStarted() ? g_PVRClients->GetStreamPosition() : 0;
123 int CPVRFile::GetTotalTime()
125 // for recordings leave this to demuxer
126 return m_isPlayRecording ? 0 : g_PVRManager.GetTotalTime();
129 int CPVRFile::GetStartTime()
131 return g_PVRManager.GetStartTime();
134 bool CPVRFile::NextChannel(bool preview/* = false*/)
136 unsigned int newchannel;
138 if (m_isPlayRecording)
140 /* We are inside a recording, skip channelswitch */
144 /* Do channel switch and save new channel number, it is not always
145 * increased by one in a case if next channel is encrypted or we
146 * on the beginning or end of the channel list!
148 if (g_PVRManager.ChannelUp(&newchannel, preview))
150 m_playingItem = newchannel;
159 bool CPVRFile::PrevChannel(bool preview/* = false*/)
161 unsigned int newchannel;
163 if (m_isPlayRecording)
165 /* We are inside a recording, skip channelswitch */
169 /* Do channel switch and save new channel number, it is not always
170 * increased by one in a case if next channel is encrypted or we
171 * on the beginning or end of the channel list!
173 if (g_PVRManager.ChannelDown(&newchannel, preview))
175 m_playingItem = newchannel;
184 bool CPVRFile::SelectChannel(unsigned int channel)
186 if (m_isPlayRecording)
188 /* We are inside a recording, skip channelswitch */
190 ** Add support for cutting keys (functions becomes the numeric keys as integer)
195 if (g_PVRManager.ChannelSwitch(channel))
197 m_playingItem = channel;
206 bool CPVRFile::UpdateItem(CFileItem& item)
208 return g_PVRManager.UpdateItem(item);
211 CStdString CPVRFile::TranslatePVRFilename(const CStdString& pathFile)
213 if (!g_PVRManager.IsStarted())
214 return StringUtils::EmptyString;
216 CStdString FileName = pathFile;
217 if (FileName.substr(0, 14) == "pvr://channels")
219 CFileItemPtr channel = g_PVRChannelGroups->GetByPath(FileName);
220 if (channel && channel->HasPVRChannelInfoTag())
222 CStdString stream = channel->GetPVRChannelInfoTag()->StreamURL();
223 if(!stream.IsEmpty())
225 if (stream.compare(6, 7, "stream/") == 0)
228 // This function was added to retrieve the stream URL for this item
229 // Is is used for the MediaPortal (ffmpeg) PVR addon
230 // see PVRManager.cpp
231 return g_PVRClients->GetStreamURL(*channel->GetPVRChannelInfoTag());
243 bool CPVRFile::CanRecord()
245 if (m_isPlayRecording || !g_PVRManager.IsStarted())
248 return g_PVRClients->CanRecordInstantly();
251 bool CPVRFile::IsRecording()
253 return g_PVRManager.IsStarted() && g_PVRClients->IsRecordingOnPlayingChannel();
256 bool CPVRFile::Record(bool bOnOff)
258 return g_PVRManager.StartRecordingOnPlayingChannel(bOnOff);
261 bool CPVRFile::Delete(const CURL& url)
263 if (!g_PVRManager.IsStarted())
266 CStdString path(url.GetFileName());
267 if (path.Left(11) == "recordings/" && path[path.size()-1] != '/')
269 CStdString strURL = url.Get();
270 CFileItemPtr tag = g_PVRRecordings->GetByPath(strURL);
271 if (tag && tag->HasPVRRecordingInfoTag())
272 return tag->GetPVRRecordingInfoTag()->Delete();
277 bool CPVRFile::Rename(const CURL& url, const CURL& urlnew)
279 if (!g_PVRManager.IsStarted())
282 CStdString path(url.GetFileName());
283 CStdString newname(urlnew.GetFileName());
285 size_t found = newname.find_last_of("/");
286 if (found != CStdString::npos)
287 newname = newname.substr(found+1);
289 if (path.Left(11) == "recordings/" && path[path.size()-1] != '/')
291 CStdString strURL = url.Get();
292 CFileItemPtr tag = g_PVRRecordings->GetByPath(strURL);
293 if (tag && tag->HasPVRRecordingInfoTag())
294 return tag->GetPVRRecordingInfoTag()->Rename(newname);
299 bool CPVRFile::Exists(const CURL& url)
301 return g_PVRManager.IsStarted() &&
302 g_PVRRecordings->GetByPath(url.Get())->HasPVRRecordingInfoTag();
305 int CPVRFile::IoControl(EIoControl request, void *param)
307 if (request == IOCTRL_SEEK_POSSIBLE)
309 if (!g_PVRManager.IsStarted())
311 else if (g_PVRClients->CanSeekStream())