Script to insert command markers

Radiohead303 wrote on 4/17/2003, 11:10 AM
I want to create a script to automate insertion of command markers for each mediaclip on a track and would appreciate any suggestions to help get me started.

We use two types of command markers ("URL" and "CAPTION") for each media clip to trigger visuals (URL) and text (CAPTION) in Windows Media. As a first step, I'd like to create a script that looks at all of the media on a track and places TWO command markers (one URL, One CAPTION) at each of three points - the beginning, 1/3rd and 2/3rds through the clip. Example, a 3 minute song would have two command markers at each point :00, :60 and 1:20.

Any starter suggestions would be appreciated!!

Comments

jetdv wrote on 4/17/2003, 12:09 PM
Here is a script that will add a standard marker between each clip on the first selected track. This can be a starter for you to modify. All you need to do is change the marker to be a command marker, do it twice, once for each type, and then add the extra ones for inside the event (evnt.Length will give you the length of the event.)



/**
* This script will add markers between all events on the selected track
*
* Written By: Edward Troxel
* www.jetdv.com/tts
* 04/02/2003
**/

import System;
import System.IO;
import System.Windows.Forms;
import SonicFoundry.Vegas;


try {
var zeroMark : Timecode = new Timecode(0);
var myMarker : Marker;

//Find the selected event
var track = FindSelectedTrack();
if (null == track)
throw "no selected track";

var eventEnum = new Enumerator(track.Events);
while (!eventEnum.atEnd()) {
var evnt : TrackEvent = TrackEvent(eventEnum.item());

if (evnt.Start > zeroMark) {
//Put a marker at the start point
myMarker = new Marker(evnt.Start);
Vegas.Project.Markers.Add(myMarker);
}

eventEnum.moveNext();
}



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

function FindSelectedTrack() : Track {
var trackEnum : Enumerator = new Enumerator(Vegas.Project.Tracks);
while (!trackEnum.atEnd()) {
var track : Track = Track(trackEnum.item());

if (track.Selected) {
return track;
}
trackEnum.moveNext();
}
return null;
}
SonyPJM wrote on 4/17/2003, 12:35 PM
Here are two problems you'll probably run across:

1) You can't put two command markers at the exact same time. The
work-around is to put the second marker in the successive frame like
so:


var start = evnt.Start;
var startPlusOneFrame = evnt.Start;
startPlusOneFrame++;

var marker1 = new CommandMarker(start, MarkerCommandType.URL, "http://www.mydomain.com");
var marker2 = new CommandMarker(startPlusOneFrame, MarkerCommandType.Text, "sample caption");
Vegas.Project.CommandMarkers.Add(marker1);
Vegas.Project.CommandMarkers.Add(marker2);



2) I'm afraid scripts can not customize the marker command type. One
of the default types must be chosen (one of the static
MarkerCommandType instances). URL is one of the default types but
"CAPTION" is not. As you see in the code fragment above, I used
MarkerCommandType.Text (TEXT) rather than CAPTION. This was an
oversight in the design of the API and can be fixed but we'll have to
wait for the next release.
Radiohead303 wrote on 4/18/2003, 1:33 AM
I can't thank you enough - this is great! Combined with the "frame offset" tip from sonicJPM, I managed to get my "first" vegas script to work - at least on a basic level - to automate the insertion of both URL and Caption Cmnd Markers at the start of each event. What a time saver. I'm still having issues with getting the timing to work on the additional markers "inside" each event, but this is a great start. Thanks again!

Radiohead303
Radiohead303 wrote on 4/18/2003, 1:51 AM
PJM-

Fantastic - Thanks for your help. Your idea of offsetting the markers by a frame works perfectly!

Would be good in the future to have the option of custom marker command types, but for the time being it's relatively easy to change all of the "TEXT" parameters to "Caption" after everything is set up.

With the script that jetdv provided - along with your tip, I can now place both types of markers at the START of each event. However, I'm having some difficulty finding the right way to duplicate this process to place markers in the MIDDLE of each event. Do you have any tips on how to "divide" the length of each individual event (into halfs or thirds)so that i can repeat the process at those points? I can't seem to make the math work.

