Windows script to convert all media files in a root dir?

Discussion of the HandBrake command line interface (CLI)
Forum rules
An Activity Log is required for support requests. Please read How-to get an activity log? for details on how and why this should be provided.
Post Reply
thomas
Posts: 4
Joined: Wed Mar 14, 2012 6:01 am

Windows script to convert all media files in a root dir?

Post by thomas »

1) I found several scripts on this forum but they're mostly for Linux/Mac. Does anyone know of a Windows script that fits my needs (see #2 below)? I'm fairly familiar with Linux scripting, but not Windows scripting. Is Windows scripting flexible enough or should I just go for Linux scripting? (mind that I don't have a Linux machine so I probably have to use cygwin)

2) I have numerous media files in a wide variety of formats (.avi, .mpg, .mpeg, .rm, .mov, .asf, .wmv, etc.) spread across a large number of subfolders all within a single root directory. Most scripts I found only work for a particular media format. Does anyone know if there's a way to test whether a file is a video file (instead of text, photo, docs, pdf, etc)? or should I just attempt to use HandBrake on any file and let it fail if it's not a video file?

Thanks,
sub0ptimal
Posts: 3
Joined: Tue Mar 27, 2012 8:01 pm

Re: Windows script to convert all media files in a root dir?

Post by sub0ptimal »

Cygwin is the easiest way if you are looking to borrow from existing scripts.

Windows batch files are pretty weak. Powershell is better, but the syntax is nothing like Linux shell script.
thomas
Posts: 4
Joined: Wed Mar 14, 2012 6:01 am

Re: Windows script to convert all media files in a root dir?

Post by thomas »

Found a solution: wrote a Perl script to run on Windows and don't have to deal with compiling HandBrakeCLI from source for Cygwin. Only need ActivePerl installed to run the script. Shared here with the community.

Code: Select all

use strict;
use warnings;
use File::Basename;    # for fileparse()
use File::Find;        # for find()
use Cwd 'abs_path';    # for abs_path()
use Getopt::Std;       # for getopts()

# Parse command line options and arguments
if (scalar(@ARGV) < 1) {
	print "usage: $0 -c <dir1> [<dir2>...]\n";
	print "  Convert all media files in specified directories\n";
	print "  -c: Delete input files after successful conversions (use with care!)\n";
	exit;
}
my %opts;
getopts('c', \%opts);
if ($opts{c}) {
	warn "\n!!Input files will be deleted after successful conversions!!\n\n";
}

# Full path to HandBrakeCLI executable
my $HandBrakeCLI = "\"c:\\Program Files\\Handbrake\\HandBrakeCLI.exe\"";

# Full path to log file
my $logfile = "\"c:\\temp\\handbrake.log\"";

# Extensions of files to convert
my @exts = (".avi", ".wmv", ".asf", ".mpg" , ".mpeg", ".ogm", 
            ".rm", ".rmvb", ".mkv");
						
# Handbrake preset name
my $preset = "M4V_Web_128";

# Targeted extension
my $newExt = ".m4v";

# Array to contain files to convert
my @allInputs;

# Recursively gets all directory listings and filter files of interest
foreach my $dir (@ARGV)
{
	$dir = abs_path($dir);
	find(\&Filter, $dir);
}

# Check number of files of interest
my $numFiles = scalar(@allInputs);
if ($numFiles == 0) {
	print "No matched files to process\n";
	exit;
}

# Perform HandBrake conversions on files of interest
my $count = 0;
foreach my $infile (@allInputs)
{
	# Output file has same name and in same directory as input file, only
	# the extension is changed
	my ($base, $path, $ext) = fileparse($infile, @exts);
	my $outfile = "$path$base$newExt";
	
	# Assemble the command line for HandBrake conversion
	my $logger = ">> $logfile 2>&1";
	my $cmd = "$HandBrakeCLI -i \"$infile\" -o \"$outfile\" --preset=\"$preset\" $logger";
	
	# Log command
	system("echo $cmd $logger");
	$count++;
	print "($count/$numFiles) $infile ... ";
	
	# Perform the conversion
	my $status = system($cmd);

	# Log status and clean up
	if ($status == 0) {
		# Conversion succeeded, delete input file
		system("del /f \"$infile\"") if ($opts{c});
		print "done\n";
	} 
	else {
		# Conversion failed, delete output file
		system("del /f \"$outfile\"") if ($opts{c});
		print "failed!\n";
	}
	system("echo exit status: $status $logger");
	system("echo ===================================== $logger");
}

# Filter directory listings and save only files with extensions in @exts
# to array @allInputs
sub Filter
{
	# Filter out directories
	return if (-d "$File::Find::name");
	
	# Replace forward slashes with backslashes to work on Windows
	my $infile = "$File::Find::name";
	$infile =~ s#/#\\#g;
	
	# Parse a full path name into its constituent path, basename, and extension
	my ($base, $path, $ext) = fileparse($infile, @exts);
	
	# Filter out files that don't have extensions in @exts
	return if ($ext eq "");
	
	# Skip if file has already been processed
	return if (-f "$path$base$newExt");
	
	# Save to @allInputs array
	push(@allInputs, $infile);
}
PatRichard
Posts: 1
Joined: Sun Apr 01, 2012 2:28 pm

Re: Windows script to convert all media files in a root dir?

Post by PatRichard »

See my blog post at http://www.ehloworld.com/643 for a PowerShell script that I've used to convert thousands of files via HandBrake.
MilkmanWes
Posts: 4
Joined: Sat Sep 22, 2012 1:16 pm

Re: Windows script to convert all media files in a root dir?

