"Project markers" to DVDA, after the render...

A. Grandt wrote on 11/28/2010, 8:52 AM
Hi

I just did a lengthy render for a DVD, and discovered that the Project markers weren't included, I never realized that the Batch Render script didn't include them.

Mine does now. Though that is obviously too late.

Is there any way to export the markers for use in DVDA without having to re-render the entire project?

Comments

altarvic wrote on 11/28/2010, 9:11 AM
Scripts can help you. The Markers tool from Vegasaur can export markers to a variety of different formats, including DVDA chapters. It is free for 30 days.
A. Grandt wrote on 11/28/2010, 9:18 AM
Thanks. I'll try that :)

Btw, if anyone want to use my modified "Batch Render" script, you can find it here:
Batch Render4.cs

There are a few other improvements (IMHO), including the use of CD Tracks as regions. I've found them to be a nice feature when breaking up a video into "YouTube sized" bites, as I can easily keep track of how long the individual pieces are with the "CD Track Time" timecode format.

It should work in Vegas Pro 9 and 10, I have no idea about Vegas Pro 8
john_dennis wrote on 11/28/2010, 9:28 AM
Sorry I don't have an answer on exporting markers from Vegas, but you could transfer the markers from the Vegas project in less time than rendering if your in a time crunch.

The Cursor Position display at the bottom right of the Vegas timeline is "hot". If you doulble click on it, you can copy the marker positions from Vegas to DVD Architect.

Right Click on the Cursor Position box on the Vegas timeline and ensure that the time display is the same format as DVD Architect.

Move the cursor on the Vegas timeline to the first marker by clicking on its tab.

Double (left) click on the Vegas Cursor Position box.

Control C to copy it contents.

Alt Tab to the DVD Architect Project.

Select the appropriate title.

Double (left) click the cursor position display just above and on the left end of the timeline.

Control V to paste. The cursor moves to the position on the timeline.

"M" to set marker.

Repeat.

Usually, a couple dozen markers can be moved quicker than rendering the project again.

I have a fairly high tolerance for tedium.
Chienworks wrote on 11/28/2010, 11:09 AM
John, i've used that method more times than i care to think about. It is pretty fast though.
farss wrote on 11/28/2010, 1:47 PM
I have a copy of the Export Markers script on my server.
I'd post it here but it is rather long, sorry cannot find a link to it.
It was written back in 2003 and I haven't used it in ages so I'm uncertain if it will still work. If anyone wants a copy drop me a PM.

Bob.
earthrisers wrote on 11/28/2010, 2:11 PM
I've used Vegas for over 10 years and never knew about that markers-exporting trick.
Thanks be unto you!!
R0cky wrote on 11/30/2010, 5:53 AM
You can also insert an all black track at the top of your project - this will render as fast as possible. Bring it into dvda as a second track and load the markers from it.
Marc S wrote on 11/30/2010, 3:45 PM
Yes, I did this recently. You need to install the free script (that I can't seem to find) that allows you to export markers for DVD Architect.

1. Name the file correctly. If your rendered file is MyMovie.mpg the marker file should be MyMovie.mpg.sfl

2. Save the marker file into the same folder as the mpg file. This is important. It you add it later it won't work.

3. Manually reload the markers in DVD Architect
farss wrote on 11/30/2010, 5:34 PM
' You need to install the free script (that I can't seem to find) that allows you to export markers for DVD Architect"

Does anyone know what happened to it?

As I said before I and obvioualy others have a copy of it. I searched the scripting forum to no avail, I've Googled it to no avail. It would be really great if everyone could get it because when you need it, it is a real time saver.
There's no authors name in the file so I guess it is free to share.

Bob.
johnmeyer wrote on 11/30/2010, 6:13 PM
I re-did the script because many of the setup variables need to be changed under certain circumstances. However, here is the original script (which I did not write).

