Render predefined file sizes

taliesin wrote on 2/14/2003, 6:21 PM
For a network 'render-farm' a friend of mine is looking for a way to output predefined file sizes out of a Vegas project.
Say - the project's video length is 60 minutes. But what he needs after rendering are AVI 1.0 files not larger than 0.9 GB. It wouldn't matter how much AVI files this method would generate if only each single file is of a maximum lenght of 0.9 GB and if splitting the files is fully automated.
Manually marking regions in the timeline before rendering is NOT an option.

I think a script would be the ideal solution for this job. Does a script like this one already exist or any chances one like this would be done in future?

Any input welcome :-)

Marco

Comments

pjproductions wrote on 2/16/2003, 12:32 PM
In order for that to happen I would assume you would have to do a two pass or use a bitrate calculator like those used for DivX and for DVD.

SonyPJM wrote on 2/17/2003, 9:52 AM

Are these DV encoded avi files? If so, I think this is possible with
scripting since DV has a constant bit rate. You can do some tests to
see how many frames adds up to 0.9 gig (I'm getting about 3700K per
second with NTSC DV).
jetdv wrote on 2/17/2003, 3:46 PM
I would assume that you could render 4 minute segments and be within the 1 Gig limit. I would think that something like the following would work (NOTE: this code DOES NOT WORK - I am getting an error message - maybe someone else can figure out the cause of the error and post a working version here)

/**
* Sample render segments *
* Revision Date:
**/

import System;
// import System.Collections;
// import System.Text;
import System.IO;
// import System.Drawing;
// import System.Windows.Forms;
// import System.Object;
// import SonicFoundry.Vegas;

// here are some default variables for the GUI.
var defaultBasePath = "Z:\\renders\\BatchRender_";

// set this to true if you want to allow files to be overwritten
var overwriteExistingFiles = false;

try {
var renderStart, renderLength, totalLength, SubClipNum;

SubClipNum = 1;
renderStart = 0;
totalLength = Vegas.Project.Length;
renderLength = 4000 * 60; // 4 minutes???

// The following line appears to be giving me the error
While (renderStart < totalLength) {
if ((renderLength + renderStart) > totalLength) {
renderLength = totalLength - renderStart;
}

// The following line is for testing purposes
// and should be removed from the final version.
MessageBox.Show("Render From: " + renderStart + " For Length: " + renderLength);

renderStart = renderStart + renderLength;
SubClipNum = SubClipNum + 1;

// This line would need to be uncommented and tested
// DoRender("test" + SubClipNum + ".AVI", "Video for Windows", "NTSC DV", renderStart, renderLength);

}

} catch (e) {
if (!e.skipMessageBox)
MessageBox.Show(e);
}



// perform the render. The Render method returns a member of the
// RenderStatus enumeration. If it is anything other than OK, exit
// the loops. This will throw an error message string if the render
// does not complete successfully.
function DoRender(fileName, rndr, rndrTemplate, start, length) {
// make sure the file does not already exist
if (!overwriteExistingFiles && File.Exists(fileName)) {
throw "File already exists: " + fileName;
}

// perform the render. The Render method returns
// a member of the RenderStatus enumeration. If
// it is anything other than OK, exit the loops.
var status = Vegas.Render(fileName, rndrTemplate, start, length);

// if the render completed successfully, just return
if (status == RenderStatus.Complete)
return;

// if the user canceled, throw out a special message that won't be
// displayed.
if (status == RenderStatus.Canceled) {
var cancelMsg = new String("User canceled");
cancelMsg.skipMessageBox = true;
throw cancelMsg;
}

// if the render failed, throw out a detailed error message.
var msg : StringBuilder = new StringBuilder("Render failed:\n");
msg.Append("\n file name: ");
msg.Append(fileName);
msg.Append("\n Renderer: ");
msg.Append(rndr.FileTypeName);
msg.Append("\n Template: ");
msg.Append(rndrTemplate.Name);
msg.Append("\n Start Time: ");
msg.Append(start.ToString());
msg.Append("\n Length: ");
msg.Append(length.ToString());
throw msg;
}
taliesin wrote on 2/17/2003, 4:56 PM
PJ and Paul,
I am not quite sure if what I described was that clear.
What we are looking for is not a method to define a data rate for the output, but to automatically divide a video into lots of small segments, each of it not larger than 0.9 GB what actually is somewhat below 5 minutes per segment.
Anyway, thanks a lot for your responses - any info about it is very welcome!

