Skip to content

Commit

Permalink
[Video] Improve user experience when playing movies/episodes from Blu…
Browse files Browse the repository at this point in the history
…ray ISO/BDMV.

	modified:   addons/resource.language.en_gb/resources/strings.po
	modified:   xbmc/FileItem.cpp
	modified:   xbmc/FileItem.h
	modified:   xbmc/PlayListPlayer.cpp
	modified:   xbmc/PlayListPlayer.h
	modified:   xbmc/application/Application.cpp
	modified:   xbmc/application/Application.h
	modified:   xbmc/dialogs/GUIDialogContextMenu.h
	modified:   xbmc/dialogs/GUIDialogSimpleMenu.cpp
	modified:   xbmc/dialogs/GUIDialogSimpleMenu.h
	modified:   xbmc/utils/SaveFileStateJob.cpp
	modified:   xbmc/video/VideoDatabase.cpp
	modified:   xbmc/video/VideoDatabase.h
	modified:   xbmc/video/windows/GUIWindowVideoBase.cpp
	modified:   xbmc/video/windows/GUIWindowVideoBase.h
	modified:   xbmc/windows/GUIMediaWindow.cpp
  • Loading branch information
78andyp committed Mar 18, 2024
1 parent 40c09d0 commit a684e10
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 68 deletions.
4 changes: 3 additions & 1 deletion addons/resource.language.en_gb/resources/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -7289,7 +7289,9 @@ msgctxt "#13423"
msgid "Remember for this path"
msgstr ""

#empty string with id 13424
msgctxt "#13424"
msgid "Choose playlist"
msgstr ""

#: system/settings/settings.xml
msgctxt "#13425"
Expand Down
36 changes: 33 additions & 3 deletions xbmc/FileItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1227,8 +1227,10 @@ bool CFileItem::IsDVDFile(bool bVobs /*= true*/, bool bIfos /*= true*/) const
bool CFileItem::IsBDFile() const
{
std::string strFileName = URIUtils::GetFileName(GetDynPath());
return (StringUtils::EqualsNoCase(strFileName, "index.bdmv") || StringUtils::EqualsNoCase(strFileName, "MovieObject.bdmv")
|| StringUtils::EqualsNoCase(strFileName, "INDEX.BDM") || StringUtils::EqualsNoCase(strFileName, "MOVIEOBJ.BDM"));
return (StringUtils::EqualsNoCase(strFileName, "index.bdmv") ||
StringUtils::EqualsNoCase(strFileName, "MovieObject.bdmv") ||
StringUtils::EqualsNoCase(strFileName, "INDEX.BDM") ||
StringUtils::EqualsNoCase(strFileName, "MOVIEOBJ.BDM") || IsBlurayPlaylist());
}

bool CFileItem::IsRAR() const
Expand Down Expand Up @@ -1323,6 +1325,11 @@ bool CFileItem::IsProtectedBlurayDisc() const
return false;
}

bool CFileItem::IsBlurayPlaylist() const
{
return StringUtils::EqualsNoCase(URIUtils::GetExtension(GetDynPath()), ".mpls");
}

bool CFileItem::IsCDDA() const
{
return URIUtils::IsCDDA(m_strPath);
Expand Down Expand Up @@ -1669,6 +1676,9 @@ bool CFileItem::IsSamePath(const CFileItem *item) const
{
if (item->HasProperty("item_start") || HasProperty("item_start"))
return (item->GetProperty("item_start") == GetProperty("item_start"));
// See if we have associated a bluray playlist
if (IsBlurayPlaylist() || item->IsBlurayPlaylist())
return (GetDynPath() == item->GetDynPath());
return true;
}
if (HasMusicInfoTag() && item->HasMusicInfoTag())
Expand Down Expand Up @@ -2099,6 +2109,22 @@ void CFileItem::SetDynPath(const std::string &path)
m_strDynPath = path;
}

std::string CFileItem::GetBlurayPath() const
{
if (IsBlurayPlaylist())
{
CURL url(GetDynPath());
CURL url2(url.GetHostName()); // strip bluray://
if (url2.IsProtocol("udf"))
// ISO
return url2.GetHostName(); // strip udf://
else if (url.IsProtocol("bluray"))
// BDMV
return url2.Get() + "BDMV/index.bdmv";
}
return GetDynPath();
}