John Meyer
/**

Objective:
==========

Script to generate *.sfl file from Vegas timeline markers, which can then be imported into
DVDA as chapter points. (File format same as that saved by Vegas.)

Note:
=====
1) The sfl file **MUST** use the MPEG file as basename, eg. "myfile.mpg.sfl".
2) If string length (including null byte) is not word aligned, ie. odd bytes, then pad
with another null byte to make it even bytes.
3) Chapter point need to fall on an I-frame, so actual frame used will depend on
how DVDA search for I-frame. If there is ever an option, choose search backwards.

History:
========
8/12/2003 WL v1.0. Creation. Supports DVDA v1.0d.
9/12/2003 WL v1.1.
- Vegas don't write blank label. Script generated blank labels, but
was accepted by DVDA. Modified script not to write blank labels.
- Do not write LIST section if there are no labels.
- Do not create SFL file if there are no markers.
- Support for NTSC.
28/12/2003 WL v1.2.
- Modified to auto detect PAL or NTSC from project setting to set frame rate.
Only supports 25f/s and 29.97f/s.
1/1/2004 WL v1.3
- Modified to match ruler format with video format. Required for *.stl
and *.chp.
2/1/2004 WL v1.4
- Problem with some DVDA NTSC chapter points being 1 frame off near end of
tape, so used double for markerTC and round up to nearest integer, but
still no good. Work-around is to add 1 frame for each NTSC chapter points.
- Check for maxMarker.
- DVDA requires chapter length be >= 1 sec. Check when creating markers
in another script.
24/7/2004 WL v1.5
- Modified to be more modular. Similar to wl_mksfl_dvda (sfl by dvda).
- Found problem with Vegas v4 and v5. *Sometimes* the chapters are displayed
at the right place as viewed on the time line, but is actually referring to
the previous frame as shown by the timecode, and the same timecode is used
to create the SFL and CHP files. So the picture from the previous chapter
is used for the chapter point. Found problem when doing PAL DV. The
workaround is to also increase chapter points by 1 frame for PAL also.
8/8/2004 WL v1.6
- Due to Vegas frame problem discovered in v1.5, need to add another frame for
NTSC, ie. frameOffset=2 for NTSC.

**/

//----------------------------------------------------------------------------------------
import System;
import System.Text;
import System.IO;
import System.Drawing;
import System.Windows.Forms;
import Sony.Vegas;

//----------------------------------------------------------------------------------------
//
// Constants
//
var NULLCH : byte = 0;
var maxMarker : int = 300;
var PALFrameTime : double = 1764; // 25 frames/sec
var NTSCFrameTime : double = 1471.47; // 30000.0/1001.0 = 29.97....

//----------------------------------------------------------------------------------------
//
// Global variables
//
var frameTime : double = PALFrameTime;
var formatMsg = "unknown";

//
// DVDA seemed to have problem with NTSC chapters points off by 1 frame near the end of tape.
// So adding 1 frame offset for NTSC chapter points. 0 for PAL.
//
var frameOffset : int = 0;

//
// Files
//
var desDir = "F:\\home\\dv\\apps\\sfoundry\\vegas\\sfl";
var srcMpgFname = "*.mpg";
var desExt = ".sfl";
var desFullFname = desDir + Path.DirectorySeparatorChar + srcMpgFname + desExt;

//----------------------------------------------------------------------------------------
function initVar() {
var frameRate = Vegas.Project.Video.FrameRate;

if ( frameRate == 25 ) {
frameTime = PALFrameTime;
frameOffset = 1;
formatMsg = "PAL, 25fps";
Vegas.Project.Ruler.Format = RulerFormat.SmpteEBU;
// MessageBox.Show(formatMsg);
}
else {
frameTime = NTSCFrameTime;
frameOffset = 2;
formatMsg = "NTSC, 29.97fps, TC=non-drop-frame";
Vegas.Project.Ruler.Format = RulerFormat.SmpteNonDrop;
// MessageBox.Show(formatMsg);
}
return null;
}

//----------------------------------------------------------------------------------------
// Button subclass that shows a save file dialog when clicked

class BrowseButton extends Button {
var myResultBox = null;

function BrowseButton(resultBox) {
myResultBox = resultBox;
}

protected override function OnClick(e : EventArgs) {
var saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "DVDA Chapter File (*.sfl)|*.sfl|All Files (*.*)|*.*";
saveFileDialog.DefaultExt = desExt;
saveFileDialog.CheckPathExists = true;
saveFileDialog.CheckFileExists = false;
//
// saveFileDialog.AddExtension is confused because file already has .mpg extension, so
// disabling this option.
//
saveFileDialog.AddExtension = false;
if (null != myResultBox) {
var filename = myResultBox.Text;
var initialDir = Path.GetDirectoryName(filename);
if (Directory.Exists(initialDir)) {
saveFileDialog.InitialDirectory = initialDir;
}
saveFileDialog.FileName = Path.GetFileName(filename);
}

if ( System.Windows.Forms.DialogResult.OK == saveFileDialog.ShowDialog() ) {
if ( null != myResultBox ) {
if ( Path.GetExtension(saveFileDialog.FileName) != desExt )
saveFileDialog.FileName += desExt;
myResultBox.Text = Path.GetFullPath(saveFileDialog.FileName);
}
}
}
}

//----------------------------------------------------------------------------------------
// Form subclass that is the dialog box for this script

