Hi all,
I have created a script to perform a batch cut-up of large video files. The motivation for this script is to be able to save large video files to several smaller disks, eg. one 14Gb DV AVI on four 4Gb DVD-R.
I thought I'd share my script with the rest of the Vegas community. Cut below the line and save as a .js file. Further explanation and documentation is available in the top comment section.
- Uffe
--- (VEGAS) Batch Cut-Up.js ---
I have created a script to perform a batch cut-up of large video files. The motivation for this script is to be able to save large video files to several smaller disks, eg. one 14Gb DV AVI on four 4Gb DVD-R.
I thought I'd share my script with the rest of the Vegas community. Cut below the line and save as a .js file. Further explanation and documentation is available in the top comment section.
- Uffe
--- (VEGAS) Batch Cut-Up.js ---
/*
* Batch Cut-Up script v1.0 for Vegas
* ==================================
* by Uffe Friis Lichtenberg (uffefl at diku dot dk)
*
* This is a JScript.NET script for Sonic Foundry Vegas 4.0a to
* perform a batch cut-up of large video files.
*
* The motivation for this script is to be able to save large
* video files to several smaller disks, eg. one 14Gb DV AVI on
* four 4Gb DVD-R.
*
* The default settings generate PAL DV AVI files of 1.38Gb size,
* allowing for 3 files to be stored on a 4.29Gb DVD-R media and
* still leaving some room for auxilliary files (like .sfk and
* project files etc.). These settings are easily customizable.
*
* Usage
* -----
*
* Run this script in Vegas, by selecting
*
* Tools | Scripting | Run Script...
*
* and pointing to this file. Alternatively you can assign this
* script to one of the 10 slots in the "Tools | Scripting" menu
* and launch it from that menu entry.
*
* You will then be prompted to select the files you wish to
* cut up. You can select more than one file. Once you press
* "Open" the process will begin.
*
* The resulting files are named "filename.partXX.ext", where
* "filename.ext" is the base filename of the input file you
* selected and "XX" is the sequence number (from "01" and
* upwards). Eg. if you select "dog.avi" and "pony.avi" you might
* end up with the files "dog.part01.avi", "dog.part02.avi",
* "pony.part01.avi", "pony.part02.avi" and "pony.part03.avi".
* The actual number of parts will of course depend on the size
* of the input files.
*
* Customization
* -------------
*
* If the default settings are inappropriate for your project,
* they can be easily modified in the "user definable parameters"
* section below.
*
* Default setting is 6.5 mins of video per chunk. Default
* renderer and template is "Video for Windows", "PAL DV". This
* could easily be modified to support different codecs (match
* the FindTemplate parameters to the codec used) and different
* bitrates and media (figure out how many seconds are storable
* on the desired media and divide by 2-4, depending on the
* flexibility required).
*
* Errors
* ------
*
* If errors occur during rendering of one chunk, the script will
* try to continue with the next chunk. All errors are summarized
* upon completion. Cancelling a render will only flag an error for
* the chunk being rendered; there is no way to cancel the entire
* operation once it has begun. (Other than canceling every single
* chunk manually.)
*/
import System;
import System.Text;
import System.IO;
import System.Windows.Forms;
import SonicFoundry.Vegas;
try
{
//////////////////////////////////////
// BEGIN user definable parameters
//
var cutuplength = 6.5*60; // units are seconds
var cutuptemplate = FindTemplate(/^Video for Windows$/,/^PAL DV$/);
//
// END user definable parameters
//////////////////////////////////////
// Select files
var opendialog = new OpenFileDialog();
opendialog.AddExtension = false;
opendialog.CheckFileExists = true;
opendialog.CheckPathExists = true;
opendialog.DefaultExt = "avi";
opendialog.DereferenceLinks = true;
opendialog.FileName = "";
opendialog.Filter = "AVI files (*.avi)|*.avi|All files (*.*)|*.*";
opendialog.FilterIndex = 0;
opendialog.Multiselect = true;
opendialog.ReadOnlyChecked = true;
opendialog.ShowHelp = false;
opendialog.Title = "Select files to cut up...";
opendialog.ValidateNames = true;
var res = opendialog.ShowDialog();
// Process selection
switch (res)
{
case DialogResult.OK:
var files = opendialog.FileNames;
var errors = new Array();
for (var i=0; i<files.Length; i++)
try
{
CutUp(files[i],new Timecode(cutuplength*1000)); // 6.5 min chunks
}
catch (x)
{
errors.push(files[i]+": "+x.ToString());
}
if (errors.length!=0)
{
var s = "Batch Cut-Up completed, but with errors:\n\n";
for (var i=0; i<errors.length; i++)
s += "- "+errors[i]+"\n\n";
MessageBox.Show(s+"The affected output files are probably invalid.","Completed with errors",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
else
MessageBox.Show("Batch Cut-Up completed succesfully.","Completed",MessageBoxButtons.OK,MessageBoxIcon.Information);
break;
case DialogResult.Cancel:
//MessageBox.Show("Batch Cut-Up cancelled.\n\nNo processing has been done.","Cancelled",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
break;
default:
MessageBox.Show("internal error: OpenFileDialog.ShowDialog() returned "+res.ToString()+"\n\nNo processing has been done.","Internal error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
catch (x)
{
MessageBox.Show("Error in user definable parameters:\n\n"+x.ToString()+"\n\nNo processing has been done.","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
function FindTemplate(reRenderer,reTemplate)
{
// Find renderer
var renderers = new Enumerator(Vegas.Renderers);
var renderer = null;
while (!renderers.atEnd())
{
if (renderers.item().FileTypeName.match(reRenderer)!=null)
{
renderer = renderers.item();
break;
}
renderers.moveNext();
}
if (renderer==null)
throw "Couldn't find a matching renderer";
// Find template
var templates = new Enumerator(renderer.Templates);
var template = null;
while (!templates.atEnd())
{
if (templates.item().Name.match(reTemplate)!=null)
{
template = templates.item();
break;
}
templates.moveNext();
}
if (template==null)
throw "Couldn't find a matching template";
return template;
}
function CutUp(infile,length)
{
// Create a new empty project
if (!Vegas.NewProject(false,false))
throw "Couldn't create a new project";
// Add the infile to the media pool and find the A/V streams
var media = new Media(infile);
var videostream = null;
var audiostream = null;
for (var streams = new Enumerator(media.Streams); !streams.atEnd(); streams.moveNext())
if (videostream==null && streams.item().MediaType==MediaType.Video)
videostream = streams.item();
else
if (audiostream==null && streams.item().MediaType==MediaType.Audio)
audiostream = streams.item();
// Add a video track and add the video stream to that track
var vtrack = new VideoTrack();
Vegas.Project.Tracks.Add(vtrack);
var vevent = new VideoEvent(new Timecode(),videostream.Length,infile);
vtrack.Events.Add(vevent);
vevent.Takes.Add(new Take(videostream));
// Add an audio track and add the audio stream to that track
var atrack = new AudioTrack();
Vegas.Project.Tracks.Add(atrack);
var aevent = new AudioEvent(new Timecode(),audiostream.Length,infile);
atrack.Events.Add(aevent);
aevent.Takes.Add(new Take(audiostream));
// Update Vegas, so length is correct
Vegas.UpdateUI();
// Find render template
var rendertemplate = cutuptemplate;
// Render in length chunks
var t0 = new Timecode();
var i = 1;
while (t0+length<Vegas.Project.Length)
{
var res = Vegas.Render(Path.ChangeExtension(infile,"part"+i.ToString().PadLeft(2,'0')+".avi"),rendertemplate,t0,length);
if (res!=RenderStatus.Complete)
throw "Error during render ("+res.ToString()+")";
t0 += length;
i++;
}
var res = Vegas.Render(Path.ChangeExtension(infile,"part"+i.ToString().PadLeft(2,'0')+".avi"),rendertemplate,t0,Vegas.Project.Length-t0);
if (res!=RenderStatus.Complete)
throw "Error during render ("+res.ToString()+")";
}