Batch script to convert movies for Zune using ffmpeg

I have a first-generation Zune and am fairly happy with it. Music-wise, it’s much better than an iPod since half my music is in WMA format and I’m not about to transcode it. Video-wise, though, it doesn’t decode anything but WMV. This wouldn’t be such a big deal if the Zune software at least transcoded movies for you, but I’ve never had luck doing so (I think it chokes on anything using XVID codecs, for example). And I haven’t found any free 3rd-party apps that work out of the box.

Fortunately, there’s the trusty ffmpeg to the rescue. There are some Zune-optimized settings here, as well as a link to the latest Win32 binaries. So, with the following Windows Script Host script I wrote, you can transcode a whole directory at once.

 
// batch_ffmpeg.js - encodes all AVI files in input directory to Zune-compatible WMV files
// Note, this doesn't do full recursion; only top-level.  Also overwrites existing files.
 
// syntax:   cscript batch_ffmpeg.js full_path_to_inputdir full_path_to_outputdir
// e.g.,     cscript batch_ffmpeg.js C:\videos\ C:\videos_for_zune
 
// edit this for your system
var ffmpeg_path = "C:\\shared\\ffmpeg\\bin\\ffmpeg.exe";
 
dirArgs = WScript.Arguments;
if (dirArgs.length != 2) {
    WScript.echo("Error: specify absolute paths to input and ouput directories.\n" +
        "e.g., cscript batch_ffmpeg.js C:\\videos\ C:\\videos_for_zune ");
    WScript.Quit();
}
 
var inputdir = dirArgs(0);
var outputdir = dirArgs(1);
 
WshShell = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");
 
log("Starting...");
 
var fileArr = new Array();
 
// push into an array, since Enumerators know their length...
var fc = new Enumerator(fso.GetFolder(inputdir).files);
for (; !fc.atEnd(); fc.moveNext()) {
    var file = fc.item();
    if (file.name.match("\.avi$") != null)
        fileArr.push(file);
}
 
for (var i=0; i<fileArr.length; i++)
{
    var file = fileArr[i];
    log("Processing " + (i+1) + "/" + fileArr.length + " - " + file.name + "\n");
    outputfile = file.name + ".wmv";
    cmd = ffmpeg_path + " -i \"" + inputdir + "\\" + file.name + "\" -y -vcodec wmv2 " +
        "-acodec wmav2 -s 320x240 -b 640000 " +
        "-maxrate 1350000 -bufsize 2048000 -ab 128000 -ac 2 " +
        "\"" +outputdir + "\\" + outputfile + "\"";
 
    log("Done processing.  Return status=" + WshShell.Run(cmd, 1, true));
}
 
log("Done.");
 
function log(str) {
    WScript.StdOut.Write("[" + getTimestamp() + "] " + str + "\n");
}
function getTimestamp() {
    var date = new Date();
    var nowString = date.getFullYear() + "-";
    var month = (date.getUTCMonth() + 1);
    if (month < 10) {
        nowString += "0";
    }
    nowString += month + "-";
    dayOfMonth = date.getDate();
    if (dayOfMonth < 10) {
        nowString += "0";
    }
    nowString += dayOfMonth + " ";
    hours = date.getHours();
    if (hours < 10) {
        nowString += "0";
    }
    nowString += hours + ":";
    mins = date.getMinutes();
    if (mins < 10) {
        nowString += "0";
    }
    nowString += "" + mins;
 
    return nowString;
}

Leave a Reply

Your email address will not be published. Required fields are marked *