Edward,
thanks for the effort of building that script. I think, this directs exactly to what we like a script to do. Would be great if somebody can proof and work on it.

Wow, this new forum starts being so much valuable!!!!!

Marco
SonyPJM wrote on 2/17/2003, 5:09 PM
Off hand I see a few problems that boil down to the type of arguments that Vegas.Render takes:

The first argument should be a full path... not just a file name.

The second argument is a RenderTemplate object, not a string... you can get a RenderTemplate object by searching in the Vegas.Renderers and Renderer.Templates collections... Below are some helper functions that use regular expressions to find a renderer and template.

The third and fourth arguments need to be Timecode objects rather than millisecond values... easy to fix though since you can create new Timecodes from millisecond values. So just do:

new Timecode(start)

and

new Timecode(length)


Here are those helper functions:

function FindRenderer(rendererRegExp : RegExp) : Renderer {
var rendererEnum : Enumerator = new Enumerator(Vegas.Renderers);
while (!rendererEnum.atEnd()) {
var renderer : Renderer = Renderer(rendererEnum.item());
if (null != renderer.FileTypeName.match(rendererRegExp)) {
return renderer;
}
rendererEnum.moveNext();
}
return null;
}

function FindRenderTemplate(renderer : Renderer, templateRegExp : RegExp) : RenderTemplate {
var templateEnum : Enumerator = new Enumerator(renderer.Templates);
while (!templateEnum.atEnd()) {
var renderTemplate : RenderTemplate = RenderTemplate(templateEnum.item());
if (null != renderTemplate.Name.match(templateRegExp)) {
return renderTemplate;
}
templateEnum.moveNext();
}
return null;
}


jetdv wrote on 2/17/2003, 7:58 PM
Yes, I knew it wasn't right. I was just trying to get the basic idea across. Thanks for the few clarifications but I don't understand the "renderer" functions. Could you explain a little more what they do?
SonyPJM wrote on 2/18/2003, 9:07 AM
A Renderer is just a file format plug-in. It represents a code module that is responsible for encoding a particular type of media file, like AVI, Quicktime, MPEG, Windows Media, RealMedia, Wave, AIFF, etc.

Each Renderer has a set of RenderTemplates which define preset output configurations. Templates usually determine the detailed type of encoding such as bit rate, stream count, channel count, etc.

When you call the Vegas.Render method, you must supply a RenderTemplate so it knows exacly how to encode the output file.
jetdv wrote on 2/18/2003, 10:23 AM
So, in this case, that is the hard-coded "Video for Windows"?

What I really don't understand is why it is wanting a ";" in the WHILE line.
SonyPJM wrote on 2/18/2003, 10:54 AM
I guess it is because JScript is case sensitive so you need 'while' rather than "While".
jetdv wrote on 2/18/2003, 11:25 AM
Thanks SonicPJM, that was it - I'm too used to Visual Basic.

Here is a new version that displays what appears to be the proper times in the message box. I turned off the message box and turned on the render command. PLEASE NOTE: this is untested but ready to be tried (the test system where I currently am doesn't have enough hard drive space to test this script). Someone give it a try and let me know if it works (or even if it doesn't work).

Render Segments Script
SonyPJM wrote on 2/18/2003, 11:47 AM

You still need to use the FindRenderer and FindRenderTemplate
functions from my earlier post rather than passing in strings.

I fixed a couple other problems too:

/**
* Sample render segments TEST #1*
* Revision Date: 2-18-2003
* By: Edward Troxel
* with various segments taken from other scripts!
**/

import System;
// import System.Collections;
import System.Text;
import System.IO;
// import System.Drawing;
import System.Windows.Forms;
import System.Object;
import SonicFoundry.Vegas;

// here are some default variables for the GUI.
var defaultBasePath = "D:\\renders\\";

// set this to true if you want to allow files to be overwritten
var overwriteExistingFiles = false;

try {
var SubClipNum = 1;
var renderStart = new Timecode();
var totalLength = Vegas.Project.Length;
var renderLength = new Timecode(4000 * 60); // 4 minutes???

while (renderStart < totalLength) {
if ((renderLength + renderStart) > totalLength) {
renderLength = totalLength - renderStart;
}

// MessageBox.Show("Render From: " + renderStart + " For Length: " + renderLength);
var renderer = FindRenderer(/Video for Windows/);
if (null == renderer)
throw "failed to find renderer";
var template = FindRenderTemplate(renderer, /NTSC DV/);
if (null == template)
throw "failed to find template";

DoRender(defaultBasePath + "test" + SubClipNum + ".AVI", renderer, template, renderStart, renderLength);

renderStart = renderStart + renderLength;
renderStart++; // advance one frame
SubClipNum = SubClipNum + 1;


}

} catch (e) {
if (!e.skipMessageBox)
MessageBox.Show(e);
}



