add options.
Some checks failed
Deploy Applications / PullDocker (push) Failing after 4s
Deploy Applications / Build (push) Failing after 2s
Windows CI / build (push) Has been cancelled

This commit is contained in:
2025-10-27 22:22:51 +08:00
parent a842d429b7
commit 8c2c912d3a

View File

@@ -1,6 +1,7 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/program_options.hpp>
#include <filesystem>
#include <fstream>
#include <iostream>
@@ -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<std::filesystem::path> 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<std::filesystem::path> 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<std::string>(&input),"set ass source path")
("output,O", boost::program_options::value<std::string>(&output)->default_value( "output"),"set ass source path")
("offset", boost::program_options::value<int>(&offset),"ass offset in millseconds")
("prefix", boost::program_options::value<std::string>(&prefix),"name prefix")
("suffix", boost::program_options::value<std::string>(&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);
}