mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-skindesigner.git
				synced 2023-10-19 15:58:31 +00:00 
			
		
		
		
	In displayreplay the tokens recstart, playbacktime and timeshiftrest added to display start time, actual playback time and the rest of the actual recording in timeshiftmode.
		
			
				
	
	
		
			425 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			425 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #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<string, int>("background", (int)eVeDisplayReplay::background));
 | |
|     viewElementNames.insert(pair<string, int>("backgroundmodeonly", (int)eVeDisplayReplay::backgroundmodeonly));
 | |
|     viewElementNames.insert(pair<string, int>("datetime", (int)eVeDisplayReplay::datetime));
 | |
|     viewElementNames.insert(pair<string, int>("time", (int)eVeDisplayReplay::time));
 | |
|     viewElementNames.insert(pair<string, int>("scrapercontent", (int)eVeDisplayReplay::scrapercontent));
 | |
|     viewElementNames.insert(pair<string, int>("currentweather", (int)eVeDisplayReplay::currentweather));
 | |
|     viewElementNames.insert(pair<string, int>("rectitle", (int)eVeDisplayReplay::rectitle));
 | |
|     viewElementNames.insert(pair<string, int>("recinfo", (int)eVeDisplayReplay::recinfo));
 | |
|     viewElementNames.insert(pair<string, int>("currenttime", (int)eVeDisplayReplay::currenttime));
 | |
|     viewElementNames.insert(pair<string, int>("timeshifttimes", (int)eVeDisplayReplay::timeshifttimes));
 | |
|     viewElementNames.insert(pair<string, int>("endtime", (int)eVeDisplayReplay::endtime));
 | |
|     viewElementNames.insert(pair<string, int>("totaltime", (int)eVeDisplayReplay::totaltime));
 | |
|     viewElementNames.insert(pair<string, int>("progressbar", (int)eVeDisplayReplay::progressbar));
 | |
|     viewElementNames.insert(pair<string, int>("cutmarks", (int)eVeDisplayReplay::cutmarks));
 | |
|     viewElementNames.insert(pair<string, int>("cutmarks", (int)eVeDisplayReplay::cutmarks));
 | |
|     viewElementNames.insert(pair<string, int>("controlicons", (int)eVeDisplayReplay::controlicons));
 | |
|     viewElementNames.insert(pair<string, int>("controliconsmodeonly", (int)eVeDisplayReplay::controliconsmodeonly));
 | |
|     viewElementNames.insert(pair<string, int>("progressmodeonly", (int)eVeDisplayReplay::progressmodeonly));
 | |
|     viewElementNames.insert(pair<string, int>("jump", (int)eVeDisplayReplay::jump));
 | |
|     viewElementNames.insert(pair<string, int>("message", (int)eVeDisplayReplay::message));
 | |
|     viewElementNames.insert(pair<string, int>("onpause", (int)eVeDisplayReplay::onpause));
 | |
|     viewElementNames.insert(pair<string, int>("onpausemodeonly", (int)eVeDisplayReplay::onpausemodeonly));
 | |
|     viewElementNames.insert(pair<string, int>("customtokens", (int)eVeDisplayReplay::customtokens));
 | |
| }
 | |
| 
 | |