// perform the render. The Render method returns a member of the
// RenderStatus enumeration. If it is anything other than OK, exit
// the loops. This will throw an error message string if the render
// does not complete successfully.
function DoRender(fileName, rndr, rndrTemplate, start, length) {
// make sure the file does not already exist
if (!overwriteExistingFiles && File.Exists(fileName)) {
throw "File already exists: " + fileName;
}

// perform the render. The Render method returns
// a member of the RenderStatus enumeration. If
// it is anything other than OK, exit the loops.
var status = Vegas.Render(fileName, rndrTemplate, start, length);

// if the render completed successfully, just return
if (status == RenderStatus.Complete)
return;

// if the user canceled, throw out a special message that won't be
// displayed.
if (status == RenderStatus.Canceled) {
var cancelMsg = new String("User canceled");
cancelMsg.skipMessageBox = true;
throw cancelMsg;
}

// if the render failed, throw out a detailed error message.
var msg : StringBuilder = new StringBuilder("Render failed:\n");
msg.Append("\n file name: ");
msg.Append(fileName);
msg.Append("\n Renderer: ");
msg.Append(rndr.FileTypeName);
msg.Append("\n Template: ");
msg.Append(rndrTemplate.Name);
msg.Append("\n Start Time: ");
msg.Append(start.ToString());
msg.Append("\n Length: ");
msg.Append(length.ToString());
throw msg;
}



function FindRenderer(rendererRegExp : RegExp) : Renderer {
var rendererEnum : Enumerator = new Enumerator(Vegas.Renderers);
while (!rendererEnum.atEnd()) {
var renderer : Renderer = Renderer(rendererEnum.item());
if (null != renderer.FileTypeName.match(rendererRegExp)) {
return renderer;
}
rendererEnum.moveNext();
}
return null;
}

function FindRenderTemplate(renderer : Renderer, templateRegExp : RegExp) : RenderTemplate {
var templateEnum : Enumerator = new Enumerator(renderer.Templates);
while (!templateEnum.atEnd()) {
var renderTemplate : RenderTemplate = RenderTemplate(templateEnum.item());
if (null != renderTemplate.Name.match(templateRegExp)) {
return renderTemplate;
}
templateEnum.moveNext();
}
return null;
}
jetdv wrote on 2/18/2003, 12:04 PM
Thanks SonicPJM, the revised version has now been posted at the same location:

Revised Render Segments Script

At least I was in the right ball-park even if I did miss a couple of items. Now, I guess the big question: Does it really work? (I still can't test it until later).
taliesin wrote on 2/18/2003, 6:01 PM
Hey Paul and Edward,

your script works like a charm!!! I configurd the render destination and set it to PAL DV instead of NTSC and it really, really works! Great!!!

One question left (or two):
The output files - Are they AVI 1.0 or AVI 2.0?
If it is AVI 2.0 - is there a way I can modify the script to render to AVI 1.0?

Thank you both a lot!

Marco
jetdv wrote on 2/18/2003, 7:42 PM
I believe they are AVI 2 files. You would need to set up the settings you need, save that format, and then pick it instead of NTSC or PAL DV. At least the pieces are under 1 Gig.
taliesin wrote on 2/18/2003, 8:05 PM
>> You would need to set up the settings you need,
>> save that format, and then pick it instead of NTSC or PAL DV.

You mean, this definition "NTSC DV" or what I used instead "PAL DV" - this is a template name taken from the regular render dialog?

If so - well, this would help.

Marco
taliesin wrote on 2/18/2003, 8:25 PM
I tested it by creating a audio-only template and refering the script to that template name.

Yesssss - that's it! It's the render template what the script takes.
So now we got what we were looking for.

Again - thank you very much. Your help is very appreciated!

Marco
jetdv wrote on 2/18/2003, 8:32 PM
You're welcome Marco. I'm glad it works for your needs.

Edward
p@mast3rs wrote on 3/1/2003, 4:48 PM
any chance we can get this for win media 9 two pass encodes?
taliesin wrote on 3/1/2003, 5:44 PM
You can use that script for any render template Vegas 4 allows to create. So as Vegas 4 also gives you WMV9 2-pass you can do that that with this script too.

Marco