Topic: Transcode directory for iPod

I wrote a little script to transcode a directory of videos for my friend's iPod and thought it might be of use to others.  It mixes audio, resizes video and adds black bars only when required.

Just change the srcDir and dstDir to your liking and execute:
avidemux2_gtk --nogui --run "iPod.js" --quit

//AD

var app = new Avidemux();
var dirSearch = new DirectorySearch();
var srcDir = "C:/Videos/ToDo";     // pathOnly(fileReadSelect());
var dstDir = "C:/Videos/iPod";     // pathOnly(fileWriteSelect());

if (dirSearch.Init(srcDir))
{
    while (dirSearch.NextFile())
    {
        if (!dirSearch.isNotFile && !dirSearch.isSingleDot && !dirSearch.isDoubleDot)
        {
            app.forceUnpack();
            app.load(srcDir + "/" + dirSearch.GetFileName());
            app.audio.scanVBR();
            app.rebuildIndex();

            // Resizing
            var targetX = 320;
            var targetY = 240;

            var rX = app.video.getWidth() / targetX;
            var rY = app.video.getHeight() / targetY;
            var newX;
            var newY;

            if (rX > rY)
            {
                // resize by X
                newX = targetX;
                newY = Math.round(app.video.getHeight() / rX);
            }
            else
            {
                // resize by Y
                newY = targetY;
                newX = Math.round(app.video.getWidth() / rY);
            }

            // resize to multiple of 4
            newX -= newX % 4;
            newY -= newY % 4;

            if (newX != app.video.getWidth() || newY != app.video.getHeight())
                app.video.addFilter("mpresize", "w=" + newX, "h=" + newY, "algo=0");

            // Black bars
            var barX = targetX - newX;
            var barY = targetY - newY;
            
            if (barX || barY)
                app.video.addFilter("addblack", "left=" + (barX >> 1), "right=" + (barX >> 1), "top=" + (barY >> 1), "bottom=" + (barY >> 1));

            //** Video Codec conf **
            app.video.codec("XVID4","CBR=400","500 06 00 00 00 01 00 00 00 fa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 1f 00 00 00 1f 00 00 00 1f 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 05 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 00 00 00 64 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ");

            //** Audio **
            app.audio.reset();
            app.audio.codec("aac",128,4,"80 00 00 00 ");
            app.audio.normalizeMode=0;
            app.audio.normalizeValue=0;
            app.audio.delay=0;

            if (app.audio.getNbChannels(0) != 2)
                app.audio.mixer("STEREO");

            app.setContainer("MP4");

            // Clip off source extension and save to destination with mp4 extension
            var srcFile = dirSearch.GetFileName();
            
            app.save(dstDir + "/" + srcFile.substring(0, srcFile.length - dirSearch.GetExtension().length) + "mp4");
        }
    }
}

Re: Transcode directory for iPod

If you're on Windows I don't think there is currently a way of scripting this unless you create the output directory structure manually first (or via a batch file).

Re: Transcode directory for iPod

surlyjake wrote:

How can we make the script traverse the sub-directories?

This should work for r4279 or later:

//AD

