Hi all,
Today during a walk in the forest I got an idea how grouping could be accessed from within scripts, under certain conditions... and it seems to work :-)
The basic idea is: if a script can enqueue keystrokes to be processed after it ended, it can also enqueue a keystroke (like Ctrl-8) that calls another script. It can even call a keystroke that re-invokes itself! As you can also enqueue several keystrokes, you can cause Vegas to perform certain actions like "g" (group all selected events) or "G" (select all events in group) and subsequently call the script again.
As you can also state store values in the registry, a script can "know" whether it was called the first, or the second time. Of course you must actually implement a state machine that allows script interruptions and restarts every time you need a grouping.
This works under the main condition that the script is assigned to a key (like Ctrl-8) _AND_ that the script knows this key! Unfortunately I'm not aware of any way the script could find out itself on what key it is assigned; so ithe user actually _MUST_ modify teh script source so far as to tell it to what key it was assigned. In the following example code you can do this in the "var restarter = new Restarter(8);" line - here it is assumed teh script was assigned to Ctrl-8. Use any int value between 0 and 9 in teh constructor in order to tell it to what key the script is assigned.
I know the formatting is not nice within a forum message, but I still post it this way because it is experimental. The following script tries to reconstruct audio events to given video events (like Excaliburs Orphan wizard). It assumes the video events are selected, constructs matching audio events into an extra track, and groups each video event with its matching audio event! Tha last step can not be performed from within the script, so it actually sequentally selects 2 events, leaves, enforces "g" and "Ctrl-8" that restarts teh script.
One caveat: It does create registry entries under "HKEY_CURRENT_USER\Software\VegasScripts\unite" (assumed the script name is unite.js), as you can see using regedit. If the script crashes by some problem, it might be the state value (which should be initially set to 0) is left on 1. You might need to remove the "unite" registry key completely in this case.
Note: Of course this technique can be used in any case where you need Vegas to perform keystrokes during scripts (like asked in "force timeline redraw")
Code:
import System.Windows.Forms;
import System.Collections;
import SonicFoundry.Vegas;
import Microsoft.Win32;
import System.IO;
try
{
var restarter = new Restarter(8);
var count: int;
switch (restarter.state)
{
case 0:
var at = new AudioTrack(-1,"Missing Audio");
Vegas.Project.Tracks.Add(at);
count = 0;
for (var t in Vegas.Project.Tracks)
{
if (t.IsAudio()) continue;
for (var e in t.Events)
{
if (!e.Selected) continue;
e.ActiveTake.Name = "#" + count + "%" +
(e.ActiveTake.Name==null? "": e.ActiveTake.Name);
var ae = new AudioEvent(e.Start,e.Length);
at.Events.Add(ae);
for (var tke in e.Takes)
{
var aviFile = new Media(tke.MediaPath);
for (var stream in aviFile.Streams)
{
if (stream.MediaType != MediaType.Audio) continue;
var newTake = new Take(stream,tke.IsActive);
ae.Takes.Add(newTake);
newTake.Offset = tke.Offset;
break;
} // for stream
} // for tke
ae.ActiveTake.Name = "#" + count + "%" +
(ae.ActiveTake.Name==null? "": ae.ActiveTake.Name);
count++;
} // for e
} // for t
restarter.setState(1);
// Fallthrough!
case 1:
var countToMatch = -1;
for (var t in Vegas.Project.Tracks)
{
for (var e in t.Events)
{
e.Selected = false;
count = -2;
var posPercent = -1; // index of % char in event name
if (e.ActiveTake.Name != null && e.ActiveTake.Name.substr(0,1) == "#")
{
var posPercent = e.ActiveTake.Name.IndexOf("%");
if (posPercent>0)
count = System.Int32.Parse(e.ActiveTake.Name.slice(1,posPercent));
}
if (count>=0 && countToMatch<0) countToMatch=count;
if (count==countToMatch)
{
e.Selected=true;
e.ActiveTake.Name = e.ActiveTake.Name.substr(posPercent+1);
}
}
}
if (countToMatch < 0)
restarter.setState(0);
else
restarter.doGroup();
} // switch
}
catch(e) {MessageBox.Show(e);}
class Restarter
{
var rk : RegistryKey;
var wshShell;
var scriptKey: String;
var state: int;
function Restarter(scriptKeyIndex:int)
{
rk = Registry.CurrentUser;
rk = rk.CreateSubKey("Software");
rk = rk.CreateSubKey("VegasScripts");
rk = rk.CreateSubKey(Path.GetFileNameWithoutExtension(ScriptFile));
wshShell = new ActiveXObject("WScript.Shell");
scriptKey = "^" + scriptKeyIndex;
state = getVarInt("$state");
}
// set state (and write to registry):
function setState(i:int)
{state=i; setVarInt("$state",state);}
// get and set general variables (int and string)
function getVarInt(n:String): int
{return(rk.GetValue(n.concat("Int"),0));}
function getVarString(n:String): String
{return(rk.GetValue(n.concat("Str"),""));}
function setVarInt(n:String, i:int)
{rk.SetValue(n.concat("Int"),i);}
function setVarString(n:String, s:String)
{rk.SetValue(n.concat("Str"),s);}
function doGroup()
{
wshShell.SendKeys("%0");
wshShell.SendKeys("^u");
wshShell.SendKeys("g");
wshShell.SendKeys(scriptKey);
}
}
Today during a walk in the forest I got an idea how grouping could be accessed from within scripts, under certain conditions... and it seems to work :-)
The basic idea is: if a script can enqueue keystrokes to be processed after it ended, it can also enqueue a keystroke (like Ctrl-8) that calls another script. It can even call a keystroke that re-invokes itself! As you can also enqueue several keystrokes, you can cause Vegas to perform certain actions like "g" (group all selected events) or "G" (select all events in group) and subsequently call the script again.
As you can also state store values in the registry, a script can "know" whether it was called the first, or the second time. Of course you must actually implement a state machine that allows script interruptions and restarts every time you need a grouping.
This works under the main condition that the script is assigned to a key (like Ctrl-8) _AND_ that the script knows this key! Unfortunately I'm not aware of any way the script could find out itself on what key it is assigned; so ithe user actually _MUST_ modify teh script source so far as to tell it to what key it was assigned. In the following example code you can do this in the "var restarter = new Restarter(8);" line - here it is assumed teh script was assigned to Ctrl-8. Use any int value between 0 and 9 in teh constructor in order to tell it to what key the script is assigned.
I know the formatting is not nice within a forum message, but I still post it this way because it is experimental. The following script tries to reconstruct audio events to given video events (like Excaliburs Orphan wizard). It assumes the video events are selected, constructs matching audio events into an extra track, and groups each video event with its matching audio event! Tha last step can not be performed from within the script, so it actually sequentally selects 2 events, leaves, enforces "g" and "Ctrl-8" that restarts teh script.
One caveat: It does create registry entries under "HKEY_CURRENT_USER\Software\VegasScripts\unite" (assumed the script name is unite.js), as you can see using regedit. If the script crashes by some problem, it might be the state value (which should be initially set to 0) is left on 1. You might need to remove the "unite" registry key completely in this case.
Note: Of course this technique can be used in any case where you need Vegas to perform keystrokes during scripts (like asked in "force timeline redraw")
Code:
import System.Windows.Forms;
import System.Collections;
import SonicFoundry.Vegas;
import Microsoft.Win32;
import System.IO;
try
{
var restarter = new Restarter(8);
var count: int;
switch (restarter.state)
{
case 0:
var at = new AudioTrack(-1,"Missing Audio");
Vegas.Project.Tracks.Add(at);
count = 0;
for (var t in Vegas.Project.Tracks)
{
if (t.IsAudio()) continue;
for (var e in t.Events)
{
if (!e.Selected) continue;
e.ActiveTake.Name = "#" + count + "%" +
(e.ActiveTake.Name==null? "": e.ActiveTake.Name);
var ae = new AudioEvent(e.Start,e.Length);
at.Events.Add(ae);
for (var tke in e.Takes)
{
var aviFile = new Media(tke.MediaPath);
for (var stream in aviFile.Streams)
{
if (stream.MediaType != MediaType.Audio) continue;
var newTake = new Take(stream,tke.IsActive);
ae.Takes.Add(newTake);
newTake.Offset = tke.Offset;
break;
} // for stream
} // for tke
ae.ActiveTake.Name = "#" + count + "%" +
(ae.ActiveTake.Name==null? "": ae.ActiveTake.Name);
count++;
} // for e
} // for t
restarter.setState(1);
// Fallthrough!
case 1:
var countToMatch = -1;
for (var t in Vegas.Project.Tracks)
{
for (var e in t.Events)
{
e.Selected = false;
count = -2;
var posPercent = -1; // index of % char in event name
if (e.ActiveTake.Name != null && e.ActiveTake.Name.substr(0,1) == "#")
{
var posPercent = e.ActiveTake.Name.IndexOf("%");
if (posPercent>0)
count = System.Int32.Parse(e.ActiveTake.Name.slice(1,posPercent));
}
if (count>=0 && countToMatch<0) countToMatch=count;
if (count==countToMatch)
{
e.Selected=true;
e.ActiveTake.Name = e.ActiveTake.Name.substr(posPercent+1);
}
}
}
if (countToMatch < 0)
restarter.setState(0);
else
restarter.doGroup();
} // switch
}
catch(e) {MessageBox.Show(e);}
class Restarter
{
var rk : RegistryKey;
var wshShell;
var scriptKey: String;
var state: int;
function Restarter(scriptKeyIndex:int)
{
rk = Registry.CurrentUser;
rk = rk.CreateSubKey("Software");
rk = rk.CreateSubKey("VegasScripts");
rk = rk.CreateSubKey(Path.GetFileNameWithoutExtension(ScriptFile));
wshShell = new ActiveXObject("WScript.Shell");
scriptKey = "^" + scriptKeyIndex;
state = getVarInt("$state");
}
// set state (and write to registry):
function setState(i:int)
{state=i; setVarInt("$state",state);}
// get and set general variables (int and string)
function getVarInt(n:String): int
{return(rk.GetValue(n.concat("Int"),0));}
function getVarString(n:String): String
{return(rk.GetValue(n.concat("Str"),""));}
function setVarInt(n:String, i:int)
{rk.SetValue(n.concat("Int"),i);}
function setVarString(n:String, s:String)
{rk.SetValue(n.concat("Str"),s);}
function doGroup()
{
wshShell.SendKeys("%0");
wshShell.SendKeys("^u");
wshShell.SendKeys("g");
wshShell.SendKeys(scriptKey);
}
}