Hi everyone
hello @jetdv sir..
i just created this script via help of ChatGPT.
only one button is working well.
others are giving errors..
✔️Distribute exiting keyframes of PAN & CROP via equal distance. (replacement not adding any new)
✖️Distribute exiting keyframes of OFX via equal distance. (replacement not adding any new)
✖️Making loop from exiting 2 keyframes from both OFX / PAN & CROP via copying both exiting keyframes and placing forward up to user's requirement. if existing keys are A B and user want 5 times loop then (A B A B A B A B A B A) considering A-B-A is one loop
please help me fixing these..
thanks in advance..
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ScriptPortal.Vegas;
public class EntryPoint
{
public void FromVegas(Vegas vegas)
{
Application.EnableVisualStyles();
Application.Run(new MainForm(vegas));
}
}
public class MainForm : Form
{
private Vegas vegas;
private Button btnPanCrop;
private Button btnOFX;
public MainForm(Vegas v)
{
vegas = v;
Text = "Keyframe Redistributor";
Width = 300;
Height = 150;
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
btnPanCrop = new Button()
{
Text = "Redistribute Pan/Crop",
Width = 220,
Height = 30,
Top = 15,
Left = 30
};
Button btnMakeLoop = new Button()
{
Text = "Make Pan/Crop Loop",
Width = 220,
Height = 30,
Top = 95,
Left = 30
};
btnMakeLoop.Click += (s, e) => MakePanCropLoop();
Controls.Add(btnMakeLoop);
btnOFX = new Button()
{
Text = "Redistribute OFX",
Width = 220,
Height = 30,
Top = 55,
Left = 30
};
btnPanCrop.Click += (s, e) => RedistributePanCropKeys();
btnOFX.Click += (s, e) => RedistributeOFXKeys();
Controls.Add(btnPanCrop);
Controls.Add(btnOFX);
}
private void MakePanCropLoop()
{
string input = PromptLoops();
if (input == null) return;
int loops;
if (!int.TryParse(input, out loops) || loops < 1)
{
MessageBox.Show("Invalid loop count.");
return;
}
foreach (Track track in vegas.Project.Tracks)
{
if (!track.IsVideo()) continue;
foreach (VideoEvent ev in track.Events)
{
if (!ev.Selected) continue;
var keys = ev.VideoMotion.Keyframes;
if (keys.Count < 2)
{
MessageBox.Show("Pan/Crop must have at least 2 keyframes (A & B).");
return;
}
// base keys
VideoMotionKeyframe A = keys[0];
VideoMotionKeyframe B = keys[1];
// clear all existing keys
while (keys.Count > 0)
keys.RemoveAt(0);
int totalKeys = loops * 2;
double step = ev.Length.ToMilliseconds() / (totalKeys - 1);
for (int i = 0; i < loops; i++)
{
// ---- A ----
int idxA = keys.Add(Timecode.FromMilliseconds(step * (i * 2)));
keys[idxA].Bounds = A.Bounds;
keys[idxA].Rotation = A.Rotation;
keys[idxA].Smoothness = A.Smoothness;
// ---- B ----
int idxB = keys.Add(Timecode.FromMilliseconds(step * (i * 2 + 1)));
keys[idxB].Bounds = B.Bounds;
keys[idxB].Rotation = B.Rotation;
keys[idxB].Smoothness = B.Smoothness;
}
}
}
MessageBox.Show("Pan/Crop loop created (A B copied & distributed).");
}
private string PromptLoops()
{
Form f = new Form();
f.Text = "Make Loop";
f.Width = 260;
f.Height = 120;
f.FormBorderStyle = FormBorderStyle.FixedDialog;
f.StartPosition = FormStartPosition.CenterScreen;
Label lbl = new Label();
lbl.Text = "How many loops? (A B = 1 loop)";
lbl.Left = 10;
lbl.Top = 10;
lbl.Width = 220;
TextBox tb = new TextBox();
tb.Left = 10;
tb.Top = 35;
tb.Width = 220;
tb.Text = "3";
Button ok = new Button();
ok.Text = "OK";
ok.Left = 155;
ok.Top = 65;
ok.DialogResult = DialogResult.OK;
f.Controls.Add(lbl);
f.Controls.Add(tb);
f.Controls.Add(ok);
f.AcceptButton = ok;
return f.ShowDialog() == DialogResult.OK ? tb.Text : null;
}
// ================= PAN / CROP =================
private void RedistributePanCropKeys()
{
bool found = false;
foreach (Track track in vegas.Project.Tracks)
{
if (!track.IsVideo()) continue;
foreach (VideoEvent ev in track.Events)
{
if (!ev.Selected) continue;
var keys = ev.VideoMotion.Keyframes;
int count = keys.Count;
if (count < 2) continue;
double step = ev.Length.ToMilliseconds() / (count - 1);
for (int i = 0; i < count; i++)
{
keys[i].Position = Timecode.FromMilliseconds(step * i);
}
found = true;
}
}
MessageBox.Show(
found ? "Pan/Crop keyframes redistributed." : "No valid Pan/Crop keys found.",
"Done",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
}
// ================= OFX =================
private void RedistributeOFXKeys()
{
bool found = false;
foreach (Track track in vegas.Project.Tracks)
{
if (!track.IsVideo()) continue;
foreach (VideoEvent ev in track.Events)
{
if (!ev.Selected) continue;
foreach (Effect eff in ev.Effects)
{
if (!eff.IsOFX) continue;
OFXEffect ofx = null;
// 🔥 THIS IS THE FIX
try
{
ofx = eff.OFXEffect;
}
catch
{
continue; // skip broken / inaccessible OFX
}
if (ofx == null) continue;
foreach (OFXParameter parm in ofx.Parameters)
{
if (!parm.IsAnimated) continue;
Timecode len = ev.Length;
try
{
switch (parm.ParameterType)
{
case OFXParameterType.Double:
RedistributeOFX(((OFXDoubleParameter)ofx[parm.Name]).Keyframes, len); found = true; break;
case OFXParameterType.Double2D:
RedistributeOFX(((OFXDouble2DParameter)ofx[parm.Name]).Keyframes, len); found = true; break;
case OFXParameterType.Double3D:
RedistributeOFX(((OFXDouble3DParameter)ofx[parm.Name]).Keyframes, len); found = true; break;
case OFXParameterType.RGB:
RedistributeOFX(((OFXRGBParameter)ofx[parm.Name]).Keyframes, len); found = true; break;
case OFXParameterType.RGBA:
RedistributeOFX(((OFXRGBAParameter)ofx[parm.Name]).Keyframes, len); found = true; break;
case OFXParameterType.Integer:
RedistributeOFX(((OFXIntegerParameter)ofx[parm.Name]).Keyframes, len); found = true; break;
case OFXParameterType.Boolean:
RedistributeOFX(((OFXBooleanParameter)ofx[parm.Name]).Keyframes, len); found = true; break;
case OFXParameterType.Choice:
RedistributeOFX(((OFXChoiceParameter)ofx[parm.Name]).Keyframes, len); found = true; break;
}
}
catch
{
// skip individual broken parameter
continue;
}
}
}
}
}
MessageBox.Show(
found ? "OFX keyframes redistributed safely." : "No usable animated OFX parameters found.",
"Done",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
}
// ================= GENERIC OFX HELPER =================
private void RedistributeOFX<T>(IList<T> keys, Timecode len) where T : OFXKeyframe
{
int count = keys.Count;
if (count < 2) return;
double step = len.ToMilliseconds() / (count - 1);
for (int i = 0; i < count; i++)
{
keys[i].Time = Timecode.FromMilliseconds(step * i);
}
}
}