function processFile(inputPath, inputFile, outputDirectory)
{
    app.forceUnpack();
    app.load(inputPath);
    app.audio.scanVBR();
    app.rebuildIndex();

    // Resizing
    var targetX = 320;
    var targetY = 240;

    var rX = app.video.getWidth() / targetX;
    var rY = app.video.getHeight() / targetY;
    var newX;
    var newY;

    if (rX > rY)
    {
        // resize by X
        newX = targetX;
        newY = Math.round(app.video.getHeight() / rX);
    }
    else
    {
        // resize by Y
        newY = targetY;
        newX = Math.round(app.video.getWidth() / rY);
    }

    // resize to multiple of 4
    newX -= newX % 4;
    newY -= newY % 4;

    if (newX != app.video.getWidth() || newY != app.video.getHeight())
        app.video.addFilter("mpresize", "w=" + newX, "h=" + newY, "algo=0");

    // Black bars
    var barX = targetX - newX;
    var barY = targetY - newY;

    if (barX || barY)
        app.video.addFilter("addblack", "left=" + (barX >> 1), "right=" + (barX >> 1), "top=" + (barY >> 1), "bottom=" + (barY >> 1));

    //** Video Codec conf **
    app.video.codec("XVID4","CBR=400","500 06 00 00 00 01 00 00 00 fa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 1f 00 00 00 1f 00 00 00 1f 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 05 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 00 00 00 64 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ");

    //** Audio **
    app.audio.reset();
    app.audio.codec("aac",128,4,"80 00 00 00 ");
    app.audio.normalizeMode=0;
    app.audio.normalizeValue=0;
    app.audio.delay=0;

    if (app.audio.getNbChannels(0) != 2)
        app.audio.mixer("STEREO");

    app.setContainer("MP4");

    // Clip off source extension and save to destination with mp4 extension
    var srcFile = inputFile;
    var extensionIndex = srcFile.lastIndexOf(".");

    // Crude check for Windows
    if (inputPath.lastIndexOf("\\") != -1)
    {
        outputDirectory = outputDirectory.replace(/\//g, "\\");

        exec("cmd.exe", new Array("/C", "mkdir", outputDirectory), true);
    }
    else
        exec("/bin/mkdir", new Array(outputDirectory), true);

    app.save(outputDirectory + "/" + srcFile.substring(0, extensionIndex + 1) + "mp4");
}

function processDirectory(inputDirectory, outputDirectory)
{
    var dirSearch = new DirectorySearch();

    if (dirSearch.Init(inputDirectory))
    {
        while (dirSearch.NextFile())
        {
            if (dirSearch.isSingleDot || dirSearch.isDoubleDot)
                continue;
            else if (dirSearch.isDirectory)
                processDirectory(dirSearch.GetFilePath(), outputDirectory + "/" + dirSearch.GetFileName());
            else if (!dirSearch.isNotFile && dirSearch.GetExtension() != "idx")
                processFile(dirSearch.GetFilePath(), dirSearch.GetFileName(), outputDirectory);
        }
    }

    dirSearch.Close();
}

var app = new Avidemux();
var dirSearch = new DirectorySearch();
var srcDir = "C:/Test/input";
var dstDir = "C:/Test/output";

processDirectory(srcDir, dstDir);

Last edited by gruntster (2008-09-08 18:39:42)

Re: Transcode directory for iPod

1. Make sure you run avidemux2_gtk with the --nogui flag.
2. Yes, you will need the latest SVN build to use the "sub-directory" script because the exec() function wasn't implemented for Windows in earlier versions of Avidemux.  You can download the latest versions from my website (the link is in my signature).


EDIT: I assume you're on Windows?

Last edited by gruntster (2008-07-25 17:59:12)

Re: Transcode directory for iPod

The exec() function was implemented for Linux and Mac but there was also a bug in the passing of args.

Changing the exec line to the following may work but ideally you need the SVN version:

exec("mkdir", new Array("mkdir", outputDirectory), true);

Re: Transcode directory for iPod

The Subtitler filter requires the following syntax:

app.video.addFilter("subtitle","_subname=C:\\subs.srt","_fontname=C:\\Windows\\Fonts\\arial.ttf","_charset=ISO-8859-1","_baseLine=1016","_Y_percent=255","_U_percent=0","_V_percent=0","_selfAdjustable=0","_delay=0","_useBackgroundColor=0","_bg_Y_percent=0","_bg_U_percent=0","_bg_V_percent=0","_blend=1");

Re: Transcode directory for iPod

Have you tried to add subtitles using GUI and then using the File -> Save project as... to check (open the project file with text editor) that filenames and folders etc are correct?

Re: Transcode directory for iPod

Try changing the exec line to the following:

exec("/bin/mkdir", new Array(outputDirectory), true);

Re: Transcode directory for iPod

I've updated the script in my previous post.  I only changed the app.save() line.  Could you please give this modification a try?

Last edited by gruntster (2008-09-08 18:42:44)

Re: Transcode directory for iPod

You can use the fileReadSelect() function to display a file dialog to manually select a directory.

Alternatively, if you want to automate the process you could set the srcDir variable using a separate js file and use the include() function in your main script.  e.g.

your wrapper script:

echo var srcDir=/home/grant/videos > setsrcvar.js
avidemux2_gtk --nogui --run iPod.js --quit

modify iPod.js to something like this:

...

var app = new Avidemux();
var dirSearch = new DirectorySearch();
var dstDir = "/home/grant/iPod";

// Set srcDir
include("setsrcvar.js");

...