Skip to content

Commit 1a60435

Browse files
committed
improved -movie action
Signed-off-by: Ken Museth <ken.museth@gmail.com>
1 parent e885dc9 commit 1a60435

File tree

2 files changed

+27
-26
lines changed

2 files changed

+27
-26
lines changed

openvdb_cmd/vdb_tool/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ endif()
111111

112112
if(OPENVDB_TOOL_USE_MPEG)
113113
target_compile_definitions(vdb_tool_common INTERFACE "VDB_TOOL_USE_MPEG")
114+
find_program(FFMPEG_PATH NAMES ffmpeg REQUIRED)
114115
endif()
115116

116117
if(OPENVDB_TOOL_USE_EXR)

openvdb_cmd/vdb_tool/include/Tool.h

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ class Tool
211211
void quadsToTriangles();
212212

213213
/// @brief Convert multiple image files to a mpeg movie file
214-
void imgToMpeg();
214+
void movie();
215215

216216
/// @brief construct a LoD sequences of VDB trees with powers of two refinements
217217
void multires();
@@ -449,13 +449,14 @@ void Tool::init()
449449
[&](){mParser.setDefaults();}, [&](){this->quadsToTriangles();});
450450

451451
mParser.addAction(
452-
{"img2mpeg"}, "Convert multiple images to an mpeg file",
453-
{{"framerate", "24", "30", "desired frame rate of mpeg movie"},
454-
{"input", "slice_*.ppm", "input.avi", "input image files"},
455-
{"output", "slices.mp4", "output.mp4", "name out output mpeg file."},
452+
{"movie", "img2mpeg", "mov2mpeg", "mov2gif", "img2gif"}, "Convert image and movie files to mpeg or animated gif files",
453+
{{"fps", "24", "24", "desired frame rate of mpeg movie"},
454+
{"input", "slice_*.ppm", "slice_*.ppm|input.avi", "input image files or movie file to get converted"},
455+
{"output", "slices.mp4", "output.mp4|output.gif", "name of output mpeg or gif file"},
456+
{"scale", "", "1280x720|640", "scale of the output movie or gif."},
456457
{"flip", "", "vertical|horizontal|180", "flip output video vertical or horizontal or rotate it by 180"},
457458
{"keep", "true", "1|0|true|false", "toggle wether the input images are preserved or deleted after the conversion"}},
458-
[&](){mParser.setDefaults();}, [&](){this->imgToMpeg();});
459+
[&](){mParser.setDefaults();}, [&](){this->movie();});
459460

460461
mParser.addAction(
461462
{"mesh2ls", "mesh2sdf"}, "Convert a watertight polygon surface into a narrow-band level set, i.e. a narrow-band signed distance to a polygon mesh",
@@ -2679,49 +2680,48 @@ void Tool::slice()
26792680

26802681
// ==============================================================================================================
26812682

2682-
#ifdef VDB_TOOL_USE_MPEG
26832683
/// @brief Convert multiple image files to a mpeg movie file
26842684
// vdb_tool -sphere -for x=0,1,0.01 -slice X='{$x}' -end -img2mpeg input="slice_*.ppm" output=slices.mp4
26852685
// vdb_tool -sphere -for x=0,1,0.01 -slice X='{$x}' -end -img2mpeg && open slices.mp4
2686-
void Tool::imgToMpeg()
2686+
void Tool::movie()
26872687
{
2688-
const int framerate = mParser.get<int>("framerate");
2688+
#ifdef VDB_TOOL_USE_MPEG
2689+
const int fps = mParser.get<int>("fps");
26892690
const std::string input = mParser.get<std::string>("input");
26902691
const std::string output = mParser.get<std::string>("output");
2692+
const VecI scale = mParser.getVec<int>("scale", "x");
26912693
const bool keep = mParser.get<bool>("keep");
26922694
const std::string flip = mParser.get<std::string>("flip");
26932695

26942696
std::string cmd("ffmpeg"), log("log.txt");
26952697
cmd += " -loglevel error";// only log error messages
2696-
cmd += " -pattern_type glob";// support expanding shell-like wildcard patterns (globbing)
2697-
cmd += " -framerate " + std::to_string(framerate);// specify frame rate
2698+
if (contains(input, '*')) cmd += " -pattern_type glob";// support expanding shell-like wildcard patterns (globbing)
26982699
cmd += " -i \'" + input + "\'";// specify multiple input files as "input_*.ppm"
2699-
if (flip=="vertical") {
2700-
cmd += " -vf \"vflip\"";// flip vertical (up/down)
2701-
} else if (flip=="horizontal") {
2702-
cmd += " -vf \"hflip\"";// flip horizontal (left/right)
2703-
} else if (flip=="180") {
2704-
cmd += " -vf \"vflip,hflip\"";// rotate 180
2705-
} else if (flip!="") {
2706-
throw std::invalid_argument("Tool::imgToMpeg: invalid flip argument: \""+flip+"\", expected \"vertical\", \"horizontal\" or \"180\"");
2707-
}
2700+
cmd += " -vf \"fps=" + std::to_string(fps);
2701+
if (findMatch(flip,{"vertical", "180"})) cmd += ",vflip";// flip vertical (up/down)
2702+
if (findMatch(flip,{"horizontal","180"})) cmd += ",hflip";// flip horizontal (left/right)
2703+
if (flip!="" && !contains(cmd,"flip")) throw std::invalid_argument("Tool::movie: invalid argument flip=\""+flip+"\", expected \"vertical\", \"horizontal\" or \"180\"");
2704+
if (scale.size()==2) {
2705+
cmd += ",scale=" + std::to_string(scale[0]) + ":" + std::to_string(scale[1]) + ":flags=lanczos";
2706+
} else if (scale.size()==1) {
2707+
cmd += ",scale=" + std::to_string(scale[0]) + ":-1:flags=lanczos";
2708+
}
2709+
cmd += "\"";// end "-vf \"fps=..."
2710+
if (getExt(output) == "gif") cmd += " -c:v gif";// create animated gif
27082711
cmd += " -y " + output;// overwrite output files without asking
27092712
cmd += " > " + log + " 2>&1";// redirect stdout and stderr to log file
2710-
2713+
if (mParser.verbose) std::cerr << cmd << std::endl;
27112714
const int code = std::system(cmd.c_str());
27122715
if (code != 0) {
27132716
std::stringstream ss;
2714-
ss << "\nFatal error in Tool::imgToMpeg: " << code << "\n\"" << cmd << "\"\n" << std::ifstream(log).rdbuf();
2717+
ss << "\nFatal error in Tool::movie: " << code << "\n\"" << cmd << "\"\n" << std::ifstream(log).rdbuf();
27152718
throw std::runtime_error(ss.str());
27162719
}
27172720
std::system(("rm " + log).c_str());
2718-
}// Tool::imgToMpeg
27192721
#else
2720-
void Tool::imgToMpeg()
2721-
{
27222722
throw std::runtime_error("MPEG support was disabled during compilation!");
2723-
}// Tool::imgToMpeg
27242723
#endif
2724+
}// Tool::movie
27252725

27262726
// ==============================================================================================================
27272727
// LeVeque, R., High-Resolution Conservative Algorithms For Advection In Incompressible Flow, SIAM J. Numer. Anal. 33, 627–665 (1996)

0 commit comments

Comments
 (0)