#include "viewdisplayreplay.h" /************************************************************************************ * cViewReplay ************************************************************************************/ cViewReplay::cViewReplay(void) { veCustomTokens = NULL; veTimeshiftTimes = NULL; veEndTime = NULL; veMessage = NULL; veScraperContent = NULL; veRecTitle = NULL; veRecInfo = NULL; veCurrentTime = NULL; veTotalTime = NULL; veProgressbar = NULL; veCutMarks = NULL; veProgressModeOnly = NULL; veControlIcons = NULL; veControlIconsModeOnly = NULL; veJump = NULL; veOnPause = NULL; veOnPauseModeOnly = NULL; ClearVariables(); viewId = eViewType::DisplayReplay; viewName = strdup("displayreplay"); numViewElements = (int)eVeDisplayReplay::count; viewElements = new cViewElement*[numViewElements]; for (int i=0; i < numViewElements; i++) { viewElements[i] = NULL; } SetViewElements(); } cViewReplay::~cViewReplay() { } void cViewReplay::SetViewElements(void) { viewElementNames.insert(pair("background", (int)eVeDisplayReplay::background)); viewElementNames.insert(pair("backgroundmodeonly", (int)eVeDisplayReplay::backgroundmodeonly)); viewElementNames.insert(pair("datetime", (int)eVeDisplayReplay::datetime)); viewElementNames.insert(pair("time", (int)eVeDisplayReplay::time)); viewElementNames.insert(pair("scrapercontent", (int)eVeDisplayReplay::scrapercontent)); viewElementNames.insert(pair("currentweather", (int)eVeDisplayReplay::currentweather)); viewElementNames.insert(pair("rectitle", (int)eVeDisplayReplay::rectitle)); viewElementNames.insert(pair("recinfo", (int)eVeDisplayReplay::recinfo)); viewElementNames.insert(pair("currenttime", (int)eVeDisplayReplay::currenttime)); viewElementNames.insert(pair("timeshifttimes", (int)eVeDisplayReplay::timeshifttimes)); viewElementNames.insert(pair("endtime", (int)eVeDisplayReplay::endtime)); viewElementNames.insert(pair("totaltime", (int)eVeDisplayReplay::totaltime)); viewElementNames.insert(pair("progressbar", (int)eVeDisplayReplay::progressbar)); viewElementNames.insert(pair("cutmarks", (int)eVeDisplayReplay::cutmarks)); viewElementNames.insert(pair("cutmarks", (int)eVeDisplayReplay::cutmarks)); viewElementNames.insert(pair("controlicons", (int)eVeDisplayReplay::controlicons)); viewElementNames.insert(pair("controliconsmodeonly", (int)eVeDisplayReplay::controliconsmodeonly)); viewElementNames.insert(pair("progressmodeonly", (int)eVeDisplayReplay::progressmodeonly)); viewElementNames.insert(pair("jump", (int)eVeDisplayReplay::jump)); viewElementNames.insert(pair("message", (int)eVeDisplayReplay::message)); viewElementNames.insert(pair("onpause", (int)eVeDisplayReplay::onpause)); viewElementNames.insert(pair("onpausemodeonly", (int)eVeDisplayReplay::onpausemodeonly)); viewElementNames.insert(pair("customtokens", (int)eVeDisplayReplay::customtokens)); } void cViewReplay::SetViewElementObjects(void) { for (int i = 0; i < numViewElements; i++) { if (!viewElements[i]) continue; if (dynamic_cast(viewElements[i])) { veMessage = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veScraperContent = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veCustomTokens = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veRecTitle = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veRecInfo = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veCurrentTime = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veTotalTime = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veTimeshiftTimes = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veEndTime = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veProgressbar = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veCutMarks = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veProgressModeOnly = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i]) && (i == (int)eVeDisplayReplay::controlicons)) { veControlIcons = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i]) && i == (int)eVeDisplayReplay::controliconsmodeonly) { veControlIconsModeOnly = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i])) { veJump = dynamic_cast(viewElements[i]); } else if (dynamic_cast(viewElements[i]) && i == (int)eVeDisplayReplay::onpause) { veOnPause = dynamic_cast(viewElements[i]); veOnPause->SetDetached(); veOnPause->UnsetWaitOnWakeup(); } else if (dynamic_cast(viewElements[i]) && i == (int)eVeDisplayReplay::onpausemodeonly) { veOnPauseModeOnly = dynamic_cast(viewElements[i]); veOnPauseModeOnly->SetDetached(); veOnPauseModeOnly->UnsetWaitOnWakeup(); } } } void cViewReplay::PreCache(void) { cView::PreCache(); SetViewelementsAnimOut(); } void cViewReplay::ClearVariables(void) { cView::ClearVariables(); recording = NULL; lastEvent = NULL; modeOnly = false; lastFlush = 0; lastFlushModeOnly = 0; message = false; timeShiftActive = NoRec; timeShiftFramesTotal = -1; timeShiftLength = -1; timeShiftDuration = ""; timeshiftrest = ""; if (veCustomTokens) veCustomTokens->Reset(); if (veTimeshiftTimes) veTimeshiftTimes->Set(cString(""), cString(""), cString("")); if (veEndTime) veEndTime->Set(cString("")); timersLoaded = false; globalTimers.ClearTimers(); } void cViewReplay::GetGlobalTimers(void) { if (!timersLoaded) { timersLoaded = true; globalTimers.LoadTimers(); } } void cViewReplay::SetTimeShiftValues(int current, int total) { timeShiftActive = NoRec; if (!recording) return; #if APIVERSNUM >= 20101 int usage = recording->IsInUse(); if (usage & ruTimer) timeShiftActive = NormalRec; else { GetGlobalTimers(); if (globalTimers.IsRecording(recording)) timeShiftActive = NormalRec; } #endif if (!timeShiftActive) return; const char *recName = recording->Name(); if (recName && *recName == '@') timeShiftActive = TimeshiftRec; const cRecordingInfo *recInfo = recording->Info(); if (!recInfo) return; const cSchedule *Schedule = NULL; if (timeShiftActive == TimeshiftRec) { { LOCK_SCHEDULES_READ; Schedule = Schedules->GetSchedule(recInfo->ChannelID()); } if (!Schedule) return; } // Get event at actual recording position const cEvent *event = (timeShiftActive == TimeshiftRec) ? Schedule->GetEventAround(time(0)) : recInfo->GetEvent(); if (!event) return; // End of live program time_t liveEventStop = event->EndTime(); // Begin of timeshift recording time_t recordingStart = time(0) - recording->LengthInSeconds(); // actual timeshiftlength in sec timeShiftLength = liveEventStop - recordingStart; // timeshiftlength until end of live program timeShiftFramesTotal = total * ((double)timeShiftLength / (double)recording->LengthInSeconds()); // Get event at actual replay position (add 30sec for a better match) int timeShiftSecondsAfter = (int)(recording->LengthInSeconds() * (1.0 - (double)current / (double)total)) + 30; if (timeShiftActive == TimeshiftRec) { const cEvent *eventReplay = Schedule->GetEventAround(time(0) - timeShiftSecondsAfter); // Display title at replay position if (veRecTitle && eventReplay != lastEvent) { veRecTitle->Set(recording, eventReplay, timeShiftActive); veRecTitle->Parse(); lastEvent = eventReplay; } } int mins = (timeShiftLength / 60) % 60; int hours = (timeShiftLength / 3600) % 24; timeShiftDuration = cString::sprintf("%d:%02d", hours, mins); mins = (timeShiftSecondsAfter / 60) % 60; hours = (timeShiftSecondsAfter / 3600) % 24; timeshiftrest = cString::sprintf("%d:%02d", hours, mins); } void cViewReplay::SetRecording(const cRecording *recording) { this->recording = recording; if (veRecTitle) { veRecTitle->Set(recording); } if (veRecInfo) { veRecInfo->Set(recording); } if (veScraperContent) { veScraperContent->Set(recording); } } void cViewReplay::SetTitle(const char *title) { if (veRecTitle) { veRecTitle->Set(title); } if (veRecInfo) { veRecInfo->Set(NULL); } if (veScraperContent) { veScraperContent->Set(NULL); } } void cViewReplay::SetCurrent(const char *current) { if (veCurrentTime) veCurrentTime->Set(current, timeShiftActive); Render((int)eVeDisplayReplay::currenttime); } void cViewReplay::SetTotal(const char *total) { if (veTotalTime) veTotalTime->Set(total, *timeShiftDuration, timeShiftActive); Render((int)eVeDisplayReplay::totaltime); } void cViewReplay::SetTimeshiftTimes(int current, int total) { if (!veTimeshiftTimes || !recording) return; time_t recordingStart = 0; time_t playbackTime = 0; if (timeShiftActive) { recordingStart = time(0) - recording->LengthInSeconds(); playbackTime = time(0) - (int)(recording->LengthInSeconds() * (1.0 - (double)current / (double)total)); } else recordingStart = recording->Start(); veTimeshiftTimes->Set(TimeString(recordingStart), TimeString(playbackTime), timeshiftrest, timeShiftActive); Render((int)eVeDisplayReplay::timeshifttimes); } void cViewReplay::SetEndTime(int current, int total) { if (!veEndTime || !recording) return; int totalLength = total; int recordingLength = recording->LengthInSeconds(); if (timeShiftActive && timeShiftFramesTotal > 0) { totalLength = timeShiftFramesTotal; recordingLength = timeShiftLength; } double rest = (double)(totalLength - current) / (double)totalLength; time_t end = time(0) + rest * recordingLength; veEndTime->Set(TimeString(end), timeShiftActive); Render((int)eVeDisplayReplay::endtime); } void cViewReplay::SetProgressbar(int current, int total) { SetTimeShiftValues(current, total); if (veProgressbar) veProgressbar->Set(current, total, timeShiftActive, timeShiftFramesTotal); Render((int)eVeDisplayReplay::progressbar); } void cViewReplay::SetMarks(const cMarks *marks, int current, int total) { if (!veCutMarks) return; veCutMarks->Set(marks, current, total, timeShiftActive, timeShiftFramesTotal); Render((int)eVeDisplayReplay::cutmarks); } void cViewReplay::SetControlIcons(bool play, bool forward, int speed) { if (!modeOnly) { if (veControlIcons) veControlIcons->Set(play, forward, speed); Render((int)eVeDisplayReplay::controlicons); } else { if (veControlIconsModeOnly) veControlIconsModeOnly->Set(play, forward, speed); Render((int)eVeDisplayReplay::controliconsmodeonly); } } void cViewReplay::SetJump(const char *jump) { if (veJump) { if (!jump) veJump->Clear(); else veJump->Set(jump); } Render((int)eVeDisplayReplay::jump); } void cViewReplay::SetMessage(eMessageType type, const char *text) { if (veMessage) { if (text) veMessage->Set(type, text); else veMessage->Clear(); } Render((int)eVeDisplayReplay::message); } void cViewReplay::StartOnPause(const char *recfilename) { cVeDrOnPause *onPause = (!modeOnly) ? veOnPause : veOnPauseModeOnly; if (!onPause) return; onPause->Set(recfilename); onPause->Parse(true); } void cViewReplay::ClearOnPause(void) { cVeDrOnPause *onPause = (!modeOnly) ? veOnPause : veOnPauseModeOnly; if (!onPause) return; onPause->Close(); } void cViewReplay::DelayOnPause(void) { if (!veOnPause) return; if (!veOnPause->Started()) return; veOnPause->ResetSleep(); } void cViewReplay::Flush(void) { if (init) { if (!modeOnly) { Render((int)eVeDisplayReplay::background); Render((int)eVeDisplayReplay::rectitle); Render((int)eVeDisplayReplay::recinfo); Render((int)eVeDisplayReplay::scrapercontent); Render((int)eVeDisplayReplay::currentweather); Render((int)eVeDisplayReplay::customtokens); } else { Render((int)eVeDisplayReplay::backgroundmodeonly); } } time_t now = time(0); if (!modeOnly && (now != lastFlush)) { Render((int)eVeDisplayReplay::datetime); Render((int)eVeDisplayReplay::time); Render((int)eVeDisplayChannel::customtokens); lastFlush = now; } if (modeOnly) { SetProgressModeOnly(); } cView::Flush(); } void cViewReplay::SetProgressModeOnly(void) { if (!veProgressModeOnly) return; time_t now = time(0); if (now == lastFlushModeOnly) { return; } lastFlushModeOnly = now; cControl *control = cControl::Control(); if (!control) return; double fps = control->FramesPerSecond(); int current = 0; int total = 0; if (!control->GetIndex(current, total)) return; veProgressModeOnly->Set(fps, current, total); if (veProgressModeOnly->Parse()) veProgressModeOnly->Render(); }