Post by MilkmanWes »

Not to disregard all the previous suggestions, but OP wanted to do this in Windows and it is very possible to do so

Code: Select all

for %%f in (*.mkv) do (
	echo %%~nxf
)
in a windows batch script this will cycle through all files with the extension mkv and echo the name to the screen. replace the echo command with:

Code: Select all

handbrakecli -s %%~nxf blah blah blah
To expand this, if all files in the folder are subject to the same handbrake command you could do

Code: Select all

for %%f in (*.*) do (
	echo %%~nxf
)
or if each media type needs separate settings in HB:

Code: Select all

for %%f in (*.avi) do (
	echo %%~nxf
)

for %%f in (*.mp4) do (
	echo %%~nxf
)

and so on and so forth.

Don't let people turning their noses up at Windows make you believe that batch files under windows are powerless and limited. Yes, you will frequently find more examples and people able/willing to answer questions for other methods than a windows bat file, but it doesn't mean it is impossible
MilkmanWes
Posts: 4
Joined: Sat Sep 22, 2012 1:16 pm

Re: Windows script to convert all media files in a root dir?

Post by MilkmanWes »

an addendum to the above

%%~nf = name of the file
%%~nxf = name with extension
%%~pnxf = path (without drive letter) name and extension of the file
%%~dpnxf = drive letter:\path\name.extension
MilkmanWes
Posts: 4
Joined: Sat Sep 22, 2012 1:16 pm

Re: Windows script to convert all media files in a root dir?

Post by MilkmanWes »

A windows batch file to unzip and convert and make sure that it doesnt run handbrakecli concurrently with other instances

Code: Select all

REM Make it less chatty
@echo off

REM If you leave tis out, you're gonna have a bad day
@SETLOCAL enabledelayedexpansion

REM Take the folder passed as a command line parameter and look for all RAR files in it
for %%f in (%1\*.rar) do (

REM %%~dpnxf - full drive:\path\name.ext of the file in this iteration passed to WinRAR
REM %%~dpf - drive:\path of the file, but you can send this wherever you want, just update 
REM the paths in the handbrake loop below accordingly
	WinRAR x -idcdpq "%%~dpnxf" "%%~dpf"
	)
	
REM Look for all mkv files in the %1 folder
for %%f in (%1\*.mkv) do (

REM Go to :test to see if handbrake is already running
	call :test

REM Set a location for output. use quotes if path has spaces. 
REM %%~nf is name of the file in this routine so add extension
	set HANDBRAKE_OUT=I:\incomming\processed\%%~nf.mp4

REM Build your command line, note use of ! not % inside loop
	"c:\Program Files\Handbrake\HandBrakeCLI.exe" -i "%%~dpnxf" -o "!HANDBRAKE_OUT!"

REM Clean up the variable to make a clean start on the next loop
	set HANDBRAKE_OUT=
	)

REM Go to the end of the file, all done here
goto :end
	
:test
REM Use the tasklist piped to find to determine if it is running
REM Redirecting output to NUL since we really dont care about the results, 
REM just if it was successful
tasklist /FI "imagename eq handbrakecli.exe" 2 > NUL | find /I /N "handbrakecli.exe" > NUL

REM Errorlevel 1 indicates nothing found, 0 if it succeeded (no error)
REM So if there is an error jump to end of function which 
REM returns us back to where the function was CALLed from
if %ERRORLEVEL% == 1 goto :eof

REM If it was found to be running we get here and use timeout to wait 1800 secs (30 mins)
REM Reset to whatever time you like.
REM Redirecting to NUL since we do not want to see the countdown timer, remove if you want
timeout 1800 > NUL

REM When timeout is done we go back to the beginning of this function
goto :test

REM End of the batch file
:end
REM Counterpart to SETLOCAL above
ENDLOCAL
thomas
Posts: 4
Joined: Wed Mar 14, 2012 6:01 am

Re: Windows script to convert all media files in a root dir?

Post by thomas »

@MilkmanWes
Thanks for the very helpful inputs and suggestions. You opened my eyes to the potential of Windows batch scripting.

I recently worked on a new project that requires extensive Windows batch scripting. Do you know of any good resources (such as books, online tutorials, etc.) that teach Windows batch scripting? I am looking for something that starts out basic, but doesn't dwell on the basics for too long (I already know about looping, branching concepts, etc.), then rapidly advances to the intermediate and advanced stages. Bonus points if it can be used as deskside reference. And BTW, my company is still stuck in Windows XP so I have no PowerShell available (and before you ask, no I cannot install anything, I must use everything available as is).

Thanks,
JaKohl
Posts: 5
Joined: Wed Dec 12, 2012 11:08 am

Re: Windows script to convert all media files in a root dir?

Post by JaKohl »

I just made a quick little app to do just this thing as I wanted to convert my entire library.

https://dl.dropbox.com/u/197176/HMR.zip
Barry D.
Posts: 21
Joined: Thu Feb 26, 2015 4:13 pm

Re: Windows script to convert all media files in a root dir?

Post by Barry D. »

JaKohl wrote:I just made a quick little app to do just this thing as I wanted to convert my entire library.

https://dl.dropbox.com/u/197176/HMR.zip
Any chance you can make this available again? Thanks.
Barry D.
Posts: 21
Joined: Thu Feb 26, 2015 4:13 pm

Re: Windows script to convert all media files in a root dir?

Post by Barry D. »

JaKohl: While waiting to see what you have or if you are still around to share it, I put together a couple of batch files that are chugging away as we sleep. Working great on my TV series but it's going to more labor intensive on my movies...so I am still interested.
Post Reply