void CFileItem::SetCueDocument(const CCueDocumentPtr& cuePtr)
{
m_cueDocument = cuePtr;
Expand Down Expand Up @@ -3690,7 +3716,11 @@ std::string CFileItem::GetLocalMetadataPath() const
if (m_bIsFolder && !IsFileFolder())
return m_strPath;

std::string parent(URIUtils::GetParentPath(m_strPath));
std::string parent{};
if (IsBlurayPlaylist())
parent = URIUtils::GetParentPath(GetBlurayPath());
else
parent = URIUtils::GetParentPath(m_strPath);
std::string parentFolder(parent);
URIUtils::RemoveSlashAtEnd(parentFolder);
parentFolder = URIUtils::GetFileName(parentFolder);
Expand Down
3 changes: 3 additions & 0 deletions xbmc/FileItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ class CFileItem :
const std::string &GetDynPath() const;
void SetDynPath(const std::string &path);

std::string GetBlurayPath() const;

/*! \brief reset class to it's default values as per construction.
Free's all allocated memory.
\sa Initialize
Expand Down Expand Up @@ -221,6 +223,7 @@ class CFileItem :
bool IsBDFile() const;
bool IsBluray() const;
bool IsProtectedBlurayDisc() const;
bool IsBlurayPlaylist() const;
bool IsRAR() const;
bool IsAPK() const;
bool IsZIP() const;
Expand Down
11 changes: 7 additions & 4 deletions xbmc/PlayListPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,9 @@ bool CPlayListPlayer::PlayItemIdx(int itemIdx)
return Play();
}

bool CPlayListPlayer::Play(const CFileItemPtr& pItem, const std::string& player)
bool CPlayListPlayer::Play(const CFileItemPtr& pItem,
const std::string& player,
bool forceSelection /* = false */)
{
Id playlistId;
bool isVideo{pItem->IsVideo()};
Expand Down Expand Up @@ -301,13 +303,14 @@ bool CPlayListPlayer::Play(const CFileItemPtr& pItem, const std::string& player)
SetCurrentPlaylist(playlistId);
Add(playlistId, pItem);

return Play(0, player);
return Play(0, player, false, false, forceSelection);
}

bool CPlayListPlayer::Play(int iSong,
const std::string& player,
bool bAutoPlay /* = false */,
bool bPlayPrevious /* = false */)
bool bPlayPrevious /* = false */,
bool forceSelection /* = false */)
{
if (m_iCurrentPlayList == TYPE_NONE)
return false;
Expand Down Expand Up @@ -339,7 +342,7 @@ bool CPlayListPlayer::Play(int iSong,
m_bPlaybackStarted = false;

const auto playAttempt = std::chrono::steady_clock::now();
bool ret = g_application.PlayFile(*item, player, bAutoPlay);
bool ret = g_application.PlayFile(*item, player, bAutoPlay, forceSelection);
if (!ret)
{
CLog::Log(LOGERROR, "Playlist Player: skipping unplayable item: {}, path [{}]", m_iCurrentSong,
Expand Down
7 changes: 5 additions & 2 deletions xbmc/PlayListPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,22 @@ class CPlayListPlayer : public IMsgTargetCallback,
* \brief Creates a new playlist for an item and starts playing it
* \param pItem The item to play.
* \param player The player name.
* \param forceSelection for Blurays, force simple menu to change playlist (default to false)
* \return True if has success, otherwise false.
*/
bool Play(const CFileItemPtr& pItem, const std::string& player);
bool Play(const CFileItemPtr& pItem, const std::string& player, bool forceSelection = false);

/*! \brief Start playing a particular entry in the current playlist
\param index the index of the item to play. This value is modified to ensure it lies within the current playlist.
\param replace whether this item should replace the currently playing item. See CApplication::PlayFile (defaults to false).
\param playPreviousOnFail whether to go back to the previous item if playback fails (default to false)
\param forceSelection for Blurays, force simple menu to change playlist (default to false)
*/
bool Play(int index,
const std::string& player,
bool replace = false,
bool playPreviousOnFail = false);
bool playPreviousOnFail = false,
bool forceSelection = false);

/*! \brief Returns the index of the current item in active playlist.
\return Current item in the active playlist.
Expand Down
9 changes: 6 additions & 3 deletions xbmc/application/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2278,7 +2278,10 @@ bool CApplication::PlayStack(CFileItem& item, bool bRestart)
return PlayFile(selectedStackPart, "", true);
}

bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRestart)
bool CApplication::PlayFile(CFileItem item,
const std::string& player,
bool bRestart /* = false */,
bool forceSelection /* = false */)
{
// Ensure the MIME type has been retrieved for http:// and shout:// streams
if (item.GetMimeType().empty())
Expand Down Expand Up @@ -2418,7 +2421,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes

// a disc image might be Blu-Ray disc
if (!(options.startpercent > 0.0 || options.starttime > 0.0) &&
(item.IsBDFile() || item.IsDiscImage()))
(item.IsBDFile() || item.IsDiscImage() || (item.IsBlurayPlaylist() && forceSelection)))
{
// No video selection when using external or remote players (they handle it if supported)
const bool isSimpleMenuAllowed = [&]()
Expand All @@ -2436,7 +2439,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
if (isSimpleMenuAllowed)
{
// Check if we must show the simplified bd menu.
if (!CGUIDialogSimpleMenu::ShowPlaySelection(item))
if (!CGUIDialogSimpleMenu::ShowPlaySelection(item, forceSelection))
return true;
}
}
Expand Down
5 changes: 4 additions & 1 deletion xbmc/application/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ class CApplication : public IWindowManagerCallback,
PLAYLIST::CPlayList& playlist,
PLAYLIST::Id playlistId,
int track = 0);
bool PlayFile(CFileItem item, const std::string& player, bool bRestart = false);
bool PlayFile(CFileItem item,
const std::string& player,
bool bRestart = false,
bool forceSelection = false);
void StopPlaying();
void Restart(bool bSamePosition = true);
void DelayedPlayerRestart();
Expand Down
1 change: 1 addition & 0 deletions xbmc/dialogs/GUIDialogContextMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ enum CONTEXT_BUTTON
CONTEXT_BUTTON_PLAY_NEXT,
CONTEXT_BUTTON_NAVIGATE,
CONTEXT_BUTTON_MANAGE_VIDEOVERSIONS,
CONTEXT_BUTTON_CHOOSE_PLAYLIST,
};

