Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #320 from dvblogic/frodo

Backport of the DVBLink PVR addon 1.9.1 to Frodo branch
  • Loading branch information...
commit 271a23f16a0d68ac6b4a9a435d59942298429d8f 2 parents caea54e + 8d32abe
@opdenkamp authored
View
4 addons/pvr.dvblink/addon/addon.xml.in
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="pvr.dvblink"
- version="1.6.1"
+ version="1.7.1"
name="DVBLink PVR Client"
- provider-name="Barcode Madness">
+ provider-name="DVBLogic">
<requires>
<c-pluff version="0.1"/>
<import addon="xbmc.pvr" version="1.6.0"/>
View
6 addons/pvr.dvblink/addon/changelog.txt
@@ -1,3 +1,9 @@
+[B]Version 1.7.1[/B]
+Backport of version 1.9.1 to Frodo branch
+Added: support for DVBLink v5 server timeshifting capabilities
+Fixed: series number, genre, episode name tags
+Fixed: correct displaying of series recordings
+
[B]Version 1.7.0[/B]
Fixed: Recordings on DVBLINK 4.5.3
Fixed: Closing socket file handles
View
5 addons/pvr.dvblink/addon/resources/settings.xml
@@ -3,9 +3,8 @@
<!-- Connection -->
<category label="30000">
<setting id="host" type="text" label="30001" option="urlencoded" default="127.0.0.1" />
- <setting id="port" type="number" option="int" label="30002" default="8080" />
+ <setting id="port" type="number" option="int" label="30002" default="8100" />
<setting id="timeout" visible="false" type="enum" label="30004" values="0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20" default="10"/>
- <setting id="client" type="text" label="30003" default="xbmc" />
<setting id="username" type="text" label="30005" default="" />
<setting id="password" type="text" label="30006" default="" option="hidden" enable="!eq(-1,)" />
@@ -14,7 +13,6 @@
<category label="30100">
<setting id="streamtype" type="enum" label="30102" lvalues="30107|30108|30109|30110" default="0" />
<setting id="timeshift" visible="eq(-1,0)" type="bool" label="30111" default="false" />
- <setting id="timeshiftpath" visible="eq(-2,0)" enabled="eq(-1,0)" type="text" label="30112" default="special://userdata/addon_data/pvr.dvblink/" />
<setting id="height" visible="gt(-3,0)" type="number" label="30103" default="720" />
<setting id="width" visible="gt(-4,0)" type="number" label="30104" default="576" />
<setting id="bitrate" visible="gt(-5,0)" type="number" label="30105" default="512" />
@@ -23,7 +21,6 @@
<!-- Advanced -->
<category label="30200">
- <setting id="ch_handle" type="bool" label="30201" default="true" />
<setting id="showinfomsg" type="bool" label="30202" default="false" />
</category>
</settings>
View
265 addons/pvr.dvblink/src/DVBLinkClient.cpp
@@ -56,7 +56,7 @@ std::string DVBLinkClient::GetBuildInRecorderObjectID()
-DVBLinkClient::DVBLinkClient(CHelper_libXBMC_addon *XBMC, CHelper_libXBMC_pvr *PVR,std::string clientname, std::string hostname, long port,bool showinfomsg, std::string username, std::string password, bool usetimeshift, std::string timeshiftpath)
+DVBLinkClient::DVBLinkClient(CHelper_libXBMC_addon *XBMC, CHelper_libXBMC_pvr *PVR,std::string clientname, std::string hostname, long port,bool showinfomsg, std::string username, std::string password, bool usetimeshift)
{
this->PVR = PVR;
this->XBMC = XBMC;
@@ -65,14 +65,10 @@ DVBLinkClient::DVBLinkClient(CHelper_libXBMC_addon *XBMC, CHelper_libXBMC_pvr *
m_connected = false;
m_currentChannelId = 0;
m_showinfomsg = showinfomsg;
+ m_usetimeshift = usetimeshift;
- m_usetimeshift = usetimeshift && XBMC->DirectoryExists(timeshiftpath.c_str());
-
- m_timeshiftpath.append(timeshiftpath);
- m_timeshiftpath.append(clientname);
-
- m_httpClient = new HttpPostClient(XBMC,hostname,port, username, password);
- m_dvblinkRemoteCommunication = DVBLinkRemote::Connect((HttpClient&)*m_httpClient, m_hostname.c_str(), 8080, username.c_str(), password.c_str());
+ m_httpClient = new HttpPostClient(XBMC,hostname, port, username, password);
+ m_dvblinkRemoteCommunication = DVBLinkRemote::Connect((HttpClient&)*m_httpClient, m_hostname.c_str(), port, username.c_str(), password.c_str());
DVBLinkRemoteStatusCode status;
m_timerCount = -1;
@@ -209,88 +205,70 @@ PVR_ERROR DVBLinkClient::GetTimers(ADDON_HANDLE handle)
PVR_ERROR result = PVR_ERROR_FAILED;
PLATFORM::CLockObject critsec(m_mutex);
- GetSchedulesRequest getSchedulesRequest;
- StoredSchedules sschedules;
+ GetRecordingsRequest recordingsRequest;
+ RecordingList recordings;
DVBLinkRemoteStatusCode status;
- int count = 0;
- if ((status = m_dvblinkRemoteCommunication->GetSchedules(getSchedulesRequest, sschedules)) != DVBLINK_REMOTE_STATUS_OK)
+ if ((status = m_dvblinkRemoteCommunication->GetRecordings(recordingsRequest, recordings)) != DVBLINK_REMOTE_STATUS_OK)
{
std::string error;
m_dvblinkRemoteCommunication->GetLastError(error);
- XBMC->Log(LOG_ERROR, "Could not get timers (Error code : %d Description : %s)", (int)status,error.c_str());
- // XBMC->QueueNotification(QUEUE_ERROR, XBMC->GetLocalizedString(32006), (int)status);
+ XBMC->Log(LOG_ERROR, "Could not get timers (Error code : %d Description : %s)", (int)status, error.c_str());
return result;
}
- XBMC->Log(LOG_INFO, "Found %d epg timers", sschedules.GetEpgSchedules().size());
+ XBMC->Log(LOG_INFO, "Found %d timers", recordings.size());
if (m_showinfomsg)
{
- XBMC->QueueNotification(QUEUE_INFO, XBMC->GetLocalizedString(32007), sschedules.GetEpgSchedules().size());
+ XBMC->QueueNotification(QUEUE_INFO, XBMC->GetLocalizedString(32007), recordings.size());
}
- for (std::vector<StoredEpgSchedule*>::iterator it = sschedules.GetEpgSchedules().begin(); it < sschedules.GetEpgSchedules().end(); it++)
+ for (size_t i=0; i < recordings.size(); i++)
{
- StoredEpgSchedule* schedule = (StoredEpgSchedule*)*it;
+ Recording* rec = recordings[i];
+
PVR_TIMER xbmcTimer;
memset(&xbmcTimer, 0, sizeof(PVR_TIMER));
- PVR_STR2INT(xbmcTimer.iClientIndex, schedule->GetID().c_str());
+ //fake index
+ xbmcTimer.iClientIndex = i;
+ //misuse strDirectory to keep id of the timer
+ PVR_STRCPY(xbmcTimer.strDirectory, rec->GetID().c_str());
- xbmcTimer.iClientChannelUid = GetInternalUniqueIdFromChannelId(schedule->GetChannelID());
+ xbmcTimer.iClientChannelUid = GetInternalUniqueIdFromChannelId(rec->GetChannelID());
xbmcTimer.state = PVR_TIMER_STATE_SCHEDULED;
- xbmcTimer.bIsRepeating = schedule->Repeat;
- PVR_STR2INT(xbmcTimer.iEpgUid, schedule->GetProgramID().c_str());
- EpgSearchResult epgSearchResult;
- if (DoEPGSearch(epgSearchResult,schedule->GetChannelID(), -1, -1, schedule->GetProgramID()))
- {
- if (epgSearchResult.size() < 1 || epgSearchResult[0]->GetEpgData().size() < 1)
- {
- XBMC->Log(LOG_INFO, "No EPG program data for timer '%s' on channel '%s' with program id '%s'", schedule->GetID().c_str(),schedule->GetChannelID().c_str(),schedule->GetProgramID().c_str());
- continue;
- }
- ChannelEpgData * channelepgdata = epgSearchResult[0];
- Program * program = channelepgdata->GetEpgData()[0];
-
- xbmcTimer.startTime =program->GetStartTime();
- xbmcTimer.endTime = program->GetStartTime() + program->GetDuration();
- PVR_STRCPY(xbmcTimer.strTitle, program->GetTitle().c_str());
- PVR_STRCPY(xbmcTimer.strSummary, program->ShortDescription.c_str());
- PVR->TransferTimerEntry(handle, &xbmcTimer);
- XBMC->Log(LOG_INFO, "Added EPG timer : %s", program->GetTitle().c_str());
-
- count++;
- }
+ if (rec->IsActive)
+ xbmcTimer.state = PVR_TIMER_STATE_RECORDING;
+ if (rec->IsConflict)
+ xbmcTimer.state = PVR_TIMER_STATE_CONFLICT_NOK;
+ if (!rec->GetProgram().IsRecord)
+ xbmcTimer.state = PVR_TIMER_STATE_CANCELLED;
- }
-
- XBMC->Log(LOG_INFO, "Found %d manual timers", sschedules.GetManualSchedules().size());
-
- if (m_showinfomsg)
- {
- XBMC->QueueNotification(QUEUE_INFO, XBMC->GetLocalizedString(32008), sschedules.GetManualSchedules().size());
- }
-
- for (std::vector<StoredManualSchedule*>::iterator it = sschedules.GetManualSchedules().begin(); it < sschedules.GetManualSchedules().end(); it++)
- {
- StoredManualSchedule* schedule = (StoredManualSchedule*)*it;
- PVR_TIMER xbmcTimer;
- memset(&xbmcTimer, 0, sizeof(PVR_TIMER));
- PVR_STR2INT(xbmcTimer.iClientIndex, schedule->GetID().c_str());
-
- xbmcTimer.iClientChannelUid = GetInternalUniqueIdFromChannelId(schedule->GetChannelID());
+ xbmcTimer.bIsRepeating = rec->GetProgram().IsSeries;
+ PVR_STR2INT(xbmcTimer.iEpgUid, rec->GetProgram().GetID().c_str());
+
+ xbmcTimer.startTime =rec->GetProgram().GetStartTime();
+ xbmcTimer.endTime = rec->GetProgram().GetStartTime() + rec->GetProgram().GetDuration();
+ PVR_STRCPY(xbmcTimer.strTitle, rec->GetProgram().GetTitle().c_str());
+ PVR_STRCPY(xbmcTimer.strSummary, rec->GetProgram().ShortDescription.c_str());
+
+ int genre_type, genre_subtype;
+ SetEPGGenre(rec->GetProgram(), genre_type, genre_subtype);
+ if (genre_type == EPG_GENRE_USE_STRING)
+ {
+ xbmcTimer.iGenreType = EPG_EVENT_CONTENTMASK_UNDEFINED;
+ } else
+ {
+ xbmcTimer.iGenreType = genre_type;
+ xbmcTimer.iGenreSubType = genre_subtype;
+ }
- xbmcTimer.state = PVR_TIMER_STATE_SCHEDULED;
- xbmcTimer.startTime = schedule->GetStartTime();
- xbmcTimer.endTime = schedule->GetStartTime() + schedule->GetDuration();
- PVR_STRCPY(xbmcTimer.strTitle, schedule->Title.c_str());
- //TODO: PAE: Add weekdays
- XBMC->Log(LOG_INFO, "Added manual timer : %s", schedule->Title.c_str());
PVR->TransferTimerEntry(handle, &xbmcTimer);
- count++;
+ XBMC->Log(LOG_INFO, "Added EPG timer : %s", rec->GetProgram().GetTitle().c_str());
}
- m_timerCount = count;
+
+ m_timerCount = recordings.size();
result = PVR_ERROR_NO_ERROR;
return result;
}
@@ -302,7 +280,7 @@ PVR_ERROR DVBLinkClient::AddTimer(const PVR_TIMER &timer)
DVBLinkRemoteStatusCode status;
AddScheduleRequest * addScheduleRequest = NULL;
std::string channelId = m_channelMap[timer.iClientChannelUid]->GetID();
- if (timer.iEpgUid != 0)
+ if (timer.iEpgUid != -1)
{
char programId [33];
PVR_INT2STR(programId,timer.iEpgUid);
@@ -336,13 +314,11 @@ PVR_ERROR DVBLinkClient::DeleteTimer(const PVR_TIMER &timer)
PVR_ERROR result = PVR_ERROR_FAILED;
PLATFORM::CLockObject critsec(m_mutex);
DVBLinkRemoteStatusCode status;
- char scheduleId [33];
- PVR_INT2STR(scheduleId, timer.iClientIndex);
- RemoveScheduleRequest removeSchedule(scheduleId);
-
+ //recording id is kept in strDirectory!
+ RemoveRecordingRequest removeRecording(timer.strDirectory);
- if ((status = m_dvblinkRemoteCommunication->RemoveSchedule(removeSchedule)) == DVBLINK_REMOTE_STATUS_OK)
+ if ((status = m_dvblinkRemoteCommunication->RemoveRecording(removeRecording)) == DVBLINK_REMOTE_STATUS_OK)
{
XBMC->Log(LOG_INFO, "Timer deleted");
PVR->TriggerTimerUpdate();
@@ -359,12 +335,8 @@ PVR_ERROR DVBLinkClient::DeleteTimer(const PVR_TIMER &timer)
PVR_ERROR DVBLinkClient::UpdateTimer(const PVR_TIMER &timer)
{
- PVR_ERROR deleteResult = DeleteTimer(timer);
- if (deleteResult == PVR_ERROR_NO_ERROR)
- {
- return AddTimer(timer);
- }
- return deleteResult;
+ //DVBLink serverdoes not support timer update (e.g. delete/re-create)
+ return PVR_ERROR_FAILED;
}
int DVBLinkClient::GetRecordingsAmount()
@@ -373,8 +345,6 @@ int DVBLinkClient::GetRecordingsAmount()
return m_recordingCount;
}
-
-
std::string DVBLinkClient::GetRecordedTVByDateObjectID(const std::string& buildInRecoderObjectID)
{
std::string result = "";
@@ -392,7 +362,6 @@ std::string DVBLinkClient::GetRecordedTVByDateObjectID(const std::string& buildI
PlaybackContainer * container = (PlaybackContainer *) *it;
- // if (strcmp(container->GetName().c_str(), "By Date") == 0)
if (container->GetObjectID().find("F6F08949-2A07-4074-9E9D-423D877270BB") != std::string::npos)
{
result = container->GetObjectID();
@@ -468,6 +437,17 @@ PVR_ERROR DVBLinkClient::GetRecordings(ADDON_HANDLE handle)
xbmcRecording.iDuration = tvitem->GetMetadata().GetDuration();
PVR_STRCPY(xbmcRecording.strChannelName, tvitem->ChannelName.c_str());
PVR_STRCPY(xbmcRecording.strThumbnailPath, tvitem->GetThumbnailUrl().c_str());
+ int genre_type, genre_subtype;
+ SetEPGGenre(tvitem->GetMetadata(), genre_type, genre_subtype);
+ if (genre_type == EPG_GENRE_USE_STRING)
+ {
+ xbmcRecording.iGenreType = EPG_EVENT_CONTENTMASK_UNDEFINED;
+ } else
+ {
+ xbmcRecording.iGenreType = genre_type;
+ xbmcRecording.iGenreSubType = genre_subtype;
+ }
+
PVR->TransferRecordingEntry(handle, &xbmcRecording);
}
@@ -506,20 +486,26 @@ const char * DVBLinkClient::GetLiveStreamURL(const PVR_CHANNEL &channel, DVBLINK
options.SetAudioTrack(audiotrack);
Channel * c = m_channelMap[channel.iUniqueId];
DVBLinkRemoteStatusCode status;
- switch (streamtype)
- {
- case HTTP:
- streamRequest = new RawHttpStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str());
- break;
- case RTP:
- streamRequest = new RealTimeTransportProtocolStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str(), options);
- break;
- case HLS:
- streamRequest = new HttpLiveStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str(), options);
- break;
- case ASF:
- streamRequest = new WindowsMediaStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str(), options);
- break;
+ if (m_usetimeshift)
+ {
+ streamRequest = new RawHttpTimeshiftStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str());
+ } else
+ {
+ switch (streamtype)
+ {
+ case HTTP:
+ streamRequest = new RawHttpStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str());
+ break;
+ case RTP:
+ streamRequest = new RealTimeTransportProtocolStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str(), options);
+ break;
+ case HLS:
+ streamRequest = new HttpLiveStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str(), options);
+ break;
+ case ASF:
+ streamRequest = new WindowsMediaStreamRequest(m_hostname.c_str(), c->GetDvbLinkID(), m_clientname.c_str(), options);
+ break;
+ }
}
if ((status = m_dvblinkRemoteCommunication->PlayChannel(*streamRequest, *m_stream)) != DVBLINK_REMOTE_STATUS_OK)
@@ -539,14 +525,14 @@ const char * DVBLinkClient::GetLiveStreamURL(const PVR_CHANNEL &channel, DVBLINK
bool DVBLinkClient::OpenLiveStream(const PVR_CHANNEL &channel, DVBLINK_STREAMTYPE streamtype, int width, int height, int bitrate, std::string audiotrack)
{
- if (m_usetimeshift && streamtype == HTTP)
+ if (m_usetimeshift)
{
if (m_tsBuffer)
{
SAFE_DELETE(m_tsBuffer);
}
- m_tsBuffer = new TimeShiftBuffer(XBMC, GetLiveStreamURL(channel, streamtype, width, height, bitrate, audiotrack), m_timeshiftpath);
- return m_tsBuffer->IsValid();
+ m_tsBuffer = new TimeShiftBuffer(XBMC, GetLiveStreamURL(channel, streamtype, width, height, bitrate, audiotrack));
+ return true;
}
return false;
}
@@ -578,6 +564,27 @@ long long DVBLinkClient::LengthLiveStream(void)
return 0;
}
+time_t DVBLinkClient::GetPlayingTime()
+{
+ if(m_tsBuffer)
+ return m_tsBuffer->GetPlayingTime();
+ return 0;
+}
+
+time_t DVBLinkClient::GetBufferTimeStart()
+{
+ if(m_tsBuffer)
+ return m_tsBuffer->GetBufferTimeStart();
+ return 0;
+}
+
+time_t DVBLinkClient::GetBufferTimeEnd()
+{
+ if(m_tsBuffer)
+ return m_tsBuffer->GetBufferTimeEnd();
+ return 0;
+}
+
void DVBLinkClient::StopStreaming(bool bUseChlHandle)
{
PLATFORM::CLockObject critsec(m_mutex);
@@ -610,53 +617,53 @@ void DVBLinkClient::StopStreaming(bool bUseChlHandle)
SAFE_DELETE(request);
}
-void DVBLinkClient::SetEPGGenre(Program *program, EPG_TAG *tag)
+void DVBLinkClient::SetEPGGenre(dvblinkremote::ItemMetadata& metadata, int& genre_type, int& genre_subtype)
{
- if (program->IsCatNews)
+ genre_type = EPG_GENRE_USE_STRING;
+ genre_subtype = 0x00;
+
+ if (metadata.IsCatNews)
{
- tag->iGenreType = 0x20;
- tag->iGenreSubType = 0x00;
+ genre_type = EPG_EVENT_CONTENTMASK_NEWSCURRENTAFFAIRS;
+ genre_subtype = 0x00;
}
- if (program->IsCatDocumentary)
+ if (metadata.IsCatDocumentary)
{
- tag->iGenreType = 0x20;
- tag->iGenreSubType = 0x03;
+ genre_type = EPG_EVENT_CONTENTMASK_NEWSCURRENTAFFAIRS;
+ genre_subtype = 0x03;
}
- if (program->IsCatEducational)
+ if (metadata.IsCatEducational)
{
- tag->iGenreType = 0x90;
+ genre_type = EPG_EVENT_CONTENTMASK_EDUCATIONALSCIENCE;
}
- if (program->IsCatSports)
+ if (metadata.IsCatSports)
{
- tag->iGenreType = 0x40;
+ genre_type = EPG_EVENT_CONTENTMASK_SPORTS;
}
-
-
-
- if (program->IsCatMovie)
+ if (metadata.IsCatMovie)
{
- tag->iGenreType = 0x10;
- tag->iGenreSubType =program->IsCatThriller ? 0x01 : program->IsCatScifi ? 0x03 :program->IsCatHorror ? 0x03 : program->IsCatComedy ? 0x04 : program->IsCatSoap ? 0x05 : program->IsCatRomance ? 0x06 :program->IsCatDrama ? 0x08 : 0;
+ genre_type = EPG_EVENT_CONTENTMASK_MOVIEDRAMA;
+ genre_subtype =metadata.IsCatThriller ? 0x01 : metadata.IsCatScifi ? 0x03 :metadata.IsCatHorror ? 0x03 : metadata.IsCatComedy ? 0x04 : metadata.IsCatSoap ? 0x05 : metadata.IsCatRomance ? 0x06 :metadata.IsCatDrama ? 0x08 : 0;
}
- if (program->IsCatKids)
+ if (metadata.IsCatKids)
{
- tag->iGenreType = 0x50;
+ genre_type = EPG_EVENT_CONTENTMASK_CHILDRENYOUTH;
}
- if (program->IsCatMusic)
+ if (metadata.IsCatMusic)
{
- tag->iGenreType = 0x60;
+ genre_type = EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE;
}
- if (program->IsCatSpecial)
+ if (metadata.IsCatSpecial)
{
- tag->iGenreType = 0xB0;
+ genre_type = EPG_EVENT_CONTENTMASK_SPECIAL;
}
}
@@ -713,11 +720,19 @@ PVR_ERROR DVBLinkClient::GetEPGForChannel(ADDON_HANDLE handle, const PVR_CHANNEL
broadcast.iParentalRating = 0;
broadcast.iStarRating = p->Rating;
broadcast.bNotify = false;
- broadcast.iSeriesNumber = 0;
+ broadcast.iSeriesNumber = p->SeasonNumber;
broadcast.iEpisodeNumber = p->EpisodeNumber;
broadcast.iEpisodePartNumber = 0;
- broadcast.strEpisodeName = "";
- SetEPGGenre(p, &broadcast);
+ broadcast.strEpisodeName = p->SubTitle.c_str();
+
+ int genre_type, genre_subtype;
+ SetEPGGenre(*p, genre_type, genre_subtype);
+ broadcast.iGenreType = genre_type;
+ if (genre_type == EPG_GENRE_USE_STRING)
+ broadcast.strGenreDescription = p->Keywords.c_str();
+ else
+ broadcast.iGenreSubType = genre_subtype;
+
PVR->TransferEpgEntry(handle, &broadcast);
}
}
View
10 addons/pvr.dvblink/src/DVBLinkClient.h
@@ -40,12 +40,10 @@
#define DVBLINK_BUILD_IN_RECORDER_SOURCE_ID "8F94B459-EFC0-4D91-9B29-EC3D72E92677"
#define DVBLINK_RECODINGS_BY_DATA_ID "F6F08949-2A07-4074-9E9D-423D877270BB"
-
-
class DVBLinkClient : public PLATFORM::CThread
{
public:
- DVBLinkClient(ADDON::CHelper_libXBMC_addon *XBMC, CHelper_libXBMC_pvr *PVR, std::string clientname, std::string hostname, long port, bool showinfomsg, std::string username, std::string password, bool usetimeshift, std::string timeshiftpath);
+ DVBLinkClient(ADDON::CHelper_libXBMC_addon *XBMC, CHelper_libXBMC_pvr *PVR, std::string clientname, std::string hostname, long port, bool showinfomsg, std::string username, std::string password, bool usetimeshift);
~DVBLinkClient(void);
int GetChannelsAmount();
PVR_ERROR GetChannels(ADDON_HANDLE handle, bool bRadio);
@@ -68,10 +66,13 @@ class DVBLinkClient : public PLATFORM::CThread
long long PositionLiveStream(void);
long long LengthLiveStream(void);
int ReadLiveStream(unsigned char *pBuffer, unsigned int iBufferSize);
+ time_t GetPlayingTime();
+ time_t GetBufferTimeStart();
+ time_t GetBufferTimeEnd();
private:
bool DoEPGSearch(dvblinkremote::EpgSearchResult& epgSearchResult, const std::string& channelId, const long startTime, const long endTime, const std::string & programId = "");
- void SetEPGGenre(dvblinkremote::Program *program, EPG_TAG *tag);
+ void SetEPGGenre(dvblinkremote::ItemMetadata& metadata, int& genre_type, int& genre_subtype);
std::string GetBuildInRecorderObjectID();
std::string GetRecordedTVByDateObjectID(const std::string& buildInRecoderObjectID);
int GetInternalUniqueIdFromChannelId(const std::string& channelId);
@@ -93,7 +94,6 @@ class DVBLinkClient : public PLATFORM::CThread
std::string m_clientname;
std::string m_hostname;
TimeShiftBuffer *m_tsBuffer;
- std::string m_timeshiftpath;
bool m_usetimeshift;
bool m_showinfomsg;
bool m_updating;
View
203 addons/pvr.dvblink/src/TimeShiftBuffer.cpp
@@ -22,119 +22,176 @@
*
*/
-
#include "TimeShiftBuffer.h"
using namespace ADDON;
-TimeShiftBuffer::TimeShiftBuffer(CHelper_libXBMC_addon * XBMC, std::string streampath, std::string bufferpath)
+TimeShiftBuffer::TimeShiftBuffer(CHelper_libXBMC_addon * XBMC, std::string streampath)
{
+ last_pos_req_time_ = -1;
+ last_pos_ = 0;
+
this->XBMC = XBMC;
+ streampath_ = streampath;
- m_bufferPath = bufferpath;
- m_streamHandle = XBMC->OpenFile(streampath.c_str(), 0);
- m_filebufferWriteHandle = XBMC->OpenFileForWrite(m_bufferPath.c_str(),true);
- Sleep(100);
- m_filebufferReadHandle = XBMC->OpenFile(m_bufferPath.c_str(), 0);
- m_shifting = true;
- CreateThread();
+ m_streamHandle = XBMC->OpenFile(streampath_.c_str(), 0);
}
-
-bool TimeShiftBuffer::IsValid()
+TimeShiftBuffer::~TimeShiftBuffer(void)
{
- return (m_streamHandle != NULL);
+ XBMC->CloseFile(m_streamHandle);
}
-void TimeShiftBuffer::Stop()
-{
- m_shifting = false;
-}
-TimeShiftBuffer::~TimeShiftBuffer(void)
+long long TimeShiftBuffer::Seek(long long iPosition, int iWhence)
{
- Stop();
- if (IsRunning())
+ if (iPosition == 0 && iWhence == SEEK_CUR)
{
- StopThread();
+ return Position();
}
- if (m_filebufferWriteHandle)
- {
- XBMC->CloseFile(m_filebufferWriteHandle);
- }
- if (m_filebufferReadHandle)
- {
- XBMC->CloseFile(m_filebufferReadHandle);
- }
- if (XBMC->FileExists(m_bufferPath.c_str(), true))
- {
- XBMC->DeleteFile(m_bufferPath.c_str());
- }
+ long long ret_val = 0;
+
+ char param_buf[1024];
+ sprintf(param_buf, "&seek=%lld&whence=%d", iPosition, iWhence);
- if (m_streamHandle)
+ std::string req_url = streampath_;
+ req_url += param_buf;
+
+ //close streaming handle before executing seek
+ XBMC->CloseFile(m_streamHandle);
+ //execute seek request
+ std::vector<std::string> response_values;
+ if (ExecuteServerRequest(req_url, response_values))
{
- XBMC->CloseFile(m_streamHandle);
+ ret_val = atoll(response_values[0].c_str());
}
+
+ //restart streaming
+ m_streamHandle = XBMC->OpenFile(streampath_.c_str(), 0);
+
+ return ret_val;
}
-void *TimeShiftBuffer::Process()
+long long TimeShiftBuffer::Position()
{
- XBMC->Log(LOG_DEBUG, "TimeShiftProcess:: thread started");
- byte buffer[STREAM_READ_BUFFER_SIZE];
- int bytesRead = STREAM_READ_BUFFER_SIZE;
+ long long ret_val = 0;
- while (m_shifting)
+ time_t duration;
+ long long length;
+ GetBufferParams(length, duration, ret_val);
+
+ return ret_val;
+}
+
+bool TimeShiftBuffer::ExecuteServerRequest(const std::string& url, std::vector<std::string>& response_values)
+{
+ bool ret_val = false;
+ response_values.clear();
+
+ void* req_handle = XBMC->OpenFile(url.c_str(), 0);
+ if (req_handle != NULL)
{
- bytesRead = XBMC->ReadFile(m_streamHandle, buffer, sizeof(buffer));
- XBMC->WriteFile(m_filebufferWriteHandle,buffer,bytesRead);
+ char resp_buf[1024];
+ unsigned int read = XBMC->ReadFile(req_handle, resp_buf, sizeof(resp_buf));
+
+ if (read > 0)
+ {
+ //add zero at the end to turn response into string
+ resp_buf[read] = '\0';
+ char* token = strtok( resp_buf, ",");
+ while( token != NULL )
+ {
+ response_values.push_back(token);
+ /* Get next token: */
+ token = strtok(NULL, ",");
+ }
+ ret_val = response_values.size() > 0;
+ }
+
+ XBMC->CloseFile(req_handle);
}
- XBMC->Log(LOG_DEBUG, "TimeShiftProcess:: thread stopped");
- return NULL;
-}
+ return ret_val;
+}
-long long TimeShiftBuffer::Seek(long long iPosition, int iWhence)
+long long TimeShiftBuffer::Length()
{
- if (m_filebufferReadHandle)
- return XBMC->SeekFile(m_filebufferReadHandle,iPosition,iWhence);
- return 0;
+ long long ret_val = 0;
+
+ time_t duration;
+ long long cur_pos;
+ GetBufferParams(ret_val, duration, cur_pos);
+
+ return ret_val;
}
-long long TimeShiftBuffer::Position()
+bool TimeShiftBuffer::GetBufferParams(long long& length, time_t& duration, long long& cur_pos)
{
- if (m_filebufferReadHandle)
- return XBMC->GetFilePosition(m_filebufferReadHandle);
- return 0;
+ bool ret_val = false;
+
+ std::string req_url = streampath_;
+ req_url += "&get_stats=1";
+
+ std::vector<std::string> response_values;
+ if (ExecuteServerRequest(req_url, response_values) &&
+ response_values.size() == 3)
+ {
+ length = atoll(response_values[0].c_str());
+ duration = (time_t)atoll(response_values[1].c_str());
+ cur_pos = atoll(response_values[2].c_str());
+ ret_val = true;
+ }
+
+ return ret_val;
}
-long long TimeShiftBuffer::Length()
+int TimeShiftBuffer::ReadData(unsigned char *pBuffer, unsigned int iBufferSize)
{
- if (m_filebufferReadHandle)
- return XBMC->GetFileLength(m_filebufferReadHandle);
- return 0;
+ return XBMC->ReadFile(m_streamHandle, pBuffer, iBufferSize);
}
-int TimeShiftBuffer::ReadData(unsigned char *pBuffer, unsigned int iBufferSize)
+time_t TimeShiftBuffer::GetPlayingTime()
{
- unsigned int totalReadBytes = 0;
- unsigned int totalTimeWaited = 0;
- if (m_filebufferReadHandle)
- {
- unsigned int read = XBMC->ReadFile(m_filebufferReadHandle, pBuffer,iBufferSize);
- totalReadBytes += read;
+ time_t ret_val = last_pos_;
- while (read < iBufferSize && totalTimeWaited < BUFFER_READ_TIMEOUT)
- {
- Sleep(BUFFER_READ_WAITTIME);
- totalTimeWaited += BUFFER_READ_WAITTIME;
- read = XBMC->ReadFile(m_filebufferReadHandle, pBuffer,iBufferSize - totalReadBytes);
- totalReadBytes += read;
- }
+ time_t now;
+ now = time(NULL);
- if(totalTimeWaited > BUFFER_READ_TIMEOUT)
+ if (last_pos_req_time_ == -1 || now > last_pos_req_time_ + 1)
+ {
+ long long length, cur_pos;
+ time_t duration;
+ if (GetBufferParams(length, duration, cur_pos))
{
- XBMC->Log(LOG_DEBUG, "Timeshifterbuffer timed out, waited : %d", totalTimeWaited);
+ ret_val = now - (time_t)((length - cur_pos) * duration / length);
}
+
+ last_pos_ = ret_val;
+ last_pos_req_time_ = now;
}
- return totalReadBytes;
+
+ return ret_val;
+}
+
+time_t TimeShiftBuffer::GetBufferTimeStart()
+{
+ time_t ret_val = 0;
+
+ time_t now;
+ now = time(NULL);
+
+ long long length, cur_pos;
+ time_t duration;
+ if (GetBufferParams(length, duration, cur_pos))
+ ret_val = now - duration;
+
+ return ret_val;
+}
+
+time_t TimeShiftBuffer::GetBufferTimeEnd()
+{
+ time_t now;
+ now = time(NULL);
+
+ return now;
}
View
32 addons/pvr.dvblink/src/TimeShiftBuffer.h
@@ -24,39 +24,35 @@
#pragma once
-#ifdef TARGET_WINDOWS
-#define DeleteFile DeleteFileA
-#endif
-
#include "libXBMC_addon.h"
#include "platform/util/StdString.h"
#include "libdvblinkremote/dvblinkremote.h"
-#include "platform/threads/threads.h"
#include "platform/util/util.h"
-#define STREAM_READ_BUFFER_SIZE 8192
-#define BUFFER_READ_TIMEOUT 10000
-#define BUFFER_READ_WAITTIME 50
-
-class TimeShiftBuffer : public PLATFORM::CThread
+class TimeShiftBuffer
{
public:
- TimeShiftBuffer(ADDON::CHelper_libXBMC_addon * XBMC, std::string streampath, std::string bufferpath);
+ TimeShiftBuffer(ADDON::CHelper_libXBMC_addon * XBMC, std::string streampath);
~TimeShiftBuffer(void);
+
int ReadData(unsigned char *pBuffer, unsigned int iBufferSize);
- bool IsValid();
long long Seek(long long iPosition, int iWhence);
long long Position();
long long Length();
- void Stop(void);
+ void Stop();
+
+ time_t GetPlayingTime();
+ time_t GetBufferTimeStart();
+ time_t GetBufferTimeEnd();
+
private:
- virtual void * Process(void);
+ bool ExecuteServerRequest(const std::string& url, std::vector<std::string>& response_values);
+ bool GetBufferParams(long long& length, time_t& duration, long long& cur_pos);
- std::string m_bufferPath;
void * m_streamHandle;
- void * m_filebufferReadHandle;
- void * m_filebufferWriteHandle;
- bool m_shifting;
ADDON::CHelper_libXBMC_addon * XBMC;
+ std::string streampath_;
+ time_t last_pos_req_time_;
+ time_t last_pos_;
};
View
117 addons/pvr.dvblink/src/client.cpp
@@ -26,11 +26,11 @@
#include "xbmc_pvr_dll.h"
#include "DVBLinkClient.h"
#include "platform/util/util.h"
+#include "platform/util/timeutils.h"
using namespace std;
using namespace ADDON;
-
#ifdef TARGET_WINDOWS
#define snprintf _snprintf
#endif
@@ -48,22 +48,44 @@ std::string g_szHostname = DEFAULT_HOST; ///< The Ho
long g_lPort = DEFAULT_PORT; ///< The DVBLink Connect Server listening port (default: 8080)
int g_iConnectTimeout = DEFAULT_TIMEOUT; ///< The Socket connection timeout
DVBLINK_STREAMTYPE g_eStreamType = DEFAULT_STREAMTYPE; ///< Stream type used by video stream
-std::string g_szClientname = DEFAULT_CLIENTNAME; ///< Name of dvblink client
+std::string g_szClientname; ///< Name of dvblink client
std::string g_szUsername = DEFAULT_USERNAME; ///< Username
std::string g_szPassword = DEFAULT_PASSWORD; ///< Password
-bool g_bUseChlHandle = DEFAULT_USECHLHANDLE; ///< Use channel handle instead of client id
bool g_bShowInfoMSG = DEFAULT_SHOWINFOMSG; ///< Show information messages
int g_iHeight = DEFAULT_HEIGHT; ///< Height of stream when using transcoding
int g_iWidth = DEFAULT_WIDTH; ///< Width of stream when using transcoding
int g_iBitrate = DEFAULT_BITRATE; ///< Bitrate of stream when using transcoding
std::string g_szAudiotrack = DEFAULT_AUDIOTRACK; ///< Audiotrack to include in stream when using transcoding
-std::string g_szTimeShiftBufferPath = DEFAULT_TIMESHIFTBUFFERPATH; ///< Path to timeshift buffer
bool g_bUseTimeshift = DEFAULT_USETIMESHIFT; ///< Use timeshift
CHelper_libXBMC_addon *XBMC = NULL;
CHelper_libXBMC_pvr *PVR = NULL;
extern "C" {
+static void generate_uuid(std::string& uuid)
+{
+ int64_t seed_value = PLATFORM::GetTimeMs();
+ seed_value = seed_value % 1000000000;
+ srand((unsigned int)seed_value);
+
+ //fill in uuid string from a template
+ std::string template_str = "xxxx-xx-xx-xx-xxxxxx";
+ for (size_t i=0; i<template_str.size(); i++)
+ {
+ if (template_str[i] != '-')
+ {
+ double a1 = rand();
+ double a3 = RAND_MAX;
+ unsigned char ch = (unsigned char)(a1 * 255 / a3);
+ char buf[16];
+ sprintf(buf, "%02x", ch);
+ uuid += buf;
+ } else
+ {
+ uuid += '-';
+ }
+ }
+}
ADDON_STATUS ADDON_Create(void* hdl, void* props)
{
@@ -89,6 +111,10 @@ ADDON_STATUS ADDON_Create(void* hdl, void* props)
XBMC->Log(LOG_DEBUG, "%s - Creating the PVR DVBlink add-on", __FUNCTION__);
+ //generate a guid to use as a client identification
+ generate_uuid(g_szClientname);
+ XBMC->Log(LOG_NOTICE, "Generated guid %s to use as a DVBLink client ID", g_szClientname.c_str());
+
m_CurStatus = ADDON_STATUS_UNKNOWN;
g_strUserPath = pvrprops->strUserPath;
g_strClientPath = pvrprops->strClientPath;
@@ -110,18 +136,6 @@ ADDON_STATUS ADDON_Create(void* hdl, void* props)
g_szHostname = DEFAULT_HOST;
}
- /* Read setting "client" from settings.xml */
- if (XBMC->GetSetting("client", buffer))
- {
- g_szClientname = buffer;
- }
- else
- {
- /* If setting is unknown fallback to defaults */
- XBMC->Log(LOG_ERROR, "Couldn't get 'clientname' setting, falling back to 'xbmc' as default");
- g_szClientname = DEFAULT_CLIENTNAME;
- }
-
/* Read setting "username" from settings.xml */
if (XBMC->GetSetting("username", buffer))
{
@@ -170,14 +184,6 @@ ADDON_STATUS ADDON_Create(void* hdl, void* props)
g_iConnectTimeout = DEFAULT_TIMEOUT;
}
- /* Read setting "ch_handle" from settings.xml */
- if (!XBMC->GetSetting("ch_handle", &g_bUseChlHandle))
- {
- /* If setting is unknown fallback to defaults */
- XBMC->Log(LOG_ERROR, "Couldn't get 'ch_handle' setting, falling back to 'true' as default");
- g_bUseChlHandle = DEFAULT_USECHLHANDLE;
- }
-
/* Read setting "timeshift" from settings.xml */
if (!XBMC->GetSetting("timeshift", &g_bUseTimeshift))
{
@@ -186,20 +192,7 @@ ADDON_STATUS ADDON_Create(void* hdl, void* props)
g_bUseTimeshift = DEFAULT_USETIMESHIFT;
}
- /* Read setting "timeshiftpath" from settings.xml */
- if (XBMC->GetSetting("timeshiftpath", buffer))
- {
- g_szTimeShiftBufferPath = buffer;
- }
- else
- {
- /* If setting is unknown fallback to defaults */
- XBMC->Log(LOG_ERROR, "Couldn't get 'timeshiftpath' setting, falling back to 'special://userdata/addon_data/pvr.dvblink/' as default");
- g_szTimeShiftBufferPath = DEFAULT_TIMESHIFTBUFFERPATH;
- }
-
-
- /* Read setting "ch_handle" from settings.xml */
+ /* Read setting "shoow info message" from settings.xml */
if (!XBMC->GetSetting("showinfomsg", &g_bShowInfoMSG))
{
/* If setting is unknown fallback to defaults */
@@ -245,7 +238,7 @@ ADDON_STATUS ADDON_Create(void* hdl, void* props)
/* Log the current settings for debugging purposes */
XBMC->Log(LOG_DEBUG, "settings: streamtype='%i' host='%s', port=%i, timeout=%i", g_eStreamType, g_szHostname.c_str(), g_lPort, g_iConnectTimeout);
- dvblinkclient = new DVBLinkClient(XBMC,PVR, g_szClientname, g_szHostname, g_lPort, g_bShowInfoMSG, g_szUsername, g_szPassword, g_bUseTimeshift, g_szTimeShiftBufferPath);
+ dvblinkclient = new DVBLinkClient(XBMC,PVR, g_szClientname, g_szHostname, g_lPort, g_bShowInfoMSG, g_szUsername, g_szPassword, g_bUseTimeshift);
m_CurStatus = ADDON_STATUS_OK;
m_bCreated = true;
@@ -287,15 +280,6 @@ ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue)
if (tmp_sHostname != g_szHostname)
return ADDON_STATUS_NEED_RESTART;
}
- else if (str == "client")
- {
- string tmp_sClientname;
- XBMC->Log(LOG_INFO, "Changed Setting 'client' from %s to %s", g_szClientname.c_str(), (const char*) settingValue);
- tmp_sClientname = g_szClientname;
- g_szClientname = (const char*) settingValue;
- if (tmp_sClientname != g_szClientname)
- return ADDON_STATUS_NEED_RESTART;
- }
else if (str == "username")
{
string tmp_sUsername;
@@ -338,26 +322,12 @@ ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue)
XBMC->Log(LOG_INFO, "Changed setting 'timeout' from %u to %u", g_iConnectTimeout, *(int*) settingValue);
g_iConnectTimeout = *(int*) settingValue;
}
- else if (str == "ch_handle")
- {
- XBMC->Log(LOG_INFO, "Changed Setting 'ch_handle' from %u to %u", g_bUseChlHandle, *(int*) settingValue);
- g_bUseChlHandle = *(bool*) settingValue;
- }
else if (str == "timeshift")
{
XBMC->Log(LOG_INFO, "Changed Setting 'timeshift' from %u to %u", g_bUseTimeshift, *(int*) settingValue);
g_bUseTimeshift = *(bool*) settingValue;
return ADDON_STATUS_NEED_RESTART;
}
- else if (str == "timeshiftpath")
- {
- string tmp_sTimeShiftBufferPath;
- XBMC->Log(LOG_INFO, "Changed Setting 'timeshiftpath' from %s to %s", g_szTimeShiftBufferPath.c_str(), (const char*) settingValue);
- tmp_sTimeShiftBufferPath = g_szTimeShiftBufferPath;
- g_szTimeShiftBufferPath = (const char*) settingValue;
- if (tmp_sTimeShiftBufferPath != g_szTimeShiftBufferPath)
- return ADDON_STATUS_NEED_RESTART;
- }
else if (str == "showinfomsg")
{
XBMC->Log(LOG_INFO, "Changed Setting 'showinfomsg' from %u to %u", g_bShowInfoMSG, *(int*) settingValue);
@@ -490,7 +460,7 @@ bool OpenLiveStream(const PVR_CHANNEL &channel)
void CloseLiveStream(void)
{
if (dvblinkclient)
- dvblinkclient->StopStreaming(g_bUseChlHandle);
+ dvblinkclient->StopStreaming(true);
}
const char * GetLiveStreamURL(const PVR_CHANNEL &channel)
@@ -528,6 +498,27 @@ long long LengthLiveStream(void)
return -1;
}
+time_t GetPlayingTime()
+{
+ if (dvblinkclient)
+ return dvblinkclient->GetPlayingTime();
+ return 0;
+}
+
+time_t GetBufferTimeStart()
+{
+ if (dvblinkclient)
+ return dvblinkclient->GetBufferTimeStart();
+ return 0;
+}
+
+time_t GetBufferTimeEnd()
+{
+ if (dvblinkclient)
+ return dvblinkclient->GetBufferTimeEnd();
+ return 0;
+}
+
void PauseStream(bool bPaused)
{
}
View
10 addons/pvr.dvblink/src/client.h
@@ -33,19 +33,16 @@ enum DVBLINK_STREAMTYPE {HTTP=0,RTP=1,HLS =2, ASF=3};
/* Client Settings default values */
#define DEFAULT_HOST "127.0.0.1"
-#define DEFAULT_PORT 8080
+#define DEFAULT_PORT 8100
#define DEFAULT_TIMEOUT 10
#define DEFAULT_STREAMTYPE HTTP
-#define DEFAULT_CLIENTNAME "xbmc"
#define DEFAULT_USERNAME ""
#define DEFAULT_PASSWORD ""
-#define DEFAULT_USECHLHANDLE true
#define DEFAULT_SHOWINFOMSG false
#define DEFAULT_HEIGHT 720
#define DEFAULT_WIDTH 576
#define DEFAULT_BITRATE 512
#define DEFAULT_AUDIOTRACK "eng"
-#define DEFAULT_TIMESHIFTBUFFERPATH "special://userdata/addon_data/pvr.dvblink/"
#define DEFAULT_USETIMESHIFT false
/* Client Settings */
@@ -60,13 +57,8 @@ extern int g_iHeight;
extern int g_iWidth;
extern int g_iBitrate;
extern std::string g_szAudiotrack;
-extern bool g_bUseChlHandle;
extern bool g_bShowInfoMSG;
extern bool g_bUseTimeshift;
-extern std::string g_szTimeShiftBufferPath;
-
-
extern ADDON::CHelper_libXBMC_addon *XBMC;
extern CHelper_libXBMC_pvr *PVR;
-
View
5 lib/libdvblinkremote/dvblinkremote.h
@@ -207,6 +207,11 @@ namespace dvblinkremote
const std::string DVBLINK_REMOTE_STREAM_TYPE_RAW_HTTP = "raw_http";
/**
+ * A constant string representing a Raw HTTP stream type with timeshifting capabilities.
+ */
+ const std::string DVBLINK_REMOTE_STREAM_TYPE_RAW_HTTP_TIMESHIFT = "raw_http_timeshift";
+
+ /**
* A constant string representing a Raw UDP stream type.
*/
const std::string DVBLINK_REMOTE_STREAM_TYPE_RAW_UDP = "raw_udp";
View
6 lib/libdvblinkremote/recording.cpp
@@ -34,6 +34,7 @@ Recording::Recording(const std::string& id, const std::string& scheduleId, const
m_program((Program*)program)
{
IsActive = false;
+ IsConflict = false;
}
Recording::Recording(Recording& recording)
@@ -43,6 +44,7 @@ Recording::Recording(Recording& recording)
m_channelId = recording.GetChannelID();
m_program = new Program(recording.GetProgram());
IsActive = false;
+ IsConflict = false;
}
Recording::~Recording()
@@ -143,6 +145,10 @@ bool GetRecordingsResponseSerializer::GetRecordingsResponseXmlDataDeserializer::
r->IsActive = Util::GetXmlFirstChildElementTextAsBoolean(&element, "is_active");
}
+ if (m_parent.HasChildElement(element, "is_conflict")) {
+ r->IsConflict = Util::GetXmlFirstChildElementTextAsBoolean(&element, "is_conflict");
+ }
+
m_recordingList.push_back(r);
return false;
View
25 lib/libdvblinkremote/request.h
@@ -514,6 +514,31 @@ namespace dvblinkremote {
};
/**
+ * Class for Raw HTTP stream requests that supports timeshifting.
+ * This is used as input parameter for the IDVBLinkRemoteConnection::PlayChannel method.
+ * @see IDVBLinkRemoteConnection::PlayChannel()
+ */
+ class RawHttpTimeshiftStreamRequest : public StreamRequest
+ {
+ public:
+ /**
+ * Initializes a new instance of the dvblinkremote::RawHttpStreamRequest class.
+ * @param serverAddress a constant string reference representing the DVBLink server address.
+ * @param dvbLinkChannelId a constant long representing the DVBLink channel identifier.
+ * @param clientId a constant string reference representing the unique identification string of the client.
+ * \remark \p serverAddress is the IP address/server network name of the DVBLink server.
+ * \remark \p clientId should be the same across all DVBLink Client API calls from a given client.
+ * It can be a uuid for example or id/mac of the client device.
+ */
+ RawHttpTimeshiftStreamRequest(const std::string& serverAddress, const long dvbLinkChannelId, const std::string& clientId);
+
+ /**
+ * Destructor for cleaning up allocated memory.
+ */
+ ~RawHttpTimeshiftStreamRequest();
+ };
+
+ /**
* Class for Raw UDP stream requests.
* This is used as input parameter for the IDVBLinkRemoteConnection::PlayChannel method.
* @see IDVBLinkRemoteConnection::PlayChannel()
View
5 lib/libdvblinkremote/response.h
@@ -509,6 +509,11 @@ namespace dvblinkremote {
bool IsActive;
/**
+ * Represents if the recording is conflicting with another recording.
+ */
+ bool IsConflict;
+
+ /**
* Gets the program of the recording.
* @return Recording program
*/
View
11 lib/libdvblinkremote/stream_request.cpp
@@ -73,6 +73,17 @@ RawHttpStreamRequest::~RawHttpStreamRequest()
}
+RawHttpTimeshiftStreamRequest::RawHttpTimeshiftStreamRequest(const std::string& serverAddress, const long channelDvbLinkId, const std::string& clientId)
+ : StreamRequest(serverAddress, channelDvbLinkId, clientId, DVBLINK_REMOTE_STREAM_TYPE_RAW_HTTP_TIMESHIFT)
+{
+
+}
+
+RawHttpTimeshiftStreamRequest::~RawHttpTimeshiftStreamRequest()
+{
+
+}
+
RawUdpStreamRequest::RawUdpStreamRequest(const std::string& serverAddress, const long channelDvbLinkId, const std::string& clientId, const std::string& clientAddress, const unsigned short int streamingPort)
: m_clientAddress(clientAddress), m_streamingPort(streamingPort), StreamRequest(serverAddress, channelDvbLinkId, clientId, DVBLINK_REMOTE_STREAM_TYPE_RAW_UDP)
{ }
View
2  lib/libdvblinkremote/util.cpp
@@ -202,7 +202,7 @@ bool Util::GetXmlFirstChildElementTextAsBoolean(const tinyxml2::XMLElement* pare
s = el->GetText();
}
- if (s && strcmp(s, "true") != 0)
+ if (s && strcmp(s, "true") == 0)
{
value = true;
}
Please sign in to comment.
Something went wrong with that request. Please try again.