I wanted a way to run the contents of a folder through ffmpeg and turn some mp4 files into avi's my dvd player could play, after a bit of trial an error, below is what I ended up with! As it is made with D, there are no dependencies and it is fast and fairly memory safe. I did not use any one line cleverness so it is pretty easy to understand too!
The code below has been extended to show how other file types could be added to the process.
import std.stdio; import std.file; import std.algorithm:endsWith; import std.process; void main(string[] args){ // Make sure we have a folder passed string fn; if (args.length>1){ fn=args[1]; }else{ writeln("Processes a folder"); writeln("Usage: ",args[0]," [folder]"); return; } // Check to see if passed item exists and really is a folder! if (exists(fn)){ if (fn.isDir==false){ writeln("Error! Not a folder!"); return; } }else{ writeln("Cannot find this folder!"); return; } foreach(string name; dirEntries(fn, SpanMode.shallow)){ auto infile=name; string outfile=null; string[] runme; // Run the MP4 through FFMPEG (which is in my path) if (name.endsWith(".mp4")){ outfile=name[0..$-4]~".avi"; runme=["ffmpeg.exe","-i",infile,"-vtag","xvid","-q:v","5",outfile]; } // Recompress a folder of JPEG files as JPEG XL using CJXL (which is also in my path) if (name.endsWith(".jpg")){ outfile=name[0..$-4]~".jxl"; runme=["cjxl.exe",infile,outfile]; } // If our outfile name is still 'null' then we have not been able to process. if (outfile!=null){ // Only convert if the destination file does not exist so we do not overwrite! if (exists(outfile)==false){ writeln(infile~" => "~outfile); auto proc = execute(runme); if (proc.status != 0) writeln("Failed:\n", proc.output); }else{ writeln(infile~" == Skipping! (Already processed?)"); } }else{ writeln(infile~" == Skipping! (Unknown file type)"); } } }
Save the above and compile with your favourite D compiler, run specifying a folder to process. For example, if we saved the above as list.d, we would compile with dmd list.d and would get a file called list.exe. Using the above, to encode a folder using FFMPEG we would do the following:
>list test test\witch_transform.mp4 => test\witch_transform.avi
And if we run it again:
>list c:\myfolder test\witch_transform.avi == Skipping! (Unknown file type) test\witch_transform.mp4 == Skipping! (Already processed?)
The above can be easily modified for other tasks, for example to compress a folder of files as JPEG XL you could add the following:
// Recompress a folder of JPEG files as JPEG XL using CJXL (which is also in my path)
if (name.endsWith(".jpg")){
outfile=name[0..$-4]~".jxl";
runme=["cjxl.exe",infile,outfile];
}
Although many applications (such as IrfanView) have batch options, the above is useful if you need to be able to schedule an encode or if the utility you use does not allow the use of wildcards. Folder contents processing is the sort of task may be given to a scripting language like Python, using D instead would likely be much faster and mean less hardware resources are required which is both cheaper and better for the planet as detailed in this greener software guide.
Updated 15/12/2024
Created 12/12/2024