@@ -221,6 +221,12 @@ PVR_ERROR CVNSIClientInstance::GetCapabilities(kodi::addon::PVRCapabilities& cap
221221 capabilities.SetSupportsRecordingsLifetimeChange (false );
222222 capabilities.SetSupportsDescrambleInfo (false );
223223
224+ if (GetProtocol () >= 14 )
225+ {
226+ capabilities.SetSupportsRecordingPlayCount (CVNSISettings::Get ().GetBackendResume ());
227+ capabilities.SetSupportsLastPlayedPosition (CVNSISettings::Get ().GetBackendResume ());
228+ }
229+
224230 return PVR_ERROR_NO_ERROR;
225231}
226232
@@ -583,17 +589,39 @@ PVR_ERROR CVNSIClientInstance::GetEPGForChannel(int channelUid,
583589 tag.SetTitle (vresp->extract_String ());
584590 tag.SetPlotOutline (vresp->extract_String ());
585591 tag.SetPlot (vresp->extract_String ());
586- tag.SetOriginalTitle (" " );
587- tag.SetCast (" " );
592+
593+ if (GetProtocol () >= 14 )
594+ {
595+ tag.SetIconPath (vresp->extract_String ());
596+ int season = vresp->extract_U32 ();
597+ int episode = vresp->extract_U32 ();
598+ if (season > 0 )
599+ tag.SetSeriesNumber (season);
600+ if (episode > 0 )
601+ tag.SetEpisodeNumber (episode);
602+ tag.SetFirstAired (vresp->extract_String ());
603+ tag.SetStarRating (vresp->extract_U32 ());
604+ tag.SetOriginalTitle (vresp->extract_String ());
605+ tag.SetCast (vresp->extract_String ());
606+ tag.SetDirector (vresp->extract_String ());
607+ tag.SetWriter (vresp->extract_String ());
608+ tag.SetIMDBNumber (vresp->extract_String ());
609+ }
610+ else
611+ {
612+ tag.SetSeriesNumber (EPG_TAG_INVALID_SERIES_EPISODE);
613+ tag.SetEpisodeNumber (EPG_TAG_INVALID_SERIES_EPISODE);
614+ tag.SetOriginalTitle (" " );
615+ tag.SetCast (" " );
616+ }
617+
588618 tag.SetDirector (" " );
589619 tag.SetWriter (" " );
590620 tag.SetYear (0 );
591621 tag.SetIMDBNumber (" " );
592622 if (!tag.GetPlotOutline ().empty ())
593623 tag.SetEpisodeName (tag.GetPlotOutline ());
594624 tag.SetFlags (EPG_TAG_FLAG_UNDEFINED);
595- tag.SetSeriesNumber (EPG_TAG_INVALID_SERIES_EPISODE);
596- tag.SetEpisodeNumber (EPG_TAG_INVALID_SERIES_EPISODE);
597625 tag.SetEpisodePartNumber (EPG_TAG_INVALID_SERIES_EPISODE);
598626
599627 results.Add (tag);
@@ -666,6 +694,9 @@ PVR_ERROR CVNSIClientInstance::GetAvailableRecordings(kodi::addon::PVRRecordings
666694 return PVR_ERROR_UNKNOWN;
667695 }
668696
697+ m_lastPlayed.clear ();
698+ m_playCount.clear ();
699+
669700 std::string strRecordingId;
670701 while (vresp->getRemainingLength () >= 5 * 4 + 5 )
671702 {
@@ -705,6 +736,38 @@ PVR_ERROR CVNSIClientInstance::GetAvailableRecordings(kodi::addon::PVRRecordings
705736 tag.SetPlot (vresp->extract_String ());
706737 tag.SetDirectory (vresp->extract_String ());
707738 tag.SetRecordingId (std::to_string (vresp->extract_U32 ()));
739+
740+ if (GetProtocol () >= 14 )
741+ {
742+ tag.SetThumbnailPath (vresp->extract_String ());
743+ tag.SetFanartPath (vresp->extract_String ());
744+ int season = vresp->extract_U32 ();
745+ int episode = vresp->extract_U32 ();
746+ if (season > 0 )
747+ tag.SetSeriesNumber (season);
748+ if (episode > 0 )
749+ tag.SetEpisodeNumber (episode);
750+
751+ tag.SetFirstAired (vresp->extract_String ());
752+
753+ int LastPlayedPosition = vresp->extract_U32 ();
754+
755+ if (CVNSISettings::Get ().GetBackendResume ())
756+ {
757+ tag.SetPlayCount (0 );
758+ tag.SetLastPlayedPosition (LastPlayedPosition);
759+ if (tag.GetLastPlayedPosition () > 0 )
760+ {
761+ if (tag.GetLastPlayedPosition () >= tag.GetDuration () - 60 )
762+ {
763+ tag.SetPlayCount (1 );
764+ tag.SetLastPlayedPosition (0 );
765+ }
766+ }
767+ m_lastPlayed[std::stoi (tag.GetRecordingId ())] = tag.GetLastPlayedPosition ();
768+ m_playCount[std::stoi (tag.GetRecordingId ())] = tag.GetPlayCount ();
769+ }
770+ }
708771
709772 results.Add (tag);
710773 }
@@ -947,6 +1010,92 @@ PVR_ERROR CVNSIClientInstance::GetRecordingEdl(const kodi::addon::PVRRecording&
9471010 }
9481011}
9491012
1013+ // Code for GetRecordingLastPlayedPosition, SetRecordingLastPlayedPosition and SetRecordingPlayCount
1014+ // mostly taken from https://github.com/kodi-pvr/pvr.nextpvr/blob/Matrix/src/Recordings.cpp
1015+ PVR_ERROR CVNSIClientInstance::GetRecordingLastPlayedPosition (const kodi::addon::PVRRecording& recording, int & position)
1016+ {
1017+ position = m_lastPlayed[std::stoi (recording.GetRecordingId ())];
1018+ if (position == recording.GetDuration ())
1019+ position = 0 ;
1020+ return PVR_ERROR_NO_ERROR;
1021+ }
1022+
1023+ // ==============================================================================
1024+ // / SetRecordingLastPlayedPosition will be called when
1025+ // / Set watched - postion = 0, play count incremented. Note it is not called if
1026+ // / the watched positions is already 0
1027+ // / Resume reset - position = 0
1028+ // / Recording start position = 0 at start of file
1029+ // / Recording end actual position or when end is in ignorepercentatend zone the
1030+ // / position is -1 with play count incremented
1031+ // / Set unwatched - Not called by core
1032+ // /
1033+ PVR_ERROR CVNSIClientInstance::SetRecordingLastPlayedPosition (const kodi::addon::PVRRecording& recording, int lastplayedposition)
1034+ {
1035+ try
1036+ {
1037+ cRequestPacket vrp;
1038+ vrp.init (VNSI_RECORDINGS_SETLASTPLAYEDPOSITION);
1039+
1040+ int originalPosition = lastplayedposition;
1041+ int current = m_playCount[std::stoi (recording.GetRecordingId ())];
1042+ if (recording.GetPlayCount () > current && lastplayedposition == 0 )
1043+ {
1044+ // Kodi rolled the play count but didn't send EOF
1045+ lastplayedposition = recording.GetDuration ();
1046+ m_playCount[std::stoi (recording.GetRecordingId ())] = recording.GetPlayCount ();
1047+ }
1048+
1049+ if ( m_lastPlayed[std::stoi (recording.GetRecordingId ())] != lastplayedposition )
1050+ {
1051+ if (lastplayedposition == -1 )
1052+ {
1053+ lastplayedposition = recording.GetDuration ();
1054+ }
1055+ }
1056+ vrp.add_U32 (std::stoi (recording.GetRecordingId ()));
1057+ vrp.add_U32 (lastplayedposition);
1058+
1059+ auto vresp = ReadResult (&vrp);
1060+ if (vresp == nullptr || vresp->noResponse ())
1061+ {
1062+ kodi::Log (ADDON_LOG_ERROR, " %s - Can't get response packed" , __func__);
1063+ return PVR_ERROR_UNKNOWN;
1064+ }
1065+
1066+ return PVR_ERROR_NO_ERROR;
1067+ }
1068+ catch (std::exception e)
1069+ {
1070+ kodi::Log (ADDON_LOG_ERROR, " %s - %s" , __func__, e.what ());
1071+ return PVR_ERROR_SERVER_ERROR;
1072+ }
1073+ }
1074+
1075+ // ==============================================================================
1076+ // / SetRecordingPlayCount will be called when
1077+ // / Set watched - play count increases
1078+ // / Set unwatched - count set to 0,
1079+ // / Recording start - no change in count
1080+ // / Recording end when end is in playcountminimumpercent zone then the count
1081+ // / is incremented
1082+ // /
1083+ PVR_ERROR CVNSIClientInstance::SetRecordingPlayCount (const kodi::addon::PVRRecording& recording, int count)
1084+ {
1085+ int current = m_playCount[std::stoi (recording.GetRecordingId ())];
1086+ kodi::Log (ADDON_LOG_DEBUG, " Playcount %s %d %d" , recording.GetTitle ().c_str (), count, current);
1087+ if (count < current)
1088+ {
1089+ // unwatch count is zero.
1090+ SetRecordingLastPlayedPosition (recording, 0 );
1091+ m_playCount[std::stoi (recording.GetRecordingId ())] = count;
1092+ }
1093+ else
1094+ {
1095+
1096+ }
1097+ return PVR_ERROR_NO_ERROR;
1098+ }
9501099
9511100/* ******************************************/
9521101/* * PVR Timer Functions **/
0 commit comments