1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "guilib/guiinfo/VideoGUIInfo.h"
10
11 #include "Application.h"
12 #include "FileItem.h"
13 #include "PlayListPlayer.h"
14 #include "ServiceBroker.h"
15 #include "URL.h"
16 #include "cores/DataCacheCore.h"
17 #include "cores/VideoPlayer/VideoRenderers/BaseRenderer.h"
18 #include "guilib/GUIComponent.h"
19 #include "guilib/GUIWindowManager.h"
20 #include "guilib/LocalizeStrings.h"
21 #include "guilib/StereoscopicsManager.h"
22 #include "guilib/WindowIDs.h"
23 #include "guilib/guiinfo/GUIInfo.h"
24 #include "guilib/guiinfo/GUIInfoHelper.h"
25 #include "guilib/guiinfo/GUIInfoLabels.h"
26 #include "playlists/PlayList.h"
27 #include "settings/AdvancedSettings.h"
28 #include "settings/SettingUtils.h"
29 #include "settings/Settings.h"
30 #include "settings/SettingsComponent.h"
31 #include "settings/lib/Setting.h"
32 #include "utils/StringUtils.h"
33 #include "utils/URIUtils.h"
34 #include "utils/log.h"
35 #include "video/VideoInfoTag.h"
36 #include "video/VideoThumbLoader.h"
37
38 #include <math.h>
39
40 using namespace KODI::GUILIB;
41 using namespace KODI::GUILIB::GUIINFO;
42
GetPercentPlayed(const CVideoInfoTag * tag) const43 int CVideoGUIInfo::GetPercentPlayed(const CVideoInfoTag* tag) const
44 {
45 CBookmark bookmark = tag->GetResumePoint();
46 if (bookmark.IsPartWay())
47 return std::lrintf(static_cast<float>(bookmark.timeInSeconds) / bookmark.totalTimeInSeconds * 100.0f);
48 else
49 return 0;
50 }
51
InitCurrentItem(CFileItem * item)52 bool CVideoGUIInfo::InitCurrentItem(CFileItem *item)
53 {
54 if (item && item->IsVideo())
55 {
56 // special case where .strm is used to start an audio stream
57 if (item->IsInternetStream() && g_application.GetAppPlayer().IsPlayingAudio())
58 return false;
59
60 CLog::Log(LOGDEBUG,"CVideoGUIInfo::InitCurrentItem(%s)", CURL::GetRedacted(item->GetPath()).c_str());
61
62 // Find a thumb for this file.
63 if (!item->HasArt("thumb"))
64 {
65 CVideoThumbLoader loader;
66 loader.LoadItem(item);
67 }
68
69 // find a thumb for this stream
70 if (item->IsInternetStream())
71 {
72 if (!g_application.m_strPlayListFile.empty())
73 {
74 CLog::Log(LOGDEBUG,"Streaming media detected... using %s to find a thumb", g_application.m_strPlayListFile.c_str());
75 CFileItem thumbItem(g_application.m_strPlayListFile,false);
76
77 CVideoThumbLoader loader;
78 if (loader.FillThumb(thumbItem))
79 item->SetArt("thumb", thumbItem.GetArt("thumb"));
80 }
81 }
82 return true;
83 }
84 return false;
85 }
86
GetLabel(std::string & value,const CFileItem * item,int contextWindow,const CGUIInfo & info,std::string * fallback) const87 bool CVideoGUIInfo::GetLabel(std::string& value, const CFileItem *item, int contextWindow, const CGUIInfo &info, std::string *fallback) const
88 {
89 // For videoplayer "offset" and "position" info labels check playlist
90 if (info.GetData1() && ((info.m_info >= VIDEOPLAYER_OFFSET_POSITION_FIRST &&
91 info.m_info <= VIDEOPLAYER_OFFSET_POSITION_LAST) ||
92 (info.m_info >= PLAYER_OFFSET_POSITION_FIRST && info.m_info <= PLAYER_OFFSET_POSITION_LAST)))
93 return GetPlaylistInfo(value, info);
94
95 const CVideoInfoTag* tag = item->GetVideoInfoTag();
96 if (tag)
97 {
98 switch (info.m_info)
99 {
100 /////////////////////////////////////////////////////////////////////////////////////////////
101 // PLAYER_* / VIDEOPLAYER_* / LISTITEM_*
102 /////////////////////////////////////////////////////////////////////////////////////////////
103 case PLAYER_PATH:
104 case PLAYER_FILENAME:
105 case PLAYER_FILEPATH:
106 if (item->HasMusicInfoTag()) // special handling for music videos, which have both a videotag and a musictag
107 break;
108
109 value = tag->m_strFileNameAndPath;
110 if (value.empty())
111 value = item->GetPath();
112 value = GUIINFO::GetFileInfoLabelValueFromPath(info.m_info, value);
113 return true;
114 case PLAYER_TITLE:
115 value = tag->m_strTitle;
116 return !value.empty();
117 case VIDEOPLAYER_TITLE:
118 value = tag->m_strTitle;
119 return !value.empty();
120 case LISTITEM_TITLE:
121 value = tag->m_strTitle;
122 return true;
123 case VIDEOPLAYER_ORIGINALTITLE:
124 case LISTITEM_ORIGINALTITLE:
125 value = tag->m_strOriginalTitle;
126 return true;
127 case VIDEOPLAYER_GENRE:
128 case LISTITEM_GENRE:
129 value = StringUtils::Join(tag->m_genre, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoItemSeparator);
130 return true;
131 case VIDEOPLAYER_DIRECTOR:
132 case LISTITEM_DIRECTOR:
133 value = StringUtils::Join(tag->m_director, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoItemSeparator);
134 return true;
135 case VIDEOPLAYER_IMDBNUMBER:
136 case LISTITEM_IMDBNUMBER:
137 value = tag->GetUniqueID();
138 return true;
139 case VIDEOPLAYER_DBID:
140 case LISTITEM_DBID:
141 if (tag->m_iDbId > -1)
142 {
143 value = StringUtils::Format("%i", tag->m_iDbId);
144 return true;
145 }
146 break;
147 case VIDEOPLAYER_TVSHOWDBID:
148 case LISTITEM_TVSHOWDBID:
149 if (tag->m_iIdShow > -1)
150 {
151 value = StringUtils::Format("%i", tag->m_iIdShow);
152 return true;
153 }
154 break;
155 case VIDEOPLAYER_UNIQUEID:
156 case LISTITEM_UNIQUEID:
157 if (!info.GetData3().empty())
158 value = tag->GetUniqueID(info.GetData3());
159 return true;
160 case VIDEOPLAYER_RATING:
161 case LISTITEM_RATING:
162 {
163 float rating = tag->GetRating(info.GetData3()).rating;
164 if (rating > 0.f)
165 {
166 value = StringUtils::FormatNumber(rating);
167 return true;
168 }
169 break;
170 }
171 case VIDEOPLAYER_RATING_AND_VOTES:
172 case LISTITEM_RATING_AND_VOTES:
173 {
174 CRating rating = tag->GetRating(info.GetData3());
175 if (rating.rating >= 0.f)
176 {
177 if (rating.rating > 0.f && rating.votes == 0)
178 value = StringUtils::FormatNumber(rating.rating);
179 else if (rating.votes > 0)
180 value = StringUtils::Format(g_localizeStrings.Get(20350).c_str(),
181 StringUtils::FormatNumber(rating.rating).c_str(),
182 StringUtils::FormatNumber(rating.votes).c_str());
183 else
184 break;
185 return true;
186 }
187 break;
188 }
189 case VIDEOPLAYER_USER_RATING:
190 case LISTITEM_USER_RATING:
191 if (tag->m_iUserRating > 0)
192 {
193 value = StringUtils::Format("%i", tag->m_iUserRating);
194 return true;
195 }
196 break;
197 case VIDEOPLAYER_VOTES:
198 case LISTITEM_VOTES:
199 value = StringUtils::FormatNumber(tag->GetRating(info.GetData3()).votes);
200 return true;
201 case VIDEOPLAYER_YEAR:
202 case LISTITEM_YEAR:
203 if (tag->HasYear())
204 {
205 value = StringUtils::Format("%i", tag->GetYear());
206 return true;
207 }
208 break;
209 case VIDEOPLAYER_PREMIERED:
210 case LISTITEM_PREMIERED:
211 {
212 CDateTime dateTime;
213 if (tag->m_firstAired.IsValid())
214 dateTime = tag->m_firstAired;
215 else if (tag->HasPremiered())
216 dateTime = tag->GetPremiered();
217
218 if (dateTime.IsValid())
219 {
220 value = dateTime.GetAsLocalizedDate();
221 return true;
222 }
223 break;
224 }
225 case VIDEOPLAYER_PLOT:
226 value = tag->m_strPlot;
227 return true;
228 case VIDEOPLAYER_TRAILER:
229 case LISTITEM_TRAILER:
230 value = tag->m_strTrailer;
231 return true;
232 case VIDEOPLAYER_PLOT_OUTLINE:
233 case LISTITEM_PLOT_OUTLINE:
234 value = tag->m_strPlotOutline;
235 return true;
236 case VIDEOPLAYER_EPISODE:
237 case LISTITEM_EPISODE:
238 {
239 int iEpisode = -1;
240 if (tag->m_iEpisode > 0)
241 {
242 iEpisode = tag->m_iEpisode;
243 }
244
245 if (iEpisode >= 0)
246 {
247 value = StringUtils::Format("%d", iEpisode);
248 return true;
249 }
250 break;
251 }
252 case VIDEOPLAYER_SEASON:
253 case LISTITEM_SEASON:
254 if (tag->m_iSeason >= 0)
255 {
256 value = StringUtils::Format("%d", tag->m_iSeason);
257 return true;
258 }
259 break;
260 case VIDEOPLAYER_TVSHOW:
261 case LISTITEM_TVSHOW:
262 value = tag->m_strShowTitle;
263 return true;
264 case VIDEOPLAYER_STUDIO:
265 case LISTITEM_STUDIO:
266 value = StringUtils::Join(tag->m_studio, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoItemSeparator);
267 return true;
268 case VIDEOPLAYER_COUNTRY:
269 case LISTITEM_COUNTRY:
270 value = StringUtils::Join(tag->m_country, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoItemSeparator);
271 return true;
272 case VIDEOPLAYER_MPAA:
273 case LISTITEM_MPAA:
274 value = tag->m_strMPAARating;
275 return true;
276 case VIDEOPLAYER_TOP250:
277 case LISTITEM_TOP250:
278 if (tag->m_iTop250 > 0)
279 {
280 value = StringUtils::Format("%i", tag->m_iTop250);
281 return true;
282 }
283 break;
284 case VIDEOPLAYER_CAST:
285 case LISTITEM_CAST:
286 value = tag->GetCast();
287 return true;
288 case VIDEOPLAYER_CAST_AND_ROLE:
289 case LISTITEM_CAST_AND_ROLE:
290 value = tag->GetCast(true);
291 return true;
292 case VIDEOPLAYER_ARTIST:
293 case LISTITEM_ARTIST:
294 value = StringUtils::Join(tag->m_artist, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoItemSeparator);
295 return true;
296 case VIDEOPLAYER_ALBUM:
297 case LISTITEM_ALBUM:
298 value = tag->m_strAlbum;
299 return true;
300 case VIDEOPLAYER_WRITER:
301 case LISTITEM_WRITER:
302 value = StringUtils::Join(tag->m_writingCredits, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoItemSeparator);
303 return true;
304 case VIDEOPLAYER_TAGLINE:
305 case LISTITEM_TAGLINE:
306 value = tag->m_strTagLine;
307 return true;
308 case VIDEOPLAYER_LASTPLAYED:
309 case LISTITEM_LASTPLAYED:
310 {
311 const CDateTime dateTime = tag->m_lastPlayed;
312 if (dateTime.IsValid())
313 {
314 value = dateTime.GetAsLocalizedDate();
315 return true;
316 }
317 break;
318 }
319 case VIDEOPLAYER_PLAYCOUNT:
320 case LISTITEM_PLAYCOUNT:
321 if (tag->GetPlayCount() > 0)
322 {
323 value = StringUtils::Format("%i", tag->GetPlayCount());
324 return true;
325 }
326 break;
327
328 /////////////////////////////////////////////////////////////////////////////////////////////
329 // LISTITEM_*
330 /////////////////////////////////////////////////////////////////////////////////////////////
331 case LISTITEM_DURATION:
332 {
333 int iDuration = tag->GetDuration();
334 if (iDuration > 0)
335 {
336 value = StringUtils::SecondsToTimeString(iDuration, static_cast<TIME_FORMAT>(info.GetData4()));
337 return true;
338 }
339 break;
340 }
341 case LISTITEM_TRACKNUMBER:
342 if (tag->m_iTrack > -1 )
343 {
344 value = StringUtils::Format("%i", tag->m_iTrack);
345 return true;
346 }
347 break;
348 case LISTITEM_PLOT:
349 {
350 std::shared_ptr<CSettingList> setting(std::dynamic_pointer_cast<CSettingList>(
351 CServiceBroker::GetSettingsComponent()->GetSettings()->GetSetting(CSettings::SETTING_VIDEOLIBRARY_SHOWUNWATCHEDPLOTS)));
352 if (tag->m_type != MediaTypeTvShow && tag->m_type != MediaTypeVideoCollection &&
353 tag->GetPlayCount() == 0 && setting &&
354 ((tag->m_type == MediaTypeMovie &&
355 !CSettingUtils::FindIntInList(
356 setting, CSettings::VIDEOLIBRARY_PLOTS_SHOW_UNWATCHED_MOVIES)) ||
357 (tag->m_type == MediaTypeEpisode &&
358 !CSettingUtils::FindIntInList(
359 setting, CSettings::VIDEOLIBRARY_PLOTS_SHOW_UNWATCHED_TVSHOWEPISODES))))
360 {
361 value = g_localizeStrings.Get(20370);
362 }
363 else
364 {
365 value = tag->m_strPlot;
366 }
367 return true;
368 }
369 case LISTITEM_STATUS:
370 value = tag->m_strStatus;
371 return true;
372 case LISTITEM_TAG:
373 value = StringUtils::Join(tag->m_tags, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoItemSeparator);
374 return true;
375 case LISTITEM_SET:
376 value = tag->m_set.title;
377 return true;
378 case LISTITEM_SETID:
379 if (tag->m_set.id > 0)
380 {
381 value = StringUtils::Format("%d", tag->m_set.id);
382 return true;
383 }
384 break;
385 case LISTITEM_ENDTIME_RESUME:
386 {
387 const CDateTimeSpan duration(0, 0, 0, tag->GetDuration() - tag->GetResumePoint().timeInSeconds);
388 value = (CDateTime::GetCurrentDateTime() + duration).GetAsLocalizedTime("", false);
389 return true;
390 }
391 case LISTITEM_ENDTIME:
392 {
393 const CDateTimeSpan duration(0, 0, 0, tag->GetDuration());
394 value = (CDateTime::GetCurrentDateTime() + duration).GetAsLocalizedTime("", false);
395 return true;
396 }
397 case LISTITEM_DATE_ADDED:
398 if (tag->m_dateAdded.IsValid())
399 {
400 value = tag->m_dateAdded.GetAsLocalizedDate();
401 return true;
402 }
403 break;
404 case LISTITEM_DBTYPE:
405 value = tag->m_type;
406 return true;
407 case LISTITEM_APPEARANCES:
408 if (tag->m_relevance > -1)
409 {
410 value = StringUtils::Format("%i", tag->m_relevance);
411 return true;
412 }
413 break;
414 case LISTITEM_PERCENT_PLAYED:
415 value = StringUtils::Format("%d", GetPercentPlayed(tag));
416 return true;
417 case LISTITEM_VIDEO_CODEC:
418 value = tag->m_streamDetails.GetVideoCodec();
419 return true;
420 case LISTITEM_VIDEO_RESOLUTION:
421 value = CStreamDetails::VideoDimsToResolutionDescription(tag->m_streamDetails.GetVideoWidth(), tag->m_streamDetails.GetVideoHeight());
422 return true;
423 case LISTITEM_VIDEO_ASPECT:
424 value = CStreamDetails::VideoAspectToAspectDescription(tag->m_streamDetails.GetVideoAspect());
425 return true;
426 case LISTITEM_AUDIO_CODEC:
427 value = tag->m_streamDetails.GetAudioCodec();
428 return true;
429 case LISTITEM_AUDIO_CHANNELS:
430 {
431 int iChannels = tag->m_streamDetails.GetAudioChannels();
432 if (iChannels > 0)
433 {
434 value = StringUtils::Format("%i", iChannels);
435 return true;
436 }
437 break;
438 }
439 case LISTITEM_AUDIO_LANGUAGE:
440 value = tag->m_streamDetails.GetAudioLanguage();
441 return true;
442 case LISTITEM_SUBTITLE_LANGUAGE:
443 value = tag->m_streamDetails.GetSubtitleLanguage();
444 return true;
445 case LISTITEM_FILENAME:
446 case LISTITEM_FILE_EXTENSION:
447 if (item->IsVideoDb())
448 value = URIUtils::GetFileName(tag->m_strFileNameAndPath);
449 else if (item->HasMusicInfoTag()) // special handling for music videos, which have both a videotag and a musictag
450 break;
451 else
452 value = URIUtils::GetFileName(item->GetPath());
453
454 if (info.m_info == LISTITEM_FILE_EXTENSION)
455 {
456 std::string strExtension = URIUtils::GetExtension(value);
457 value = StringUtils::TrimLeft(strExtension, ".");
458 }
459 return true;
460 case LISTITEM_FOLDERNAME:
461 case LISTITEM_PATH:
462 if (item->IsVideoDb())
463 {
464 if (item->m_bIsFolder)
465 value = tag->m_strPath;
466 else
467 URIUtils::GetParentPath(tag->m_strFileNameAndPath, value);
468 }
469 else if (item->HasMusicInfoTag()) // special handling for music videos, which have both a videotag and a musictag
470 break;
471 else
472 URIUtils::GetParentPath(item->GetPath(), value);
473
474 value = CURL(value).GetWithoutUserDetails();
475
476 if (info.m_info == LISTITEM_FOLDERNAME)
477 {
478 URIUtils::RemoveSlashAtEnd(value);
479 value = URIUtils::GetFileName(value);
480 }
481 return true;
482 case LISTITEM_FILENAME_AND_PATH:
483 if (item->IsVideoDb())
484 value = tag->m_strFileNameAndPath;
485 else if (item->HasMusicInfoTag()) // special handling for music videos, which have both a videotag and a musictag
486 break;
487 else
488 value = item->GetPath();
489
490 value = CURL(value).GetWithoutUserDetails();
491 return true;
492 }
493 }
494
495 switch (info.m_info)
496 {
497 ///////////////////////////////////////////////////////////////////////////////////////////////
498 // VIDEOPLAYER_*
499 ///////////////////////////////////////////////////////////////////////////////////////////////
500 case VIDEOPLAYER_PLAYLISTLEN:
501 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST_VIDEO)
502 {
503 value = GUIINFO::GetPlaylistLabel(PLAYLIST_LENGTH);
504 return true;
505 }
506 break;
507 case VIDEOPLAYER_PLAYLISTPOS:
508 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST_VIDEO)
509 {
510 value = GUIINFO::GetPlaylistLabel(PLAYLIST_POSITION);
511 return true;
512 }
513 break;
514 case VIDEOPLAYER_VIDEO_ASPECT:
515 value = CStreamDetails::VideoAspectToAspectDescription(CServiceBroker::GetDataCacheCore().GetVideoDAR());
516 return true;
517 case VIDEOPLAYER_STEREOSCOPIC_MODE:
518 value = CServiceBroker::GetDataCacheCore().GetVideoStereoMode();
519 return true;
520 case VIDEOPLAYER_SUBTITLES_LANG:
521 value = m_subtitleInfo.language;
522 return true;
523 break;
524 case VIDEOPLAYER_COVER:
525 if (g_application.GetAppPlayer().IsPlayingVideo())
526 {
527 if (fallback)
528 *fallback = "DefaultVideoCover.png";
529
530 value = item->HasArt("thumb") ? item->GetArt("thumb") : "DefaultVideoCover.png";
531 return true;
532 }
533 break;
534
535 ///////////////////////////////////////////////////////////////////////////////////////////////
536 // LISTITEM_*
537 ///////////////////////////////////////////////////////////////////////////////////////////////
538 case LISTITEM_STEREOSCOPIC_MODE:
539 value = item->GetProperty("stereomode").asString();
540 if (value.empty() && tag)
541 value = CStereoscopicsManager::NormalizeStereoMode(tag->m_streamDetails.GetStereoMode());
542 return true;
543
544 ///////////////////////////////////////////////////////////////////////////////////////////////
545 // VIDEOPLAYER_*
546 ///////////////////////////////////////////////////////////////////////////////////////////////
547 case VIDEOPLAYER_VIDEO_CODEC:
548 value = m_videoInfo.codecName;
549 return true;
550 case VIDEOPLAYER_VIDEO_RESOLUTION:
551 value = CStreamDetails::VideoDimsToResolutionDescription(m_videoInfo.width, m_videoInfo.height);
552 return true;
553 case VIDEOPLAYER_AUDIO_CODEC:
554 value = m_audioInfo.codecName;
555 return true;
556 case VIDEOPLAYER_AUDIO_CHANNELS:
557 {
558 int iChannels = m_audioInfo.channels;
559 if (iChannels > 0)
560 {
561 value = StringUtils::Format("%i", iChannels);
562 return true;
563 }
564 break;
565 }
566 case VIDEOPLAYER_AUDIO_BITRATE:
567 {
568 int iBitrate = m_audioInfo.bitrate;
569 if (iBitrate > 0)
570 {
571 value = StringUtils::Format("%li", std::lrint(static_cast<double>(iBitrate) / 1000.0));
572 return true;
573 }
574 break;
575 }
576 case VIDEOPLAYER_VIDEO_BITRATE:
577 {
578 int iBitrate = m_videoInfo.bitrate;
579 if (iBitrate > 0)
580 {
581 value = StringUtils::Format("%li", std::lrint(static_cast<double>(iBitrate) / 1000.0));
582 return true;
583 }
584 break;
585 }
586 case VIDEOPLAYER_AUDIO_LANG:
587 value = m_audioInfo.language;
588 return true;
589 }
590
591 return false;
592 }
593
GetPlaylistInfo(std::string & value,const CGUIInfo & info) const594 bool CVideoGUIInfo::GetPlaylistInfo(std::string& value, const CGUIInfo& info) const
595 {
596 PLAYLIST::CPlayList& playlist = CServiceBroker::GetPlaylistPlayer().GetPlaylist(PLAYLIST_VIDEO);
597 if (playlist.size() < 1)
598 return false;
599
600 int index = info.GetData2();
601 if (info.GetData1() == 1)
602 { // relative index (requires current playlist is PLAYLIST_VIDEO)
603 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() != PLAYLIST_VIDEO)
604 return false;
605
606 index = CServiceBroker::GetPlaylistPlayer().GetNextSong(index);
607 }
608
609 if (index < 0 || index >= playlist.size())
610 return false;
611
612 const CFileItemPtr playlistItem = playlist[index];
613 // try to set a thumbnail
614 if (!playlistItem->HasArt("thumb"))
615 {
616 CVideoThumbLoader loader;
617 loader.LoadItem(playlistItem.get());
618 // still no thumb? then just the set the default cover
619 if (!playlistItem->HasArt("thumb"))
620 playlistItem->SetArt("thumb", "DefaultVideoCover.png");
621 }
622 if (info.m_info == VIDEOPLAYER_PLAYLISTPOS)
623 {
624 value = StringUtils::Format("%i", index + 1);
625 return true;
626 }
627 else if (info.m_info == VIDEOPLAYER_COVER)
628 {
629 value = playlistItem->GetArt("thumb");
630 return true;
631 }
632
633 return GetLabel(value, playlistItem.get(), 0, CGUIInfo(info.m_info), nullptr);
634 }
635
GetFallbackLabel(std::string & value,const CFileItem * item,int contextWindow,const CGUIInfo & info,std::string * fallback)636 bool CVideoGUIInfo::GetFallbackLabel(std::string& value,
637 const CFileItem* item,
638 int contextWindow,
639 const CGUIInfo& info,
640 std::string* fallback)
641 {
642 // No fallback for videoplayer "offset" and "position" info labels
643 if (info.GetData1() && ((info.m_info >= VIDEOPLAYER_OFFSET_POSITION_FIRST &&
644 info.m_info <= VIDEOPLAYER_OFFSET_POSITION_LAST) ||
645 (info.m_info >= PLAYER_OFFSET_POSITION_FIRST && info.m_info <= PLAYER_OFFSET_POSITION_LAST)))
646 return false;
647
648 const CVideoInfoTag* tag = item->GetVideoInfoTag();
649 if (tag)
650 {
651 switch (info.m_info)
652 {
653 /////////////////////////////////////////////////////////////////////////////////////////////
654 // VIDEOPLAYER_*
655 /////////////////////////////////////////////////////////////////////////////////////////////
656 case VIDEOPLAYER_TITLE:
657 value = item->GetLabel();
658 if (value.empty())
659 value = CUtil::GetTitleFromPath(item->GetPath());
660 return true;
661 default:
662 break;
663 }
664 }
665 return false;
666 }
667
GetInt(int & value,const CGUIListItem * gitem,int contextWindow,const CGUIInfo & info) const668 bool CVideoGUIInfo::GetInt(int& value, const CGUIListItem *gitem, int contextWindow, const CGUIInfo &info) const
669 {
670 if (!gitem->IsFileItem())
671 return false;
672
673 const CFileItem *item = static_cast<const CFileItem*>(gitem);
674 const CVideoInfoTag* tag = item->GetVideoInfoTag();
675 if (tag)
676 {
677 switch (info.m_info)
678 {
679 /////////////////////////////////////////////////////////////////////////////////////////////
680 // LISTITEM_*
681 /////////////////////////////////////////////////////////////////////////////////////////////
682 case LISTITEM_PERCENT_PLAYED:
683 value = GetPercentPlayed(tag);
684 return true;
685 }
686 }
687
688 return false;
689 }
690
GetBool(bool & value,const CGUIListItem * gitem,int contextWindow,const CGUIInfo & info) const691 bool CVideoGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int contextWindow, const CGUIInfo &info) const
692 {
693 if (!gitem->IsFileItem())
694 return false;
695
696 const CFileItem *item = static_cast<const CFileItem*>(gitem);
697 const CVideoInfoTag* tag = item->GetVideoInfoTag();
698 if (tag)
699 {
700 switch (info.m_info)
701 {
702 /////////////////////////////////////////////////////////////////////////////////////////////
703 // VIDEOPLAYER_*
704 /////////////////////////////////////////////////////////////////////////////////////////////
705 case VIDEOPLAYER_HAS_INFO:
706 value = !tag->IsEmpty();
707 return true;
708
709 /////////////////////////////////////////////////////////////////////////////////////////////
710 // LISTITEM_*
711 /////////////////////////////////////////////////////////////////////////////////////////////
712 case LISTITEM_IS_RESUMABLE:
713 value = tag->GetResumePoint().timeInSeconds > 0;
714 return true;
715 case LISTITEM_IS_COLLECTION:
716 value = tag->m_type == MediaTypeVideoCollection;
717 return true;
718 }
719 }
720
721 switch (info.m_info)
722 {
723 ///////////////////////////////////////////////////////////////////////////////////////////////
724 // VIDEOPLAYER_*
725 ///////////////////////////////////////////////////////////////////////////////////////////////
726 case VIDEOPLAYER_CONTENT:
727 {
728 std::string strContent = "files";
729 if (tag)
730 {
731 if (tag->m_type == MediaTypeMovie)
732 strContent = "movies";
733 else if (tag->m_type == MediaTypeEpisode)
734 strContent = "episodes";
735 else if (tag->m_type == MediaTypeMusicVideo)
736 strContent = "musicvideos";
737 }
738 value = StringUtils::EqualsNoCase(info.GetData3(), strContent);
739 return value; // if no match for this provider, other providers shall be asked.
740 }
741 case VIDEOPLAYER_USING_OVERLAYS:
742 value = (CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_VIDEOPLAYER_RENDERMETHOD) == RENDER_OVERLAYS);
743 return true;
744 case VIDEOPLAYER_ISFULLSCREEN:
745 value = CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
746 CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_FULLSCREEN_GAME;
747 return true;
748 case VIDEOPLAYER_HASMENU:
749 value = g_application.GetAppPlayer().HasMenu();
750 return true;
751 case VIDEOPLAYER_HASTELETEXT:
752 if (g_application.GetAppPlayer().GetTeletextCache())
753 {
754 value = true;
755 return true;
756 }
757 break;
758 case VIDEOPLAYER_HASSUBTITLES:
759 value = g_application.GetAppPlayer().GetSubtitleCount() > 0;
760 return true;
761 case VIDEOPLAYER_SUBTITLESENABLED:
762 value = g_application.GetAppPlayer().GetSubtitleVisible();
763 return true;
764 case VIDEOPLAYER_IS_STEREOSCOPIC:
765 value = !CServiceBroker::GetDataCacheCore().GetVideoStereoMode().empty();
766 return true;
767
768 ///////////////////////////////////////////////////////////////////////////////////////////////
769 // LISTITEM_*
770 ///////////////////////////////////////////////////////////////////////////////////////////////
771 case LISTITEM_IS_STEREOSCOPIC:
772 {
773 std::string stereoMode = item->GetProperty("stereomode").asString();
774 if (stereoMode.empty() && tag)
775 stereoMode = CStereoscopicsManager::NormalizeStereoMode(tag->m_streamDetails.GetStereoMode());
776 if (!stereoMode.empty() && stereoMode != "mono")
777 value = true;
778 return true;
779 }
780 }
781
782 return false;
783 }
784