class getFnameDialog extends Form {
var browseButton;
var fileNameBox;
var noticeBox;

function getFnameDialog(baseFileName) {

this.Text = "Create DVDA chapter file using timeline markers";
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.StartPosition = FormStartPosition.CenterScreen;
this.Width = 580;

var buttonWidth = 80;

fileNameBox = addTextControl("DVDA chapter file", 6, 480, 10, baseFileName);
noticeBox = addTextLabel("Caution: must use mpeg file as basename, eg. myfile.mpg.sfl\n", 6, fileNameBox.Bottom+5);

browseButton = new BrowseButton(fileNameBox);
browseButton.Left = fileNameBox.Right + 4;
browseButton.Top = fileNameBox.Top - 2;
browseButton.Width = buttonWidth;
browseButton.Height = browseButton.Font.Height + 12;
browseButton.Text = "Browse...";
Controls.Add(browseButton);

var buttonTop = noticeBox.Bottom + 16;

var okButton = new Button();
okButton.Text = "OK";
okButton.Left = this.Width - (2*(buttonWidth+10));
okButton.Top = buttonTop;
okButton.Width = buttonWidth;
okButton.Height = okButton.Font.Height + 12;
okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
AcceptButton = okButton;
Controls.Add(okButton);

var cancelButton = new Button();
cancelButton.Text = "Cancel";
cancelButton.Left = this.Width - (1*(buttonWidth+10));
cancelButton.Top = buttonTop;
cancelButton.Height = cancelButton.Font.Height + 12;
cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
CancelButton = cancelButton;
Controls.Add(cancelButton);

var titleHeight = this.Height - this.ClientSize.Height;
this.Height = titleHeight + okButton.Bottom + 8;
}

function addTextLabel(labelName, left, top) {
var label = new Label();

label.AutoSize = true;
label.Text = labelName;
label.Left = left;
label.Top = top + 4;
Controls.Add(label);
return label;
}

function addTextControl(labelName, left, width, top, defaultValue) {
var label = new Label();
label.AutoSize = true;
label.Text = labelName + ":";
label.Left = left;
label.Top = top + 4;
Controls.Add(label);

var textbox = new TextBox();
textbox.Multiline = false;
textbox.Left = label.Right;
textbox.Top = top;
textbox.Width = width - (label.Width);
textbox.Text = defaultValue;
Controls.Add(textbox);

return textbox;
}
}

//----------------------------------------------------------------------------------------
function openSFL(desDir, srcMpgFname) : FileStream {

if ( !Directory.Exists(desDir) ) {
// Directory.CreateDirectory(desDir);
throw "Directory does not exist:\n\n" + desDir;
}
var fs = File.Create(desFullFname);
return fs;
}

//----------------------------------------------------------------------------------------
function closeSFL(fs, binw) {

binw.Close();
fs.Close();
return null;
}

//----------------------------------------------------------------------------------------
function writeRIFF(binw, sectsize) {

binw.Write( "RIFF".ToCharArray() );
binw.Write( sectsize );
return null;
}

//----------------------------------------------------------------------------------------
function writeSFPL(binw) {

binw.Write( "SFPL".ToCharArray() );
}

//----------------------------------------------------------------------------------------
function writeCUE(binw, markerTC : double[], markerCnt) {

var zero : double = 0;
var tc : int;
var counter : int = 0;
var sectsize : int = (markerCnt * 24) + 4;

binw.Write( "cue ".ToCharArray() );
binw.Write( sectsize );
binw.Write( markerCnt );

for (var i : int = 0; i < markerCnt; i++) {
counter++;
tc = System.Convert.ToInt32(System.Math.Round(markerTC[i]));
binw.Write( counter );
binw.Write( tc );
binw.Write( "data".ToCharArray() );
binw.Write( zero );
binw.Write( tc );
}
return sectsize;
}

//----------------------------------------------------------------------------------------
// Do not write blank labels.
// If all labels are blank, do not write this section.

function writeLIST(binw, markerLabel, markerCnt) {

var counter : int = 0;
var sectsize : int = 0;
var elemsize : int;

binw.Write( "LIST".ToCharArray() );
binw.Write( sectsize );

binw.Write( "adtl".ToCharArray() );
sectsize += 4;

for (var i : int = 0; i < markerCnt; i++) {
counter++;
if ( markerLabel[i].Length > 0 ) {
elemsize = markerLabel[i].Length + 4 + 1;
binw.Write( "labl".ToCharArray() );
binw.Write( elemsize );
binw.Write( counter );
binw.Write( markerLabel[i].ToCharArray() );
binw.Write( NULLCH );
sectsize = sectsize + 8 + elemsize;
if ( (elemsize % 2) > 0 ) {
binw.Write( NULLCH );
sectsize++;
}
}
}
return sectsize;
}