Thanks again for your help!
SonyPJM wrote on 4/18/2003, 9:02 AM
Here's some sample code that does your Timecode "multiplication":


var start = evnt.Start; // event start Timecode
var length = evnt.Length; // event length Timecode
var third = length.ToMilliseconds() / 3; // one third of the event length (in ms)
var oneThird = start + new Timecode(third);
var twoThrids = start + new Timecode(2*third);
var end = start + length; // event end Timecode



Radiohead303 wrote on 4/18/2003, 12:59 PM
Thank you - this makes total sense. I'm just learning how many of these parameters work, so I appreciate the code samples. Let me know if I'm overstaying my welcome here, but this should be an easy one.

The following script puts exactly the correct number of markers (with one-frame offsets for the second marker). The "first set" of markers (at evnt.start and evnt2 (evnt.Start++) lay in perfectly. But the script is placing the "inside" markers (at oneThird, oneThird2, etc.) at the wrong place on the timeline - way outside the selected audio events.

Do you see any obvious logical error with the iteration to explain why the timeline appears to be adding time cumulatively, rather than looking to the "start" of each event for the inside markers?

Do I need to reset Timecode to (0) again for each event? If so, at what point in the code would this go?

I appreciate any input you can offer!
-DR


import System;
import System.IO;
import System.Windows.Forms;
import SonicFoundry.Vegas;
try {
var zeroMark : Timecode = new Timecode(0);
//Find the selected event
var track = FindSelectedTrack();
if (null == track)
throw "no selected track";
var eventEnum = new Enumerator(track.Events);
while (!eventEnum.atEnd()) {
var evnt : TrackEvent = TrackEvent(eventEnum.item());
var evnt2 = evnt.Start;
evnt2++;
var start = evnt.Start; // event start Timecode
var length = evnt.Length; // event length Timecode
var third = length.ToMilliseconds() / 3; // one third of the event length (in ms)
var oneThird = start + new Timecode(third);
var oneThird2 = oneThird;
oneThird2++;
var twoThird = start + new Timecode(2*third);
var twoThird2 = twoThird;
twoThird2++;
if (evnt.Start > zeroMark) {
//Put a marker at the start point
var startMarker = new CommandMarker(evnt.Start, MarkerCommandType.Text, "title");
var startMarker2 = new CommandMarker(evnt2, MarkerCommandType.URL, "http://www.customchannels.net")
var onethirdMarker = new CommandMarker(oneThird, MarkerCommandType.Text, "title");
var onethirdMarker2 = new CommandMarker(oneThird2, MarkerCommandType.URL, "http://www.customchannels.net")
var twothirdMarker = new CommandMarker(twoThird, MarkerCommandType.Text, "title");
var twothirdMarker2 = new CommandMarker(twoThird2, MarkerCommandType.URL, "http://www.customchannels.net")
Vegas.Project.CommandMarkers.Add(startMarker);
Vegas.Project.CommandMarkers.Add(startMarker2);
Vegas.Project.CommandMarkers.Add(onethirdMarker);
Vegas.Project.CommandMarkers.Add(onethirdMarker2);
Vegas.Project.CommandMarkers.Add(twothirdMarker);
Vegas.Project.CommandMarkers.Add(twothirdMarker2);
}
eventEnum.moveNext();
}
} catch (e) {
MessageBox.Show(e);
}
function FindSelectedTrack() : Track {
var trackEnum : Enumerator = new Enumerator(Vegas.Project.Tracks);
while (!trackEnum.atEnd()) {
var track : Track = Track(trackEnum.item());
if (track.Selected) {
return track;
}
trackEnum.moveNext();
}
return null;
}
SonyPJM wrote on 4/18/2003, 5:39 PM
You are very welcome and please do keep asking questions.

This turned out to be a tricky problem related to type casting... you really just needed to specify that the variable third is of type double (I think it was converting it to a string and using the Timecode's string constructor). Here's a fixed version of your script (with a few other clean-ups):


import System;
import System.IO;
import System.Windows.Forms;
import SonicFoundry.Vegas;
try {
var zeroMark : Timecode = new Timecode(0);
//Find the selected event
var track = FindSelectedTrack();
if (null == track)
throw "no selected track";
var commandMarkers = Vegas.Project.CommandMarkers;
var eventEnum = new Enumerator(track.Events);
while (!eventEnum.atEnd()) {
var evnt : TrackEvent = TrackEvent(eventEnum.item());
var start = evnt.Start; // event start Timecode
var start2 = evnt.Start;
start2++;
var length = evnt.Length; // event length Timecode
var third : double = length.ToMilliseconds() / 3; // one third of the event length (in ms)
var oneThird = start + new Timecode(third);
var oneThird2 = start + new Timecode(third);
oneThird2++;
var twoThird = start + new Timecode(2*third);
var twoThird2 = start + new Timecode(2*third);
twoThird2++;
if (evnt.Start > zeroMark) {
//Put a marker at the start point
var startMarker = new CommandMarker(start, MarkerCommandType.Text, "title");
var startMarker2 = new CommandMarker(start2, MarkerCommandType.URL, "http://www.customchannels.net");
var onethirdMarker = new CommandMarker(oneThird, MarkerCommandType.Text, "title");
var onethirdMarker2 = new CommandMarker(oneThird2, MarkerCommandType.URL, "http://www.customchannels.net");
var twothirdMarker = new CommandMarker(twoThird, MarkerCommandType.Text, "title");
var twothirdMarker2 = new CommandMarker(twoThird2, MarkerCommandType.URL, "http://www.customchannels.net");
commandMarkers.Add(startMarker);
commandMarkers.Add(startMarker2);
commandMarkers.Add(onethirdMarker);
commandMarkers.Add(onethirdMarker2);
commandMarkers.Add(twothirdMarker);
commandMarkers.Add(twothirdMarker2);
}
eventEnum.moveNext();
}
} catch (e) {
MessageBox.Show(e);
}
function FindSelectedTrack() : Track {
var trackEnum : Enumerator = new Enumerator(Vegas.Project.Tracks);
while (!trackEnum.atEnd()) {
var track : Track = Track(trackEnum.item());
if (track.Selected) {
return track;
}
trackEnum.moveNext();
}
return null;
}


B.T.W. It helps to put code in <PRE> tags here in the scripting forum so that indentation will be preserved.
Radiohead303 wrote on 4/21/2003, 12:52 PM
Wow- This is a huge help and it works perfectly - Thanks!

Two quick questions:
1) Is there a way to get the Event Name (evnt) and use that to populate the "title" parameter of the TEXT command marker? I've tried several approaches with String Name, but can't seem to get the argument right.

2) You suggested putting codes in
 tags to preserve indentations. Can you tell me how do to this? I'm using notepad to edit.

Thanks!
SonyPJM wrote on 4/21/2003, 1:04 PM
The thing about the TrackEvent.Name property is there's no "normal"
GUI for setting them... they're just sort of a hidden feature exposed
by the scripting API. So you can get and set event names from a script
but you can't see/edit them through the normal API. You can, however,
write a little script with a GUI to edit the name of a selected event.

If, on the other hand, you're talking about Take names, those can be
seen and edited through Vegas' GUI (right click on the event for the
Take Menu). Take names are also accessible through the scripting API:


evnt.Takes[0].Name = "my take name";
var takeName = evnt.Takes[0].Name;



As you can probable see in your last post, the <PRE> tags are just a way to preserve spacing in code that you paste into a forum message.
Radiohead303 wrote on 4/21/2003, 3:48 PM
Thanks - this is perfect. It was the evnt.Takes[0].Name that I was looking for. Now with the script the command marker parameters fill in with the actual name of the event. This is a HUGE timesaver for us. Thanks again.

SonyPJM wrote on 4/21/2003, 4:34 PM
I'm glad it worked out. The fix for customized command marker types (TEXT vs. CAPTION) should be in the next release (4.0c).