| void cViewReplay::SetViewElementObjects(void) {
 | |
|     for (int i = 0; i < numViewElements; i++) {
 | |
|         if (!viewElements[i])
 | |
|             continue;
 | |
|         if (dynamic_cast<cVeMessage*>(viewElements[i])) 
 | |
|         {
 | |
|             veMessage = dynamic_cast<cVeMessage*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrScraperContent*>(viewElements[i])) 
 | |
|         {
 | |
|             veScraperContent = dynamic_cast<cVeDrScraperContent*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeCustomTokens*>(viewElements[i])) 
 | |
|         {
 | |
|             veCustomTokens = dynamic_cast<cVeCustomTokens*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrRecTitle*>(viewElements[i])) 
 | |
|         {
 | |
|             veRecTitle = dynamic_cast<cVeDrRecTitle*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrRecInfo*>(viewElements[i])) 
 | |
|         {
 | |
|             veRecInfo = dynamic_cast<cVeDrRecInfo*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrCurrentTime*>(viewElements[i])) 
 | |
|         {
 | |
|             veCurrentTime = dynamic_cast<cVeDrCurrentTime*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrTotalTime*>(viewElements[i])) 
 | |
|         {
 | |
|             veTotalTime = dynamic_cast<cVeDrTotalTime*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrTimeshiftTimes*>(viewElements[i]))
 | |
|         {
 | |
|             veTimeshiftTimes = dynamic_cast<cVeDrTimeshiftTimes*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrEndTime*>(viewElements[i])) 
 | |
|         {
 | |
|             veEndTime = dynamic_cast<cVeDrEndTime*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrProgressBar*>(viewElements[i])) 
 | |
|         {
 | |
|             veProgressbar = dynamic_cast<cVeDrProgressBar*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrCutMarks*>(viewElements[i])) 
 | |
|         {
 | |
|             veCutMarks = dynamic_cast<cVeDrCutMarks*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrProgressModeonly*>(viewElements[i])) 
 | |
|         {
 | |
|             veProgressModeOnly = dynamic_cast<cVeDrProgressModeonly*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrControlIcons*>(viewElements[i]) && (i == (int)eVeDisplayReplay::controlicons)) 
 | |
|         {
 | |
|             veControlIcons = dynamic_cast<cVeDrControlIcons*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrControlIcons*>(viewElements[i]) && i == (int)eVeDisplayReplay::controliconsmodeonly) 
 | |
|         {
 | |
|             veControlIconsModeOnly = dynamic_cast<cVeDrControlIcons*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrJump*>(viewElements[i])) 
 | |
|         {
 | |
|             veJump = dynamic_cast<cVeDrJump*>(viewElements[i]);
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrOnPause*>(viewElements[i]) && i == (int)eVeDisplayReplay::onpause)
 | |
|         {
 | |
|             veOnPause = dynamic_cast<cVeDrOnPause*>(viewElements[i]);
 | |
|             veOnPause->SetDetached();
 | |
|             veOnPause->UnsetWaitOnWakeup();
 | |
|         }
 | |
|         else if (dynamic_cast<cVeDrOnPause*>(viewElements[i])  && i == (int)eVeDisplayReplay::onpausemodeonly) 
 | |
|         {
 | |
|             veOnPauseModeOnly = dynamic_cast<cVeDrOnPause*>(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;
 | |
|     reclength = -1;
 | |
|     timeShiftActive = false;
 | |
|     timeShiftFramesTotal = -1;
 | |
|     timeShiftLength = -1;
 | |
|     timeShiftDuration = "";
 | |
|     timeshiftrest = "";
 | |
|     if (veCustomTokens)
 | |
|         veCustomTokens->Reset();
 | |
|     if (veTimeshiftTimes)
 | |
|         veTimeshiftTimes->Set(cString(""), cString(""), cString(""));
 | |
|     if (veEndTime)
 | |
|         veEndTime->Set(cString(""));
 | |
|     if (veCutMarks)
 | |
|         veCutMarks->Reset();
 | |
|     timersLoaded = false;
 | |
|     globalTimers.ClearTimers();
 | |
| }
 | |
| 
 | |
| void cViewReplay::GetGlobalTimers(void) {
 | |
|     if (!timersLoaded) {
 | |
|         timersLoaded = true;
 | |
|         globalTimers.LoadTimers();
 | |
|     }
 | |
| }
 | |
| 
 | |
| void cViewReplay::SetTimeShiftValues(int current, int total) {
 | |
|     if (!recording)
 | |
|         return;
 | |
|     const char *recName = recording->Name();
 | |
|     if (recName && *recName != '@')
 | |
|         return;
 | |
|     timeShiftActive = false;
 | |
| #if APIVERSNUM >= 20101
 | |
|     int usage = recording->IsInUse();
 | |
|     if (usage & ruTimer)
 | |
|         timeShiftActive = true;
 | |
|     else {
 | |
|         GetGlobalTimers();
 | |
|         if (globalTimers.IsRecording(recording))
 | |
|             timeShiftActive = true;
 | |
|     }
 | |
| #endif
 | |
|     if (!timeShiftActive)
 | |
|         return;
 | |
|     const cRecordingInfo *recInfo = recording->Info();
 | |
|     if (!recInfo)
 | |
|         return;
 | |
|     const cSchedule *Schedule = NULL;
 | |
|     {
 | |
|     LOCK_SCHEDULES_READ;
 | |
|     Schedule = Schedules->GetSchedule(recInfo->ChannelID());
 | |
|     }
 | |
|     if (!Schedule)
 | |
|         return;
 | |
|     // Get event at actual recording position
 | |
|     const cEvent *eventEnde = Schedule->GetEventAround(time(0));
 | |
|     if (!eventEnde)
 | |
|         return;
 | |
|     // End of live program
 | |
|     time_t liveEventStop = eventEnde->EndTime();
 | |
|     // Begin of timeshift recording
 | |
|     time_t recordingStart = time(0) - recording->LengthInSeconds();
 | |
|     // actual timeshiftlength
 | |
|     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;
 | |
|     const cEvent *eventReplay = Schedule->GetEventAround(time(0) - timeShiftSecondsAfter);
 | |
|     // Display title at replay position
 | |
|     if (eventReplay && eventReplay != lastEvent && veRecTitle) {
 | |
|         veRecTitle->Set(recording, eventReplay, true);
 | |
|         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 || reclength == 0)
 | |
|         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 || reclength == 0)
 | |
|         return;
 | |
|     int totalLength = total;
 | |
|     int recordingLength = reclength;
 | |
|     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)
 | |
|         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();
 | |
| }
 |