static void
help(std::function<void (string)> out)
{
- out(String::compose("Syntax: %1 [OPTION} <cpl-file> [<cpl-file> ... ]", program_name));
+ out(String::compose("Syntax: %1 [OPTION} <cpl-file|ID> [<cpl-file|ID> ... ]", program_name));
out(" -V, --version show libdcp version");
out(" -h, --help show this help");
out(" -o, --output output directory");
State::override_path = *config_dir;
}
- vector<boost::filesystem::path> cpl_filenames;
+ vector<string> cpl_filenames_or_ids;
for (int i = optind; i < argc; ++i) {
- cpl_filenames.push_back(argv[i]);
+ cpl_filenames_or_ids.push_back(argv[i]);
}
- if (cpl_filenames.empty()) {
+ if (cpl_filenames_or_ids.empty()) {
return string{"No CPL specified."};
}
/* Find all the CPLs */
vector<shared_ptr<dcp::CPL>> cpls;
- for (auto filename: cpl_filenames) {
- try {
- auto cpl = make_shared<dcp::CPL>(filename);
- cpl->resolve_refs(assets);
- cpls.push_back(cpl);
- } catch (std::exception& e) {
- return String::compose("Could not read CPL %1: %2", filename, e.what());
+ for (auto filename_or_id: cpl_filenames_or_ids) {
+ if (boost::filesystem::exists(filename_or_id)) {
+ try {
+ auto cpl = make_shared<dcp::CPL>(filename_or_id);
+ cpl->resolve_refs(assets);
+ cpls.push_back(cpl);
+ } catch (std::exception& e) {
+ return String::compose("Could not read CPL %1: %2", filename_or_id, e.what());
+ }
+ } else {
+ auto cpl_iter = std::find_if(assets.begin(), assets.end(), [filename_or_id](shared_ptr<dcp::Asset> asset) {
+ return asset->id() == filename_or_id;
+ });
+ if (cpl_iter == assets.end()) {
+ return String::compose("Could not find CPL with ID %1", filename_or_id);
+ }
+ if (auto cpl = dynamic_pointer_cast<dcp::CPL>(*cpl_iter)) {
+ cpl->resolve_refs(assets);
+ cpls.push_back(cpl);
+ } else {
+ return String::compose("Could not find CPL with ID %1", filename_or_id);
+ }
}
}
vector<string> already_copied;
- auto maybe_copy = [&assets, &already_copied, output_dir](
+ auto copy = [](
+ boost::filesystem::path input_path,
+ boost::filesystem::path output_path,
+ bool hard_link,
+ bool soft_link
+ ) {
+ dcp::filesystem::create_directories(output_path.parent_path());
+
+ boost::system::error_code ec;
+ if (hard_link) {
+ dcp::filesystem::create_hard_link(input_path, output_path, ec);
+ if (ec) {
+ throw CopyError(String::compose("Could not hard-link asset %1: %2", input_path.string(), ec.message()));
+ }
+ } else if (soft_link) {
+ dcp::filesystem::create_symlink(input_path, output_path, ec);
+ if (ec) {
+ throw CopyError(String::compose("Could not soft-link asset %1: %2", input_path.string(), ec.message()));
+ }
+ } else {
+ dcp::filesystem::copy_file(input_path, output_path, ec);
+ if (ec) {
+ throw CopyError(String::compose("Could not copy asset %1: %2", input_path.string(), ec.message()));
+ }
+ }
+ };
+
+ auto maybe_copy = [&assets, &already_copied, output_dir, copy](
string asset_id,
bool rename,
bool hard_link,
output_path /= (*iter)->file()->filename();
}
- dcp::filesystem::create_directories(output_path.parent_path());
-
- boost::system::error_code ec;
- if (hard_link) {
- dcp::filesystem::create_hard_link(input_path, output_path, ec);
- if (ec) {
- throw CopyError(String::compose("Could not hard-link asset %1: %2", input_path.string(), ec.message()));
- }
- } else if (soft_link) {
- dcp::filesystem::create_symlink(input_path, output_path, ec);
- if (ec) {
- throw CopyError(String::compose("Could not soft-link asset %1: %2", input_path.string(), ec.message()));
- }
- } else {
- dcp::filesystem::copy_file(input_path, output_path, ec);
- if (ec) {
- throw CopyError(String::compose("Could not copy asset %1: %2", input_path.string(), ec.message()));
- }
- }
+ copy(input_path, output_path, hard_link, soft_link);
(*iter)->set_file_preserving_hash(output_path);
already_copied.push_back(asset_id);
} else {
}
};
- auto maybe_copy_font = [&maybe_copy](shared_ptr<const dcp::SubtitleAsset> asset, bool rename, bool hard_link, bool soft_link) {
+ auto maybe_copy_font_and_images = [&maybe_copy, output_dir, copy](shared_ptr<const dcp::SubtitleAsset> asset, bool rename, bool hard_link, bool soft_link) {
auto interop = dynamic_pointer_cast<const dcp::InteropSubtitleAsset>(asset);
boost::optional<boost::filesystem::path> extra;
if (interop) {
for (auto font_asset: interop->font_assets()) {
maybe_copy(font_asset->id(), rename, hard_link, soft_link, extra);
}
+ for (auto subtitle: interop->subtitles()) {
+ if (auto image = dynamic_pointer_cast<const dcp::SubtitleImage>(subtitle)) {
+ auto const output_path = *output_dir / asset->id() / image->file()->filename();
+ copy(*image->file(), output_path, hard_link, soft_link);
+ }
+ }
}
return extra;
};
maybe_copy_from_reel(reel->main_picture(), rename, hard_link, soft_link);
maybe_copy_from_reel(reel->main_sound(), rename, hard_link, soft_link);
if (reel->main_subtitle()) {
- auto extra = maybe_copy_font(reel->main_subtitle()->asset(), rename, hard_link, soft_link);
+ auto extra = maybe_copy_font_and_images(reel->main_subtitle()->asset(), rename, hard_link, soft_link);
maybe_copy_from_reel(reel->main_subtitle(), rename, hard_link, soft_link, extra);
}
for (auto ccap: reel->closed_captions()) {
- auto extra = maybe_copy_font(ccap->asset(), rename, hard_link, soft_link);
+ auto extra = maybe_copy_font_and_images(ccap->asset(), rename, hard_link, soft_link);
maybe_copy_from_reel(ccap, rename, hard_link, soft_link, extra);
}
maybe_copy_from_reel(reel->atmos(), rename, hard_link, soft_link);