Here is a script to export Vegas timeline markers as chapter points for import into DVDA. For PAL only. Feel free to modify it for NTSC.
/**
Objective:
==========
Script to generate *.sfl file from Vegas timeline markers, which can then be imported into
DVDA as chapter points.
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.
History:
========
8/12/2003 WL v1.0. Creation.
**/
//----------------------------------------------------------------------------------------
import System;
import System.Text;
import System.IO;
import System.Drawing;
import System.Windows.Forms;
import SonicFoundry.Vegas;
//----------------------------------------------------------------------------------------
//
// Constants
//
var NULLCH : byte = 0;
//----------------------------------------------------------------------------------------
//
// Variables
//
var desDir = "F:\\home\\dv\\apps\\sfoundry\\vegas\\sfl";
var srcMpgFname = "*.mpg";
var desExt = ".sfl";
var desFullFname = desDir + Path.DirectorySeparatorChar + srcMpgFname + desExt;
//----------------------------------------------------------------------------------------
try {
// 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);
makeSFL(mrkEnum);
MessageBox.Show("Done.\n\n" + desFullFname);
}
} catch (e) {
MessageBox.Show(e);
}
//----------------------------------------------------------------------------------------
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, markerTC, markerCnt) {
var zero : double = 0;
var tc : int;
var counter : int;
var sectsize : int = (markerCnt * 24) + 4;
binw.Write( "SFPLcue ".ToCharArray() );
binw.Write( sectsize );
binw.Write( markerCnt );
for (var i : int = 0; i < markerCnt; i++) {
counter = i + 1;
tc = markerTC[i];
binw.Write( counter );
binw.Write( tc );
binw.Write( "data".ToCharArray() );
binw.Write( zero );
binw.Write( tc );
}
return sectsize;
}
//----------------------------------------------------------------------------------------
function writeLIST(binw, markerLabel, markerCnt) {
var counter : int;
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 = i + 1;
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, SFPLsize, LISTsize, SFPIsize) {
var RIFFsize : int = (12 + SFPLsize) + (8 + LISTsize) + (8 + SFPIsize);
binw.Seek(0, SeekOrigin.Begin);
binw.Seek(4,SeekOrigin.Current);
binw.Write( RIFFsize );
binw.Seek(12 + SFPLsize + 4, SeekOrigin.Current);
binw.Write( LISTsize );
return null;
}
//----------------------------------------------------------------------------------------
// I think 1764 is for PAL only. Note sure about NTSC.
function makeSFL(mrkEnum) {
var markerCnt : int = 0;
var markerTC = new Array();
var markerLabel = new Array();
var nowMarker;
var SFPLsize : int, LISTsize : int, SFPIsize : int;
var RIFFsize : int = 0;
while ( !mrkEnum.atEnd() ) {
nowMarker = mrkEnum.item();
var nowMarkPos = Marker(nowMarker).Position;
markerTC[markerCnt] = nowMarkPos.FrameCount * 1764;
markerLabel[markerCnt] = Marker(nowMarker).Label;
markerCnt++;
mrkEnum.moveNext();
}
var fs = openSFL(desDir, srcMpgFname);
var binw = new BinaryWriter(fs);
writeRIFF(binw, RIFFsize);
SFPLsize = writeSFPL(binw, markerTC, markerCnt);
LISTsize = writeLIST(binw, markerLabel, markerCnt);
SFPIsize = writeSFPI(binw, srcMpgFname);
rewriteSize(binw, SFPLsize, LISTsize, SFPIsize);
closeSFL(fs, binw);
return null;
}
//----------------------------------------------------------------------------------------
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;
}
//----------------------------------------------------------------------------------------
// 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;
}
}
//----------------------------------------------------------------------------------------
/**
Objective:
==========
Script to generate *.sfl file from Vegas timeline markers, which can then be imported into
DVDA as chapter points.
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.
History:
========
8/12/2003 WL v1.0. Creation.
**/
//----------------------------------------------------------------------------------------
import System;
import System.Text;
import System.IO;
import System.Drawing;
import System.Windows.Forms;
import SonicFoundry.Vegas;
//----------------------------------------------------------------------------------------
//
// Constants
//
var NULLCH : byte = 0;
//----------------------------------------------------------------------------------------
//
// Variables
//
var desDir = "F:\\home\\dv\\apps\\sfoundry\\vegas\\sfl";
var srcMpgFname = "*.mpg";
var desExt = ".sfl";
var desFullFname = desDir + Path.DirectorySeparatorChar + srcMpgFname + desExt;
//----------------------------------------------------------------------------------------
try {
// 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);
makeSFL(mrkEnum);
MessageBox.Show("Done.\n\n" + desFullFname);
}
} catch (e) {
MessageBox.Show(e);
}
//----------------------------------------------------------------------------------------
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, markerTC, markerCnt) {
var zero : double = 0;
var tc : int;
var counter : int;
var sectsize : int = (markerCnt * 24) + 4;
binw.Write( "SFPLcue ".ToCharArray() );
binw.Write( sectsize );
binw.Write( markerCnt );
for (var i : int = 0; i < markerCnt; i++) {
counter = i + 1;
tc = markerTC[i];
binw.Write( counter );
binw.Write( tc );
binw.Write( "data".ToCharArray() );
binw.Write( zero );
binw.Write( tc );
}
return sectsize;
}
//----------------------------------------------------------------------------------------
function writeLIST(binw, markerLabel, markerCnt) {
var counter : int;
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 = i + 1;
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, SFPLsize, LISTsize, SFPIsize) {
var RIFFsize : int = (12 + SFPLsize) + (8 + LISTsize) + (8 + SFPIsize);
binw.Seek(0, SeekOrigin.Begin);
binw.Seek(4,SeekOrigin.Current);
binw.Write( RIFFsize );
binw.Seek(12 + SFPLsize + 4, SeekOrigin.Current);
binw.Write( LISTsize );
return null;
}
//----------------------------------------------------------------------------------------
// I think 1764 is for PAL only. Note sure about NTSC.
function makeSFL(mrkEnum) {
var markerCnt : int = 0;
var markerTC = new Array();
var markerLabel = new Array();
var nowMarker;
var SFPLsize : int, LISTsize : int, SFPIsize : int;
var RIFFsize : int = 0;
while ( !mrkEnum.atEnd() ) {
nowMarker = mrkEnum.item();
var nowMarkPos = Marker(nowMarker).Position;
markerTC[markerCnt] = nowMarkPos.FrameCount * 1764;
markerLabel[markerCnt] = Marker(nowMarker).Label;
markerCnt++;
mrkEnum.moveNext();
}
var fs = openSFL(desDir, srcMpgFname);
var binw = new BinaryWriter(fs);
writeRIFF(binw, RIFFsize);
SFPLsize = writeSFPL(binw, markerTC, markerCnt);
LISTsize = writeLIST(binw, markerLabel, markerCnt);
SFPIsize = writeSFPI(binw, srcMpgFname);
rewriteSize(binw, SFPLsize, LISTsize, SFPIsize);
closeSFL(fs, binw);
return null;
}
//----------------------------------------------------------------------------------------
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;
}
//----------------------------------------------------------------------------------------
// 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;
}
}
//----------------------------------------------------------------------------------------