This is a crude demonstration script that is meant to show the concept of how you can create an effect where a pan/crop keyframe gradually and smoothly accelerates. The idea is that sometimes you want the motion to start slowly and then gradually increase in speed, and sometimes you want the opposite.
This script is hard wired. However, those that make commercial scripts might want to take the concept (and you are welcome to the code) and add a UI that would let you specify a beginning and ending location for the event; and let the user choose from a variety of acceleration models, perhaps with slider controls. This demonstration code uses a simple arithmetic acceleration where the first frame moves by unit 1, the second keyframe by unit 2, the third by unit three, etc. It puts twenty keyframes, equally spaced, into the event, so the last keyframe is moving 20 times further than did the first keyframe.
Anyway, here it is, in all its raw, crude splendor ...
This script is hard wired. However, those that make commercial scripts might want to take the concept (and you are welcome to the code) and add a UI that would let you specify a beginning and ending location for the event; and let the user choose from a variety of acceleration models, perhaps with slider controls. This demonstration code uses a simple arithmetic acceleration where the first frame moves by unit 1, the second keyframe by unit 2, the third by unit three, etc. It puts twenty keyframes, equally spaced, into the event, so the last keyframe is moving 20 times further than did the first keyframe.
Anyway, here it is, in all its raw, crude splendor ...
/**
* This script will assign "max" keyframes to the each selected event on the first timeline.
* It then pans the event by a smoothly accelerating rate.
*
* Copyright 2006 - John H. Meyer
* Last revision, April 25, 2006
*
**/
import System;
import System.Collections;
import System.Text;
import System.IO;
import System.Drawing;
import System.Windows.Forms;
import Sony.Vegas;
var evnt : TrackEvent;
var zero : int = 0;
var max : int = 40; // Change this to increase the number of keyframes,
// and thereby increase smoothness.
// Don't make this larger than number of frames in
// shortest event (no bounds checking in this script).
try {
//Find the selected event
var track = FindSelectedTrack();
if (null == track) // Must select a track
throw "no selected track";
var eventEnum = new Enumerator(track.Events);
if (track.IsVideo()) { // Track must be a video track
while (!eventEnum.atEnd()) {
evnt = TrackEvent(eventEnum.item());
if (evnt.Selected) {
var vevnt = VideoEvent(evnt);
var EventLength = evnt.Length.ToMilliseconds();
// Check if there is only one keyframe. Don't proceed if keyframes already assigned.
var keycollection = vevnt.VideoMotion.Keyframes;
if (keycollection.Count <= 1){
var mediaStream = GetActiveMediaStream (evnt); // These lines get width of media
if (mediaStream) {
var videoStream = VideoStream (mediaStream);
}
var minkeywidth = (max*(max+1))/2;
var videoWidth = videoStream.Width;
var videoHeight = videoStream.Height;
for (var i = max; i >= 0; i--) {
// This next line is the function for how far to move each keyframe
// Change this line to change the acceleration
var offset = new VideoMotionVertex(float(((max-i)/minkeywidth)*videoWidth), float(0));
// Create the next keyframe equally spaced from last keyframe
var NewKeyTimecode = new Timecode(Timecode.FromMilliseconds(int(EventLength - EventLength * (i/max))));
var key2 = new VideoMotionKeyframe(NewKeyTimecode);
vevnt.VideoMotion.Keyframes.Add(key2); // Add the new key frame
if (i < max) {
key2.MoveBy(offset); // Actually apply the offset; Don't move first keyframe.
} // End if i<max
vevnt.VideoMotion.Keyframes[max-i].Smoothness = 0; // Turn off the stupid smoothness setting
} // End for i=max
} //End if keycollection
} //End if selected
eventEnum.moveNext();
} // End While eventEnum
} // End If track.IsVideo
else {
MessageBox.Show("You must select a video track");
}
} catch (e) {
MessageBox.Show(e);
}
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;
}
function GetActiveMediaStream (trackEvent : TrackEvent) {
try {
if ( ! trackEvent.ActiveTake.IsValid()) {
throw "empty or invalid take";
}
var media = Vegas.Project.MediaPool.Find (trackEvent.ActiveTake.MediaPath);
if (null == media) {
throw "missing media";
}
var mediaStream = media.Streams.GetItemByMediaType (MediaType.Video, trackEvent.ActiveTake.StreamIndex);
return mediaStream;
}
catch (e) {
//MessageBox.Show(e);
return null;
}
}