====== Scripting tutorial ======
This page tries to explain how scripting works inside Avidemux.
The scripting engine used by Avidemux is SpiderMonkey, and it is an ECMAScript/JavaScript engine. We will walk through a simple script that removes the evil packed bitstream from a whole directory.
===== Headers =====
The following will probably be the two first lines of any Avidemux script:
//AD <-
var app = new Avidemux();
The first one is used by Avidemux to identify the file, and must be present (at least the four first characters : ////AD//).
The second line is where we instantiate the Avidemux class. Almost all Avidemux functions will be accessed through it, in our case app.
===== Setting up directories =====
We will declare a bunch of variables and set the incoming and outgoing dirs
//AD <-
/*
Simple script that scans the orgDir directory
and unpack all AVI files
The resulting file is put in destDir directory
Using new directorySearch API
*/
var app = new Avidemux();
var ds = new DirectorySearch();
var orgDir;
var destDir;
var reg =new RegExp(".$");
/*
This is for Unix
For Windows change to
sep="\\";
*/
var sep="/";
var extension;
var target;
If you use paths directly in your script, it is very important not to forget to remove the last /. For example, /foo/bar is ok, /foo/bar/ is not.
Let's ask the user to give input and ouput dir. To do so, we will ask for files and only keep the directory part of it.
orgDir=fileReadSelect();
destDir=fileWriteSelect();
orgDir=pathOnly(orgDir);
destDir=pathOnly(destDir);
orgDir=orgDir.replace(reg,"");
destDir=destDir.replace(reg,"");
Note that we use the ''reg'' regexp to remove the trailing / or \.
===== Main loop =====
Now that the directories are set, we can parse them. Let's get the interesting files:
if(ds.Init(orgDir))
{
// Only process files we want i.e. AVI
if(!ds.isNotFile && !ds.isDirectory && !ds.isHidden && !ds.isArchive && !ds.isSingleDot && !ds.isDoubleDot)
{
extension=ds.GetExtension();
if(extension == "avi")
{
target=ds.GetFileName();
target=destDir+sep+target;
processFile(orgDir+sep+ds.GetFileName(),target);
}
}
So we keep only the files that are not directory and have an ''avi'' extension. Of course you can replace the extension to your needs.
Next we use the reg2 regexp to remove the path.
If the incoming file is /dump/you_are_under/foo.avi, and target directory is /tmp, the following will occur:
target=foo.avi
target=/tmp +/+foo.avi=/tmp/foo.avi
Next we prepend the target directory and call process file with both source and target file.
Taking the same example
source=/dump/you_are_under +/+foo.avi=/dump/you_are_under/foo.avi
target=/tmp+/+foo.avi=/tmp/foo.avi
===== Processing function =====
Our main loop is over. The fun continues in the processFile function that will do the real job. It will process one file and is called for each file by our main loop.
function processFile(filename, targetfile)
{
// Load the file
app.forceUnpack();
app.load(filename);
app.rebuildIndex();
app.audio.delay=0;
app.audio.mixer("NONE");
app.audio.scanVBR();
app.setContainer("AVI_UNP");
app.save(targetfile);
return 1;
}
We just call forceunpack to remove the packed bitstream, and call scanVBR in case it is MP3 VBR. Then set output format to AVI_UNP and save.
Of course it is a simple example. If you have processed a file and want to do the same processing to a bunch of file here is how to do:
- Edit the file to your liking
- Save the project as /tmp/prj.js for example
- Copy paste the /tmp/prj.js file into processFile
- Modify to use filename and targetfile as source and destination file
You can perfectly apply audio and video filters, change codec etc...
===== Complete script =====
The whole script looks like this:
//AD <-
/*
Simple script that scans the orgDir directory
and unpack all AVI files
The resulting file is put in destDir directory
Using new directorySearch API
*/
var app = new Avidemux();
var ds = new DirectorySearch();
var orgDir;
var destDir;
var reg =new RegExp(".$");
/*
This is for Unix
For Windows change to
sep="\\";
reg2=new RegExp("\\.*\\");
*/
var sep="/";
var reg2 =new RegExp("\/.*\/");
var extension;
var target;
//
//
//
// select files from original & target directories
//
orgDir=fileReadSelect();
destDir=fileWriteSelect();
orgDir=pathOnly(orgDir);
destDir=pathOnly(destDir);
//
// strip last \\ or //
//
orgDir=orgDir.replace(reg,"");
destDir=destDir.replace(reg,"");
print("orgDir : <"+orgDir+">");
print("destDir : <"+destDir+">");
//
// Go
//
if(ds.Init(orgDir))
{
while(ds.NextFile())
{
// Only process file we want i.e. AVI
if(!ds.isNotFile && !ds.isDirectory && !ds.isHidden && !ds.isArchive && !ds.isSingleDot && !ds.isDoubleDot)
{
extension=ds.GetExtension();
if(extension == "avi")
{
target=ds.GetFileName();
target=destDir+sep+target;
print("***"+ds.GetFileName()+"-->"+target);
processFile(orgDir+sep+ds.GetFileName(),target);
}
//print("File: "+ds.GetFileName()+" is "+ds.GetFileSize()+" bytes, extension "+extension);
}
}
print("We just searched in directory \"" + ds.GetFileDirectory() + "\"");
ds.Close();
}
else
displayError("Error initializing the directory search");
displayInfo("Finished !");
function processFile(filename, targetfile)
{
// Load the file
app.forceUnpack();
app.load(filename);
app.rebuildIndex();
app.audio.delay=0;
app.audio.mixer("NONE");
app.audio.scanVBR();
app.setContainer("AVI_UNP");
app.save(targetfile);
return 1;
}
===== See also =====
* [[using:Scripting]]