From d8bb7962b1cfd7a33316c7126bffa8290dbec15b Mon Sep 17 00:00:00 2001 From: m0viefreak Date: Mon, 21 Nov 2022 01:21:40 +0100 Subject: [PATCH] Auto-load subtitles/audio: Improve multivolume rar file handling Make it possible to load audio and subtitle files when playing any .partXX.rar file of a multivolume rar archive: Assume the following files: movie.part01.rar movie.part02.rar movie.part03.rar movie.srt movie.wav Playing any of the three .rar files will now auto load the audio and subtitle files. Before, the .srt and .wav would have needed to be renamed to something like movie.part01.rar movie.part01.srt movie.part01.wav movie.part02.rar movie.part03.rar --- src/DSUtil/PathUtils.cpp | 24 ++++++++++++++++++++++++ src/DSUtil/PathUtils.h | 3 +++ src/Subtitles/SubtitleHelpers.cpp | 12 +++--------- src/mpc-hc/Playlist.cpp | 16 ++++------------ 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/DSUtil/PathUtils.cpp b/src/DSUtil/PathUtils.cpp index c23b5e3dc69..7f250543243 100644 --- a/src/DSUtil/PathUtils.cpp +++ b/src/DSUtil/PathUtils.cpp @@ -22,6 +22,7 @@ #include "PathUtils.h" #include #include "text.h" +#include namespace PathUtils { @@ -266,4 +267,27 @@ namespace PathUtils { return (fn.Find(_T(":")) > 0) && !IsURL(fn) || (fn.Find(_T("\\\\")) == 0); } + + CString BaseName(const CString& fn) + { + return fn.Mid(std::max(fn.ReverseFind('\\'), fn.ReverseFind('/')) + 1); + } + + CString Path(const CString& fn) + { + return fn.Left(std::max(fn.ReverseFind('\\'), fn.ReverseFind('/')) + 1); + } + + CString StripExtensionAndMultiVolumeRarSuffix(const CString& fn) + { + // C:\some\dir\base.mkv ==> C:\some\dir\base + // C:\some\dir\base.partNN.rar ==> C:\some\dir\base + std::wregex re(_T("(\\.part\\d+\\.rar|\\.[^.]+)$")); + std::wcmatch mc; + if (std::regex_search(fn.GetString(), mc, re)) { + return fn.Left((int)mc.position()); + } else { + return fn; + } + } } diff --git a/src/DSUtil/PathUtils.h b/src/DSUtil/PathUtils.h index 2eea3ffb41a..7570136b1f1 100644 --- a/src/DSUtil/PathUtils.h +++ b/src/DSUtil/PathUtils.h @@ -47,4 +47,7 @@ namespace PathUtils bool IsURL(CString& fn); bool IsFullFilePath(CString& fn); + CString BaseName(const CString& fn); + CString Path(const CString& fn); + CString StripExtensionAndMultiVolumeRarSuffix(const CString& fn); } diff --git a/src/Subtitles/SubtitleHelpers.cpp b/src/Subtitles/SubtitleHelpers.cpp index 732b1450258..9bfa7e8372e 100644 --- a/src/Subtitles/SubtitleHelpers.cpp +++ b/src/Subtitles/SubtitleHelpers.cpp @@ -63,14 +63,8 @@ void Subtitle::GetSubFileNames(CString fn, const CAtlArray& paths, CAtl ExtendMaxPathLengthIfNeeded(fn, MAX_PATH); - int l = fn.ReverseFind('\\') + 1; - int l2 = fn.ReverseFind('.'); - if (l2 < l) { // no extension, read to the end - l2 = fn.GetLength(); - } - - CString orgpath = fn.Left(l); - CString title = fn.Mid(l, l2 - l); + CString orgpath = PathUtils::Path(fn); + CString title = PathUtils::StripExtensionAndMultiVolumeRarSuffix(PathUtils::BaseName(fn)); int titleLength = title.GetLength(); WIN32_FIND_DATA wfd; @@ -92,7 +86,7 @@ void Subtitle::GetSubFileNames(CString fn, const CAtlArray& paths, CAtl CString path = paths[k]; path.Replace('/', '\\'); - l = path.GetLength(); + int l = path.GetLength(); if (l > 0 && path[l - 1] != '\\') { path += _T('\\'); } diff --git a/src/mpc-hc/Playlist.cpp b/src/mpc-hc/Playlist.cpp index bc31072ae87..c0a68ffaa4c 100644 --- a/src/mpc-hc/Playlist.cpp +++ b/src/mpc-hc/Playlist.cpp @@ -159,13 +159,12 @@ void CPlaylistItem::AutoLoadFiles() CString ext = fn.Mid(i + 1).MakeLower(); if (!mf.FindExt(ext, true)) { - CString path = fn; - path.Replace('/', '\\'); - path = path.Left(path.ReverseFind('\\') + 1); + CString path = PathUtils::Path(fn); + CString base = PathUtils::StripExtensionAndMultiVolumeRarSuffix(fn); WIN32_FIND_DATA fd; ZeroMemory(&fd, sizeof(WIN32_FIND_DATA)); - HANDLE hFind = FindFirstFile(fn.Left(i) + _T("*.*"), &fd); + HANDLE hFind = FindFirstFile(base + _T("*.*"), &fd); if (hFind != INVALID_HANDLE_VALUE) { do { if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { @@ -199,14 +198,7 @@ void CPlaylistItem::AutoLoadFiles() } } while (pos != -1); - CString dir = fn; - dir.Replace('\\', '/'); - int l = dir.ReverseFind('/') + 1; - int l2 = dir.ReverseFind('.'); - if (l2 < l) { // no extension, read to the end - l2 = fn.GetLength(); - } - CString title = dir.Mid(l, l2 - l); + CString title = PathUtils::StripExtensionAndMultiVolumeRarSuffix(PathUtils::BaseName(fn)); paths.Add(title); CAtlArray ret;