diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp index 83d0a2ec3..25722473c 100644 --- a/UI/obs-app.cpp +++ b/UI/obs-app.cpp @@ -1657,6 +1657,119 @@ string GenerateSpecifiedFilename(const char *extension, bool noSpace, return string(filename); } +static void FindBestFilename(string &strPath, bool noSpace) +{ + int num = 2; + + if (!os_file_exists(strPath.c_str())) + return; + + const char *ext = strrchr(strPath.c_str(), '.'); + if (!ext) + return; + + int extStart = int(ext - strPath.c_str()); + for (;;) { + string testPath = strPath; + string numStr; + + numStr = noSpace ? "_" : " ("; + numStr += to_string(num++); + if (!noSpace) + numStr += ")"; + + testPath.insert(extStart, numStr); + + if (!os_file_exists(testPath.c_str())) { + strPath = testPath; + break; + } + } +} + +static void ensure_directory_exists(string &path) +{ + replace(path.begin(), path.end(), '\\', '/'); + + size_t last = path.rfind('/'); + if (last == string::npos) + return; + + string directory = path.substr(0, last); + os_mkdirs(directory.c_str()); +} + +static void remove_reserved_file_characters(string &s) +{ + replace(s.begin(), s.end(), '\\', '/'); + replace(s.begin(), s.end(), '*', '_'); + replace(s.begin(), s.end(), '?', '_'); + replace(s.begin(), s.end(), '"', '_'); + replace(s.begin(), s.end(), '|', '_'); + replace(s.begin(), s.end(), ':', '_'); + replace(s.begin(), s.end(), '>', '_'); + replace(s.begin(), s.end(), '<', '_'); +} + +string GetFormatString(const char *format, const char *prefix, + const char *suffix) +{ + string f; + + if (prefix && *prefix) { + f += prefix; + if (f.back() != ' ') + f += " "; + } + + f += format; + + if (suffix && *suffix) { + if (*suffix != ' ') + f += " "; + f += suffix; + } + + remove_reserved_file_characters(f); + + return f; +} + +string GetOutputFilename(const char *path, const char *ext, bool noSpace, + bool overwrite, const char *format) +{ + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + + os_dir_t *dir = path && path[0] ? os_opendir(path) : nullptr; + + if (!dir) { + if (main->isVisible()) + OBSMessageBox::warning(main, + QTStr("Output.BadPath.Title"), + QTStr("Output.BadPath.Text")); + else + main->SysTrayNotify(QTStr("Output.BadPath.Text"), + QSystemTrayIcon::Warning); + return ""; + } + + os_closedir(dir); + + string strPath; + strPath += path; + + char lastChar = strPath.back(); + if (lastChar != '/' && lastChar != '\\') + strPath += "/"; + + strPath += GenerateSpecifiedFilename(ext, noSpace, format); + ensure_directory_exists(strPath); + if (!overwrite) + FindBestFilename(strPath, noSpace); + + return strPath; +} + vector> GetLocaleNames() { string path; diff --git a/UI/obs-app.hpp b/UI/obs-app.hpp index e10ea6bdd..cb67df0e4 100644 --- a/UI/obs-app.hpp +++ b/UI/obs-app.hpp @@ -40,6 +40,10 @@ std::string GenerateTimeDateFilename(const char *extension, bool noSpace = false); std::string GenerateSpecifiedFilename(const char *extension, bool noSpace, const char *format); +std::string GetFormatString(const char *format, const char *prefix, + const char *suffix); +std::string GetOutputFilename(const char *path, const char *ext, bool noSpace, + bool overwrite, const char *format); QObject *CreateShortcutFilter(); struct BaseLexer { diff --git a/UI/window-basic-main-outputs.cpp b/UI/window-basic-main-outputs.cpp index 47eb33070..708cb270a 100644 --- a/UI/window-basic-main-outputs.cpp +++ b/UI/window-basic-main-outputs.cpp @@ -164,36 +164,6 @@ static void OBSStopVirtualCam(void *data, calldata_t *params) UNUSED_PARAMETER(params); } -static void FindBestFilename(string &strPath, bool noSpace) -{ - int num = 2; - - if (!os_file_exists(strPath.c_str())) - return; - - const char *ext = strrchr(strPath.c_str(), '.'); - if (!ext) - return; - - int extStart = int(ext - strPath.c_str()); - for (;;) { - string testPath = strPath; - string numStr; - - numStr = noSpace ? "_" : " ("; - numStr += to_string(num++); - if (!noSpace) - numStr += ")"; - - testPath.insert(extStart, numStr); - - if (!os_file_exists(testPath.c_str())) { - strPath = testPath; - break; - } - } -} - /* ------------------------------------------------------------------------ */ static bool CreateAACEncoder(OBSEncoder &res, string &id, int bitrate, @@ -903,30 +873,6 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) return false; } -static void remove_reserved_file_characters(string &s) -{ - replace(s.begin(), s.end(), '\\', '/'); - replace(s.begin(), s.end(), '*', '_'); - replace(s.begin(), s.end(), '?', '_'); - replace(s.begin(), s.end(), '"', '_'); - replace(s.begin(), s.end(), '|', '_'); - replace(s.begin(), s.end(), ':', '_'); - replace(s.begin(), s.end(), '>', '_'); - replace(s.begin(), s.end(), '<', '_'); -} - -static void ensure_directory_exists(string &path) -{ - replace(path.begin(), path.end(), '\\', '/'); - - size_t last = path.rfind('/'); - if (last == string::npos) - return; - - string directory = path.substr(0, last); - os_mkdirs(directory.c_str()); -} - void SimpleOutput::UpdateRecording() { if (replayBufferActive || recordingActive) @@ -977,54 +923,15 @@ bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer) int rbSize = config_get_int(main->Config(), "SimpleOutput", "RecRBSize"); - os_dir_t *dir = path && path[0] ? os_opendir(path) : nullptr; - - if (!dir) { - if (main->isVisible()) - OBSMessageBox::warning(main, - QTStr("Output.BadPath.Title"), - QTStr("Output.BadPath.Text")); - else - main->SysTrayNotify(QTStr("Output.BadPath.Text"), - QSystemTrayIcon::Warning); - return false; - } - - os_closedir(dir); - + string f; string strPath; - strPath += path; - - char lastChar = strPath.back(); - if (lastChar != '/' && lastChar != '\\') - strPath += "/"; - - strPath += GenerateSpecifiedFilename(ffmpegOutput ? "avi" : format, - noSpace, filenameFormat); - ensure_directory_exists(strPath); - if (!overwriteIfExists) - FindBestFilename(strPath, noSpace); obs_data_t *settings = obs_data_create(); if (updateReplayBuffer) { - string f; - - if (rbPrefix && *rbPrefix) { - f += rbPrefix; - if (f.back() != ' ') - f += " "; - } - - f += filenameFormat; - - if (rbSuffix && *rbSuffix) { - if (*rbSuffix != ' ') - f += " "; - f += rbSuffix; - } - - remove_reserved_file_characters(f); - + f = GetFormatString(filenameFormat, rbPrefix, rbSuffix); + strPath = GetOutputFilename(path, ffmpegOutput ? "avi" : format, + noSpace, overwriteIfExists, + f.c_str()); obs_data_set_string(settings, "directory", path); obs_data_set_string(settings, "format", f.c_str()); obs_data_set_string(settings, "extension", format); @@ -1033,6 +940,10 @@ bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer) obs_data_set_int(settings, "max_size_mb", usingRecordingPreset ? rbSize : 0); } else { + f = GetFormatString(filenameFormat, nullptr, nullptr); + strPath = GetOutputFilename(path, ffmpegOutput ? "avi" : format, + noSpace, overwriteIfExists, + f.c_str()); obs_data_set_string(settings, ffmpegOutput ? "url" : "path", strPath.c_str()); } @@ -1779,34 +1690,9 @@ bool AdvancedOutput::StartRecording() ? "FFFileNameWithoutSpace" : "RecFileNameWithoutSpace"); - os_dir_t *dir = path && path[0] ? os_opendir(path) : nullptr; - - if (!dir) { - if (main->isVisible()) - OBSMessageBox::warning( - main, QTStr("Output.BadPath.Title"), - QTStr("Output.BadPath.Text")); - else - main->SysTrayNotify( - QTStr("Output.BadPath.Text"), - QSystemTrayIcon::Warning); - return false; - } - - os_closedir(dir); - - string strPath; - strPath += path; - - char lastChar = strPath.back(); - if (lastChar != '/' && lastChar != '\\') - strPath += "/"; - - strPath += GenerateSpecifiedFilename(recFormat, noSpace, - filenameFormat); - ensure_directory_exists(strPath); - if (!overwriteIfExists) - FindBestFilename(strPath, noSpace); + string strPath = GetOutputFilename(path, recFormat, noSpace, + overwriteIfExists, + filenameFormat); obs_data_t *settings = obs_data_create(); obs_data_set_string(settings, ffmpegRecording ? "url" : "path", @@ -1879,53 +1765,11 @@ bool AdvancedOutput::StartReplayBuffer() rbTime = config_get_int(main->Config(), "AdvOut", "RecRBTime"); rbSize = config_get_int(main->Config(), "AdvOut", "RecRBSize"); - os_dir_t *dir = path && path[0] ? os_opendir(path) : nullptr; - - if (!dir) { - if (main->isVisible()) - OBSMessageBox::warning( - main, QTStr("Output.BadPath.Title"), - QTStr("Output.BadPath.Text")); - else - main->SysTrayNotify( - QTStr("Output.BadPath.Text"), - QSystemTrayIcon::Warning); - return false; - } - - os_closedir(dir); - - string strPath; - strPath += path; - - char lastChar = strPath.back(); - if (lastChar != '/' && lastChar != '\\') - strPath += "/"; - - strPath += GenerateSpecifiedFilename(recFormat, noSpace, - filenameFormat); - ensure_directory_exists(strPath); - if (!overwriteIfExists) - FindBestFilename(strPath, noSpace); + string f = GetFormatString(filenameFormat, rbPrefix, rbSuffix); + string strPath = GetOutputFilename( + path, recFormat, noSpace, overwriteIfExists, f.c_str()); obs_data_t *settings = obs_data_create(); - string f; - - if (rbPrefix && *rbPrefix) { - f += rbPrefix; - if (f.back() != ' ') - f += " "; - } - - f += filenameFormat; - - if (rbSuffix && *rbSuffix) { - if (*rbSuffix != ' ') - f += " "; - f += rbSuffix; - } - - remove_reserved_file_characters(f); obs_data_set_string(settings, "directory", path); obs_data_set_string(settings, "format", f.c_str());