Many thanks to jetdv (Edward Troxel). I now have a script that lets me truncate "n" frames from the beginning of the video event that lies under the cursor on the selected video track. If there is an audio track directly below, any audio event under the cursor is also trimmed by the same amount. The script is commented so I won't describe it further except to note one problem that took me several hours to solve.
The big problem is that if you use the AdjustStartLength method to shorten the event, you then have to move the event left to get the start point back where it was (otherwise there is a gap equal to the number of frames truncated). However, any attempt to set the TrackEvent Start property always resulted in the start point moving, but not the media contained in the event. The net result was that the event was truncated at the END, not the beginning. The True/False setting in the AdjustStartLength method makes no difference.
I finally got a hint when jetdv gave me a clue on another problem by suggesting I query the ActiveTake property. When I realized I could also SET this, in addition to being able to QUERY it, I started playing around, and suddenly found the combination that works. Here it is. Thanks to everyone.
John
P.S. I also have a version that trims from the current cursor location to the beginning of the selected video event. This is actually even more useful.
===============================
The big problem is that if you use the AdjustStartLength method to shorten the event, you then have to move the event left to get the start point back where it was (otherwise there is a gap equal to the number of frames truncated). However, any attempt to set the TrackEvent Start property always resulted in the start point moving, but not the media contained in the event. The net result was that the event was truncated at the END, not the beginning. The True/False setting in the AdjustStartLength method makes no difference.
I finally got a hint when jetdv gave me a clue on another problem by suggesting I query the ActiveTake property. When I realized I could also SET this, in addition to being able to QUERY it, I started playing around, and suddenly found the combination that works. Here it is. Thanks to everyone.
John
P.S. I also have a version that trims from the current cursor location to the beginning of the selected video event. This is actually even more useful.
===============================
/**
* PURPOSE OF THIS SCRIPT:
*
* Delete n frames from start of event, and then move all subsequent events to the left by n frames.
*
*
* A video track must be selected. If an audio track is selected, nothing happens.
* The video event on the track that lies beneath the cursor
* will be shortened by the number of frames set in the code below (see comments).
* The cursor does not need to be at the beginning of the event; anywhere over the event is OK.
* If the cursor lies at the boundary between events, the event to the right will be truncated.
* If the track beneath the video track contains audio, the audio event in that track
* that lies beneath the cursor will also be shortened by the same number of frames.
*
* Written By: John Meyer
* With thanks to Edward Troxel
* Written: June 3, 2003
*
**/
import System;
import System.IO;
import System.Windows.Forms;
import SonicFoundry.Vegas;
try {
//Change the next line to set the number of frames to trim.
var DeleteFrames : Timecode = new Timecode("00:00:00:07"); //This is 7 frames.
var DeleteTime : double = DeleteFrames.ToMilliseconds(); // Convert frames to milliseconds.
//Global declarations
var dStart : Double;
var dLength : Double;
var dCursor : Double;
var trackEnum : Enumerator;
var evnt : TrackEvent;
var track = FindSelectedTrack(); //Use this function to find the first selected track.
var eventEnum = new Enumerator(track.Events);
var BeyondCursor : boolean = false; // This flag used to notify if event is to right of cursor.
if (track.IsVideo()) { // Proceed only if selected track is video track.
TrimEventAtCursor(); // Function that trims event and moves all remaining events on track left.
// Get set to look at track directly below the video track.
BeyondCursor = false;
trackEnum.moveNext(); // Go to next track.
if (!trackEnum.atEnd()) { // Only proceed if there is a track below the video track.
track = Track(trackEnum.item()); // When doing the first track (above), these two lines were executed
eventEnum = new Enumerator(track.Events); // in the FindSelectedTrack() function.
if (track.IsAudio()) { // Only trim the event if this is an audio track.
TrimEventAtCursor();
}
}
}
Vegas.UpdateUI();
} catch (e) {
MessageBox.Show(e);
}
// End of main program
// Beginning of functions
function FindSelectedTrack() : Track {
trackEnum = new Enumerator(Vegas.Project.Tracks);
while (!trackEnum.atEnd()) {
var track : Track = Track(trackEnum.item());
if (track.Selected) {
return track;
}
trackEnum.moveNext();
}
return null;
}
/**
*
* The following function finds the event on the selected track
* that lies under the cursor. It also deselects all other events.
*
**/
function TrimEventAtCursor() {
dCursor = Vegas.Cursor.ToMilliseconds(); // Remember the cursor position.
//Go through each event on the track.
while (!eventEnum.atEnd()) {
evnt = TrackEvent(eventEnum.item());
evnt.Selected = false; // De-select the event
// Get the event's start and length timecode, in milliseconds.
dStart = evnt.Start.ToMilliseconds();
dLength = evnt.Length.ToMilliseconds();
//This next IF statement performs ripple edit on the audio and video tracks.
if (BeyondCursor) { // Move, but don't truncate events to the
// evnt.Start=evnt.Start-DeleteFrames; // right of the event under the
cursor.
evnt.AdjustStartLength(evnt.Start-DeleteFrames, evnt.Length, true); //Use this line instead in 4.0d
}
/**
* If the cursor timecode is between the beginning and end of the
* event timecodes, then select the event, and trim start by n frames.
* Move selected event and all events to right of cursor to left by n frames.
**/
if ( (dCursor >= dStart) && ( dCursor < (dLength + dStart) ) ) {
evnt.Selected = true; // Select this event.
BeyondCursor = true; // Remaining events are to right of cursor.
dLength = dLength - DeleteTime;
// Next two lines truncate start of event, and then move it left
// by the same amount that it was truncated.
evnt.AdjustStartLength(new Timecode(dStart), new Timecode(dLength), false);
evnt.ActiveTake.Offset = DeleteFrames+evnt.ActiveTake.Offset;
}
eventEnum.moveNext(); // Go to next event on this timeline.
Vegas.UpdateUI();
}
return null;
}