diff --git a/SubtitleShifter.cpp b/SubtitleShifter.cpp index aa02656..6414099 100644 --- a/SubtitleShifter.cpp +++ b/SubtitleShifter.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -177,63 +178,113 @@ bool processASSFile(const std::filesystem::path &inputPath, std::filesystem::pat return true; } -void processDirectory(const std::filesystem::path &source, const std::filesystem::path &target, int offsetMs) { - if (!std::filesystem::exists(source)) { - std::cerr << "错误: 源目录不存在: " << source << std::endl; - return; +class SubtitleShifter { +public: + void setNameFilter(const std::string &prefix, const std::string &suffix) { + if (m_prefix != prefix) { + m_prefix = prefix; + } + if (m_suffix != suffix) { + m_suffix = suffix; + } } - - if (!std::filesystem::exists(target)) { - std::cout << "创建目标目录: " << target << std::endl; - if (!std::filesystem::create_directories(target)) { - std::cerr << "错误: 无法创建目标目录: " << target << std::endl; + void process(const std::filesystem::path &source, const std::filesystem::path &target, int offsetMs) { + if (!std::filesystem::exists(source)) { + std::cerr << "错误: 源目录不存在: " << source << std::endl; return; } - } - std::vector assFiles; - try { - for (const auto &entry : std::filesystem::directory_iterator(source)) { - if (entry.is_regular_file() && entry.path().extension() == ".ass") { - assFiles.push_back(entry.path()); + if (!std::filesystem::exists(target)) { + std::cout << "创建目标目录: " << target << std::endl; + if (!std::filesystem::create_directories(target)) { + std::cerr << "错误: 无法创建目标目录: " << target << std::endl; + return; } } - } catch (const std::filesystem::filesystem_error &ex) { - std::cerr << "文件系统错误: " << ex.what() << std::endl; - return; - } - if (assFiles.empty()) { - std::cout << "在目录 " << source << " 中未找到.ass文件" << std::endl; - return; - } - - std::cout << "找到 " << assFiles.size() << " 个.ass文件" << std::endl; - - for (const auto &sourceFile : assFiles) { - - // 生成目标文件名 - std::string targetFilename = generateTargetFilename( - sourceFile.filename().string(), "MONSTER.TV.2004.DVDRip-Hi.x264.AC3.1280.EP", "-nezumi.zh_CN"); - - // 确保文件扩展名为.ass - if (std::filesystem::path(targetFilename).extension() != ".ass") { - targetFilename += ".ass"; + std::vector assFiles; + try { + for (const auto &entry : std::filesystem::directory_iterator(source)) { + if (entry.is_regular_file() && entry.path().extension() == ".ass") { + assFiles.push_back(entry.path()); + } + } + } catch (const std::filesystem::filesystem_error &ex) { + std::cerr << "文件系统错误: " << ex.what() << std::endl; + return; } - std::filesystem::path targetFile = target / targetFilename; - // std::cout << sourceFile << " --> " << targetFile << std::endl; + if (assFiles.empty()) { + std::cout << "在目录 " << source << " 中未找到.ass文件" << std::endl; + return; + } - // 处理文件 - processASSFile(sourceFile, targetFile, offsetMs); + std::cout << "找到 " << assFiles.size() << " 个.ass文件" << std::endl; + + for (const auto &sourceFile : assFiles) { + // 生成目标文件名 + std::string targetFilename = sourceFile.filename().string(); + if (!m_prefix.empty() && !m_suffix.empty()) { + targetFilename = generateTargetFilename(sourceFile.filename().string(), m_prefix, m_suffix); + } + + // 确保文件扩展名为.ass + if (std::filesystem::path(targetFilename).extension() != ".ass") { + targetFilename += ".ass"; + } + + std::filesystem::path targetFile = target / targetFilename; + // std::cout << sourceFile << " --> " << targetFile << std::endl; + + // 处理文件 + processASSFile(sourceFile, targetFile, offsetMs); + } } -} + +private: + std::string m_prefix; + std::string m_suffix; +}; // 1. 找出指定目录下后缀为 `.ass` 下的文件 // 2. 如果目标文件夹不存在,则创建目标文件夹 // 3. 对每个源文件,提取文件名,然后按照模板提出字串,和目标文件夹拼凑成新的目标文件 +// ./build/shifter --offset 700 --prefix "[MONSTER][" --suffix "][JP_CN]" -I /mnt/d/Monster int main(int argc, char const *argv[]) { - processDirectory("/mnt/e/Downloads/[X2] MONSTER 2004 [Chs Subtitle]", - "/mnt/e/Downloads/[X2] MONSTER 2004 [Chs Subtitle]/output",700); -} + std::string input, output; + std::string prefix, suffix; + int offset; + boost::program_options::options_description desc("Allowed options"); + // clang-format off + desc.add_options() + ("help", "produce help message") + ("input,I", boost::program_options::value(&input),"set ass source path") + ("output,O", boost::program_options::value(&output)->default_value( "output"),"set ass source path") + ("offset", boost::program_options::value(&offset),"ass offset in millseconds") + ("prefix", boost::program_options::value(&prefix),"name prefix") + ("suffix", boost::program_options::value(&suffix),"name suffix"); + // clang-format on + boost::program_options::variables_map vm; + boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); + boost::program_options::notify(vm); + if (!vm.contains("offset")) { + std::cout << desc << std::endl; + return 1; + } + if (std::filesystem::path(output).is_relative()) { + std::ostringstream oss; + oss << input; + if (!input.ends_with('/')) { + oss << "/"; + } + oss << output; + output = oss.str(); + } + std::cout << "input: " << input << std::endl; + std::cout << "output: " << output << std::endl; + std::cout << "offset: " << offset << std::endl; + SubtitleShifter shifter; + shifter.setNameFilter(prefix, suffix); + shifter.process(input, output, offset); +}