class CContextButtons : public std::vector< std::pair<size_t, std::string> >
Expand Down
17 changes: 13 additions & 4 deletions xbmc/dialogs/GUIDialogSimpleMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include "utils/log.h"
#include "video/VideoInfoTag.h"

std::string m_savePath;

namespace
{
class CGetDirectoryItems : public IRunnable
Expand All @@ -48,12 +50,18 @@ class CGetDirectoryItems : public IRunnable
};
}


bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item)
bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item, bool forceSelection /* = false */)
{
if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_DISC_PLAYBACK) != BD_PLAYBACK_SIMPLE_MENU)
return true;

m_savePath = "";
if (item.IsBlurayPlaylist() && forceSelection)
{
m_savePath = item.GetDynPath(); // save for screen refresh later
item.SetDynPath(item.GetBlurayPath());
}

if (item.IsBDFile())
{
std::string root = URIUtils::GetParentPath(item.GetDynPath());
Expand Down Expand Up @@ -123,10 +131,11 @@ bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item, const std::string&

if (item_new->m_bIsFolder == false)
{
std::string original_path = item.GetDynPath();
if (m_savePath.empty()) // If not set above (choose playlist selected)
m_savePath = item.GetDynPath();
item.SetDynPath(item_new->GetDynPath());
item.SetProperty("get_stream_details_from_player", true);
item.SetProperty("original_listitem_url", original_path);
item.SetProperty("original_listitem_url", m_savePath);
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion xbmc/dialogs/GUIDialogSimpleMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class CGUIDialogSimpleMenu
public:

/*! \brief Show dialog allowing selection of wanted playback item */
static bool ShowPlaySelection(CFileItem& item);
static bool ShowPlaySelection(CFileItem& item, bool forceSelection = false);
static bool ShowPlaySelection(CFileItem& item, const std::string& directory);

protected:
Expand Down
26 changes: 21 additions & 5 deletions xbmc/utils/SaveFileStateJob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,24 @@ void CSaveFileState::DoWork(CFileItem& item,
{
std::string progressTrackingFile = item.GetPath();

if (item.HasVideoInfoTag() && StringUtils::StartsWith(item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://"))
progressTrackingFile = item.GetVideoInfoTag()->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified
if (item.HasVideoInfoTag() &&
StringUtils::StartsWith(item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://"))
progressTrackingFile =
item.GetVideoInfoTag()
->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified
else if (item.IsBlurayPlaylist() && (item.GetVideoContentType() == VideoDbContentType::MOVIES ||
item.GetVideoContentType() == VideoDbContentType::EPISODES))
progressTrackingFile = item.GetDynPath();
else if (item.HasVideoInfoTag() && item.IsVideoDb())
progressTrackingFile = item.GetVideoInfoTag()->m_strFileNameAndPath; // we need the file url of the video db item to create the bookmark
progressTrackingFile =
item.GetVideoInfoTag()
->m_strFileNameAndPath; // we need the file url of the video db item to create the bookmark
else if (item.HasProperty("original_listitem_url"))
{
// only use original_listitem_url for Python, UPnP and Bluray sources
std::string original = item.GetProperty("original_listitem_url").asString();
if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) || URIUtils::IsBluray(item.GetPath()))
if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) ||
URIUtils::IsBluray(item.GetPath()))
progressTrackingFile = original;
}

Expand Down Expand Up @@ -159,7 +168,14 @@ void CSaveFileState::DoWork(CFileItem& item,
if (!videodatabase.GetStreamDetails(dbItem) ||
dbItem.GetVideoInfoTag()->m_streamDetails != item.GetVideoInfoTag()->m_streamDetails)
{
videodatabase.SetStreamDetailsForFile(item.GetVideoInfoTag()->m_streamDetails, progressTrackingFile);
const int idFile = videodatabase.SetStreamDetailsForFile(
item.GetVideoInfoTag()->m_streamDetails, item.GetDynPath());
if (item.GetVideoContentType() == VideoDbContentType::MOVIES)
videodatabase.SetFileForMovie(item.GetDynPath(), item.GetVideoInfoTag()->m_iDbId,
idFile);
else if (item.GetVideoContentType() == VideoDbContentType::EPISODES)
videodatabase.SetFileForEpisode(item.GetDynPath(), item.GetVideoInfoTag()->m_iDbId,
idFile);
updateListing = true;
}
}
Expand Down
Loading

0 comments on commit a684e10

Please sign in to comment.