4343
4444using namespace KODI ;
4545
46- CApplicationPlayerCallback::CApplicationPlayerCallback ()
47- {
48- }
49-
5046void CApplicationPlayerCallback::OnPlayBackEnded ()
5147{
5248 CLog::LogF (LOGDEBUG, " call" );
@@ -107,30 +103,10 @@ void CApplicationPlayerCallback::OnPlayBackStarted(const CFileItem& file)
107103 CServiceBroker::GetGUI ()->GetWindowManager ().SendThreadMessage (msg);
108104}
109105
110- void CApplicationPlayerCallback::OnPlayerCloseFile (const CFileItem& file,
111- const CBookmark& bookmarkParam)
106+ namespace
107+ {
108+ void UpdateRemovableBlurayPath (CFileItem& fileItem, bool updateStreamDetails)
112109{
113- auto & components = CServiceBroker::GetAppComponents ();
114- const auto stackHelper = components.GetComponent <CApplicationStackHelper>();
115-
116- std::unique_lock lock (stackHelper->m_critSection );
117-
118- CFileItem fileItem (file);
119- CBookmark bookmark = bookmarkParam;
120- CBookmark resumeBookmark;
121- bool playCountUpdate = false ;
122- float percent = 0 .0f ;
123-
124- // Make sure we don't reset existing bookmark etc. on eg. player start failure
125- if (bookmark.timeInSeconds == 0.0 )
126- return ;
127-
128- // Adjust paths of new fileItem for physical/removable blurays
129- // DynPath contains the mpls (playlist) played
130- // VideoInfoTag()->m_strFileNameAndPath contains the removable:// path (if played through Disc node)
131- // otherwise if played through Video->Files we need to retrieve the removable:// path
132- // We need to update DynPath with the removable:// path (for the database), keeping the playlist
133- #ifdef HAVE_LIBBLURAY
134110 if (fileItem.HasVideoInfoTag ())
135111 {
136112 const std::string dynPath{fileItem.GetDynPath ()};
@@ -146,7 +122,8 @@ void CApplicationPlayerCallback::OnPlayerCloseFile(const CFileItem& file,
146122 else
147123 {
148124#ifdef HAS_OPTICAL_DRIVE
149- // Played through Video->Files
125+ // Played through Video->Files or Movie/TV Shows etc..
126+ // Only check if system supports optical (physical/mounted) drives
150127 ::UTILS::DISCS::DiscInfo info{
151128 CServiceBroker::GetMediaManager ().GetDiscInfo (fileUrl.GetHostName ())};
152129 if (!info.empty () && info.type == ::UTILS::DISCS::DiscType::BLURAY)
@@ -155,6 +132,7 @@ void CApplicationPlayerCallback::OnPlayerCloseFile(const CFileItem& file,
155132 }
156133#endif
157134 }
135+ // Will be empty if not a physical/mounted disc (ie. an ISO file)
158136 if (!url.Get ().empty ())
159137 {
160138 url.SetFileName (fileUrl.GetFileName ());
@@ -166,7 +144,7 @@ void CApplicationPlayerCallback::OnPlayerCloseFile(const CFileItem& file,
166144 }
167145
168146 // Get streamdetails from file
169- if (file. GetProperty ( " update_stream_details " ). asBoolean ( false ) )
147+ if (updateStreamDetails )
170148 {
171149 XFILE::CBlurayDirectory dir;
172150 CFileItemList items;
@@ -179,70 +157,112 @@ void CApplicationPlayerCallback::OnPlayerCloseFile(const CFileItem& file,
179157 }
180158 }
181159 }
182- # endif
160+ }
183161
184- if (stackHelper->GetRegisteredStack (fileItem) != nullptr )
162+ void UpdateStackAndItem (const CFileItem& file,
163+ CFileItem& fileItem,
164+ CBookmark& bookmark,
165+ const std::shared_ptr<CApplicationStackHelper>& stackHelper)
166+ {
167+ if (stackHelper->GetRegisteredStackTotalTimeMs (fileItem) > 0 )
185168 {
186- if (stackHelper->GetRegisteredStackTotalTimeMs (fileItem) > 0 )
187- {
188- // Regular (not disc image) stack case: We have to save the bookmark on the stack.
189- fileItem = *stackHelper->GetRegisteredStack (file);
169+ // Regular (not disc image) stack case: We have to save the bookmark on the stack.
170+ fileItem = *stackHelper->GetRegisteredStack (file);
190171
191- // The bookmark coming from the player is only relative to the current part, thus needs
192- // to be corrected with these attributes (start time will be 0 for non-stackparts).
193- bookmark.timeInSeconds +=
194- static_cast <double >(stackHelper->GetRegisteredStackPartStartTimeMs (file)) / 1000.0 ;
172+ // The bookmark coming from the player is only relative to the current part, thus needs
173+ // to be corrected with these attributes (start time will be 0 for non-stackparts).
174+ bookmark.timeInSeconds +=
175+ static_cast <double >(stackHelper->GetRegisteredStackPartStartTimeMs (file)) / 1000.0 ;
195176
196- const uint64_t registeredStackTotalTimeMs{stackHelper->GetRegisteredStackTotalTimeMs (file)};
197- if (registeredStackTotalTimeMs > 0 )
198- bookmark.totalTimeInSeconds = static_cast <double >(registeredStackTotalTimeMs) / 1000.0 ;
199- }
200- // Any stack case: We need to save the part number.
201- bookmark.partNumber =
202- stackHelper->GetRegisteredStackPartNumber (file) + 1 ; // CBookmark part numbers are 1-based
177+ const uint64_t registeredStackTotalTimeMs{stackHelper->GetRegisteredStackTotalTimeMs (file)};
178+ if (registeredStackTotalTimeMs > 0 )
179+ bookmark.totalTimeInSeconds = static_cast <double >(registeredStackTotalTimeMs) / 1000.0 ;
203180 }
181+ // Any stack case: We need to save the part number.
182+ bookmark.partNumber =
183+ stackHelper->GetRegisteredStackPartNumber (file) + 1 ; // CBookmark part numbers are 1-based
184+ }
204185
205- percent = bookmark.timeInSeconds / bookmark.totalTimeInSeconds * 100 ;
186+ bool WithinPercentOfEnd (const CBookmark& bookmark, float ignorePercentAtEnd)
187+ {
188+ return ignorePercentAtEnd > 0 .0f &&
189+ (bookmark.totalTimeInSeconds - bookmark.timeInSeconds ) <
190+ (static_cast <double >(ignorePercentAtEnd) * bookmark.totalTimeInSeconds / 100.0 );
191+ }
206192
207- const std::shared_ptr<CAdvancedSettings> advancedSettings =
208- CServiceBroker::GetSettingsComponent ()->GetAdvancedSettings ();
193+ bool UpdatePlayCount (const CFileItem& fileItem, const CBookmark& bookmark)
194+ {
195+ if (bookmark.timeInSeconds < 0.0 )
196+ return true ; // Finished
209197
210- if ((MUSIC::IsAudio (fileItem) && advancedSettings->m_audioPlayCountMinimumPercent > 0 &&
211- percent >= advancedSettings->m_audioPlayCountMinimumPercent ) ||
212- (VIDEO::IsVideo (fileItem) && advancedSettings->m_videoPlayCountMinimumPercent > 0 &&
213- percent >= advancedSettings->m_videoPlayCountMinimumPercent ))
214- {
215- playCountUpdate = true ;
216- }
198+ const std::shared_ptr<CAdvancedSettings> advancedSettings{
199+ CServiceBroker::GetSettingsComponent ()->GetAdvancedSettings ()};
200+ const float percent{static_cast <float >(bookmark.timeInSeconds / bookmark.totalTimeInSeconds ) *
201+ 100 .0f };
217202
218- if (advancedSettings->m_videoIgnorePercentAtEnd > 0 &&
219- bookmark.totalTimeInSeconds - bookmark.timeInSeconds <
220- 0.01 * static_cast <double >(advancedSettings->m_videoIgnorePercentAtEnd ) *
221- bookmark.totalTimeInSeconds )
222- {
223- resumeBookmark.timeInSeconds = -1.0 ;
224- }
225- else if (bookmark.timeInSeconds > advancedSettings->m_videoIgnoreSecondsAtStart )
226- {
227- resumeBookmark = bookmark;
228- if (stackHelper->GetRegisteredStack (file) != nullptr )
229- {
230- // also update video info tag with total time
231- fileItem.GetVideoInfoTag ()->m_streamDetails .SetVideoDuration (
232- 0 , resumeBookmark.totalTimeInSeconds );
233- }
234- }
235- else
203+ if (MUSIC::IsAudio (fileItem) && advancedSettings->m_audioPlayCountMinimumPercent > 0 &&
204+ percent >= advancedSettings->m_audioPlayCountMinimumPercent )
205+ return true ;
206+
207+ if (VIDEO::IsVideo (fileItem) && advancedSettings->m_videoPlayCountMinimumPercent > 0 &&
208+ percent >= advancedSettings->m_videoPlayCountMinimumPercent )
209+ return true ;
210+
211+ return false ;
212+ }
213+ } // namespace
214+
215+ void CApplicationPlayerCallback::OnPlayerCloseFile (const CFileItem& file,
216+ const CBookmark& bookmarkParam)
217+ {
218+ auto & components{CServiceBroker::GetAppComponents ()};
219+ const auto stackHelper{components.GetComponent <CApplicationStackHelper>()};
220+
221+ std::unique_lock lock (stackHelper->m_critSection );
222+
223+ CFileItem fileItem{file};
224+ CBookmark bookmark{bookmarkParam};
225+
226+ // Make sure we don't reset existing bookmark etc. on eg. player start failure
227+ if (bookmark.timeInSeconds == 0.0 )
228+ return ;
229+
230+ #ifdef HAVE_LIBBLURAY
231+ // Adjust paths of new fileItem for physical/removable blurays
232+ // DynPath contains the mpls (playlist) played
233+ // VideoInfoTag()->m_strFileNameAndPath contains the removable:// path (if played through Disc node)
234+ // otherwise if played through Video->Files we need to retrieve the removable:// path
235+ // We need to update DynPath with the removable:// path (for the database), keeping the playlist
236+ // Also flag if we need to update stream details from the played file
237+ UpdateRemovableBlurayPath (fileItem, file.GetProperty (" update_stream_details" ).asBoolean (false ));
238+ #endif
239+
240+ // Update the stack
241+ const bool isStack{stackHelper->GetRegisteredStack (file) != nullptr };
242+ if (isStack)
243+ UpdateStackAndItem (file, fileItem, bookmark, stackHelper);
244+
245+ const std::shared_ptr<CAdvancedSettings> advancedSettings{
246+ CServiceBroker::GetSettingsComponent ()->GetAdvancedSettings ()};
247+
248+ if (WithinPercentOfEnd (bookmark, advancedSettings->m_videoIgnorePercentAtEnd ))
249+ bookmark.timeInSeconds = -1.0 ; // Finished (bookmark cleared)
250+ else if (bookmark.timeInSeconds < advancedSettings->m_videoIgnoreSecondsAtStart )
251+ bookmark.timeInSeconds = 0.0 ; // Not played enough to bookmark (bookmark cleared)
252+ else if (isStack)
236253 {
237- resumeBookmark.timeInSeconds = 0.0 ;
254+ // Bookmark will be saved, so update total time from stack
255+ fileItem.GetVideoInfoTag ()->m_streamDetails .SetVideoDuration (
256+ 0 ,
257+ static_cast <int >(bookmark.totalTimeInSeconds )); // Update VideoInfoTag with total time
238258 }
239259
240260 if (CServiceBroker::GetSettingsComponent ()
241261 ->GetProfileManager ()
242262 ->GetCurrentProfile ()
243263 .canWriteDatabases ())
244264 {
245- CSaveFileState::DoWork (fileItem, resumeBookmark, playCountUpdate );
265+ CSaveFileState::DoWork (fileItem, bookmark, UpdatePlayCount (fileItem, bookmark) );
246266 }
247267}
248268
0 commit comments