//----------------------------------------------------------------------------------------
function writeSFPI(binw, srcMpgFname) {

var sectsize : int = srcMpgFname.Length + 1;

binw.Write( "SFPI".ToCharArray() );
binw.Write( sectsize );
binw.Write( srcMpgFname.ToCharArray() );
binw.Write( NULLCH );
if ( (sectsize % 2) > 0 ) {
binw.Write( NULLCH );
sectsize++;
}
return sectsize
}

//----------------------------------------------------------------------------------------
function rewriteSize(binw, CUEsize, LISTsize, SFPIsize) {

var RIFFsize : int = (12 + CUEsize) + (8 + SFPIsize);

if ( LISTsize > 0 )
RIFFsize = RIFFsize + (8 + LISTsize);
binw.Seek(0, SeekOrigin.Begin);
binw.Seek(4,SeekOrigin.Current);
binw.Write( RIFFsize );

if ( LISTsize > 0 ) {
binw.Seek((12 + CUEsize) + 4, SeekOrigin.Current);
binw.Write( LISTsize );
}
return null;
}

//----------------------------------------------------------------------------------------
function makeSFL(mrkEnum) {

var markerCnt : int = 0;
var totMarker : int = 0;
// var markerTC = new Array();
var markerTC : double[] = new double[maxMarker];

var markerLabel = new Array();
var sumLabelSize = 0;
var RIFFsize : int = 0;
var CUEsize : int = 0, LISTsize : int = 0, SFPIsize : int = 0;
var nowMarker;

while ( !mrkEnum.atEnd() ) {
totMarker++;
if ( markerCnt < maxMarker ) {
nowMarker = mrkEnum.item();
var nowMarkPos = Marker(nowMarker).Position;
if ( nowMarkPos.FrameCount == 0 ) {
//
// DVDA auto creates chapter at 00:00:00:00, and creates only one if overlapped.
//
markerTC[markerCnt] = nowMarkPos.FrameCount * frameTime;
}
else {
markerTC[markerCnt] = (nowMarkPos.FrameCount + frameOffset) * frameTime;
}
markerLabel[markerCnt] = Marker(nowMarker).Label;
sumLabelSize += markerLabel[markerCnt].Length;
markerCnt++;
mrkEnum.moveNext();
}
}

if ( markerCnt == 0 )
throw "Error: no markers defined on Vegas timeline";

var fs = openSFL(desDir, srcMpgFname);
var binw = new BinaryWriter(fs);

writeRIFF(binw, RIFFsize);
writeSFPL(binw);
CUEsize = writeCUE(binw, markerTC, markerCnt);
if ( sumLabelSize > 0 )
LISTsize = writeLIST(binw, markerLabel, markerCnt);
SFPIsize = writeSFPI(binw, srcMpgFname);
rewriteSize(binw, CUEsize, LISTsize, SFPIsize);

closeSFL(fs, binw);
return totMarker;
}

//----------------------------------------------------------------------------------------
function findSelectedTrack() : Track {
var trackEnum = new Enumerator(Vegas.Project.Tracks);

while (!trackEnum.atEnd()) {
var track : Track = Track(trackEnum.item());
if (track.Selected) {
return track;
}
trackEnum.moveNext();
}
return null;
}

//----------------------------------------------------------------------------------------
try {

var totMarker : int = 0;
var missMarker : int = 0;

initVar();

// Show the script's dialog box.
var dialog = new getFnameDialog(srcMpgFname + desExt);
var dialogResult = dialog.ShowDialog();

// if the OK button was pressed...
if ( System.Windows.Forms.DialogResult.OK == dialogResult ) {

//
// Also need to check extension here in case user bypassed browse button.
//
desFullFname = Path.GetFullPath(dialog.fileNameBox.Text);
if ( Path.GetExtension(desFullFname) != desExt )
desFullFname += desExt;
desDir = Path.GetDirectoryName(desFullFname);
srcMpgFname = Path.GetFileNameWithoutExtension(desFullFname);

// MessageBox.Show(desDir.ToString() + "\n" + srcMpgFname.ToString() + "\n" + desFullFname.ToString());

var track = findSelectedTrack();
if ( null == track )
throw "Error: no selected track";

var mrkEnum = new Enumerator(Vegas.Project.Markers);
totMarker = makeSFL(mrkEnum);
if ( totMarker > maxMarker ) {
missMarker = totMarker - maxMarker;
}

MessageBox.Show(
"Done." +
"\nFile: " + desFullFname +
"\n" +
"\nFormat: " + formatMsg +
"\nTotal markers: " + totMarker.ToString() +
"\nMissed markers: " + missMarker.ToString()
);
}

} catch (e) {
MessageBox.Show(e);
}

rs170a wrote on 11/30/2010, 6:22 PM
John, I'm so glad you can't stay away from this group :-)

Mike
farss wrote on 11/30/2010, 8:05 PM
This time I have it bookmarked.

Bob.