L and J cut scripts

johnmeyer wrote on 9/24/2004, 1:41 PM
This script will let you easily create and edit "L" and "J" cuts.

To use, click in the middle of the first of two events that you want to L or J cut (actually, the cursor simply needs to be over the first of the two events). Then, run the script. The video from the first event, and the audio from the following event will be shortened by one second in a mirror image of each other. You can then trim the audio or video of either event without affecting that event's associated audio and video. Despite this, the audio and video are still locked together when you move them so they don't get out of sync. You can "butt" the audio and crossfade the video or any combination of things.

The edges of the events on the opposite sides from the L and J cut are still locked together.

I recommend that you turn off ripple edit when doing L and J cuts. You can the turn it back on again (or use "F" or "Ctrl-F") to close the gap with all the subsequent events.

You can modify one line in the script, as described in the script comments below, to create a J cut instead of an L cut (I actually don't know which one is created here). I suppose I could modify the script so you could choose which type of cut you want each time, but I didn't like the idea of having that extra step. If you need to do both types of cuts, make a copy of the script, save under a different name, and then make the edit to change from L to J. Assign both scripts to different keys, and you can do either type of cut with one keystroke.

Have fun!

Oh, yes. If you copy the following code, paste it into your word processor and then replace all the line breaks ( search for ^l in Word) and replace with paragraph marks ( replace with ^p in Word). Then, save as a text file with the extension ".js" . Sorry about that, but that is the way that Windows deals with HTML. If you just copy and paste into Notepad, you'll get a jolly jumble.

I'll try to get the script uploaded to Sundance in the next few days.

/** 
* PURPOSE OF THIS SCRIPT:
*
* Modify events that lie under the cursor so that the audio and video can be trimmed independently,
* while still retaining grouping between the audio and video. This is used for "J" and "L" cuts.
*
* Copyright © John Meyer 2004
* Written: September 24, 2004
* Tested on Vegas 5.0b
*
**/

import System;
import System.IO;
import System.Windows.Forms;
import System.Collections;
import Sony.Vegas;

try {

//Global declarations
var dStart : Double; // Start of event
var dLength : Double; // Length of event
var dCursor : Double; // Current cursor position
var dSlop : Double = 0.1; // Variable needed because Vegas is sloppy and doesn't
// make audio and video exactly the same length
var trackEnum : Enumerator;
var evnt : TrackEvent;

var track = FindSelectedTrack(); // Function to find the first selected track.
var eventEnum = new Enumerator(track.Events); // List of events on this track

if (track.IsVideo()) { // Proceed only if selected track is video track.

if ( L_J_CutAtCursor(true) ) { // Prepare both video event under cursor, and next video event
trackEnum.moveNext(); // If success on video track, go to next track.
if (!trackEnum.atEnd()) { // Only proceed if there is a track below the video track.
track = Track(trackEnum.item());
if (track.IsAudio()) { // Only proceed if this is an audio track.
eventEnum = new Enumerator(track.Events);
L_J_CutAtCursor(false); // Prepare both audio event under cursor, and next audio event
} // End If track.IsAudio()
} // End If !trackEnum.atEnd()
} // End If L_J_CutAtCursor()

}

else {
MessageBox.Show ("You need to select the video track, not the audio track", "Alert");
} // End track.IsVideo()

Vegas.UpdateUI(); // Update the UI.

} // End try

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;
}


/**
*
* If "IsVid" is true, the following function finds the video event that lies under the cursor
* on the selected track and shortens the END of this event.
* If "IsVid" is false, the following function finds the audio event immediately AFTER the
* audio event that lies under the cursor and shortens the BEGINNING of this event.
*
* By changing the one IF statement from "IsVid" to "!IsVid" the function will create the exact
* opposite effect, thus giving you a "J" cut instead of an "L" cut.
*
**/

function L_J_CutAtCursor(IsVid : boolean) {

var EventFound : boolean = false; // Function returns false if no video media under cursor.

dCursor = Vegas.Cursor.ToMilliseconds(); // Remember the cursor position.

while (!eventEnum.atEnd()) { // Go through each event on the track.
evnt = TrackEvent(eventEnum.item()); // Get next event
evnt.Selected = false; // De-select the event
dStart = evnt.Start.ToMilliseconds(); // Get the event's start and
dLength = evnt.Length.ToMilliseconds(); // length timecode, in milliseconds.

/**
* If the cursor timecode is between the beginning and end of the
* event timecodes, then we have found the event under the cursor.
**/

if ( (dCursor >= dStart) && ( dCursor < (dStart + dLength - dSlop) ) ) {

evnt.Selected = true; // Select this event.
EventFound = true; // Notify calling function that event was found

if (IsVid) { // Do one thing if this is video event, another if it is audio.
// if (!IsVid) { // Use this line rather than one above to change from L to J cut.
// Next line changes event length
evnt.AdjustStartLength(evnt.Start, evnt.Length - Timecode.FromSeconds(1), false);
}
else {
eventEnum.moveNext(); // Go to next event on this timeline.
evnt = TrackEvent(eventEnum.item()); // Next line changes event length
evnt.AdjustStartLength(evnt.Start + Timecode.FromSeconds(1), evnt.Length - Timecode.FromSeconds(1), false);
}

} // End If dCursor (etc.)

eventEnum.moveNext(); // Go to next event on this timeline.
}

return EventFound;

}

Comments

jetdv wrote on 9/24/2004, 6:26 PM
All 4 of John Meyer's new scripts can now be downloaded from here.
BrianStanding wrote on 9/27/2004, 7:02 AM
Hi, John

I thought I'd move our discussion in the Vegas forum here. I installed DVDA 2.0a to fix the object reference problem. Then I tried your script and it seems to work well.. Thanks for doing all this.

A couple of questions:
1. Any particular reason this is limited this to the video track? There are times I'd like to be able to adjust the audio track, rather than the video.
2. It looks like I would have to run the script twice (once on each event) to trim adjacent event edges (Ctrtl-Alt-mouse drag). Is this right?

I'm not a scripter (although I'm increasingly thinking I should learn JavaScript), so please forgive me if I'm asking some stupid questions. I have a couple of thoughts.

Is it possible in the Vegas scripting protocol to write a script that would initiate one action, wait for some kind of mouse movement, then initiate another action? What I have in mind is a script that would do the following:

1. Turn on "Ignore Event Grouping"
2. Wait for any kind of mouse action on timeline events, then
3. Turn off "Ignore Event Grouping."

If possible, I think this would have the following advantages:
- this would allow you to adjust adjacent event edges at the same time
- this would be applicable to either audio or video tracks
- this technique could be applied to other Vegas commands, like "Auto-Ripple," where you don't want to forget to turn the feature off.

Is this possible? Thanks again for all your work on thisl
jetdv wrote on 9/27/2004, 7:37 AM
Is it possible in the Vegas scripting protocol to write a script that would initiate one action, wait for some kind of mouse movement, then initiate another action? What I have in mind is a script that would do the following:

No it is not. When the script is running, you cannot do anything to the interface.
johnmeyer wrote on 9/27/2004, 3:13 PM
1. Any particular reason this is limited this to the video track?

The only reason is that I was focused on L and J cuts, which are where the audio from one event overlaps the video from the other event.

2. It looks like I would have to run the script twice (once on each event) to trim adjacent event edges (Ctrtl-Alt-mouse drag). Is this right?

I am not quite sure what you mean. The script works on the video and audio event under the cursor AND the following video/audio event. Thus, as you must have already seen, the adjacent edges (at least as I would define them) of the events are already being prepared for the L or J cut and therefore you only need to run the script once. However, if you want to trim the other edge of either of the two events involved in the first cut then yes, you would need to run the script again. Each invocation of the script prepares one boundary between two events.
BrianStanding wrote on 9/28/2004, 9:26 AM
O.K., after reading the instructions within the script itself, I finally realized how they are supposed to work. I didn't realize you really need to edit the file and save as two separate scripts: one for L-cuts, and and another for J-cuts.

I now have remapped my keyboard so "Ctrl-J" runs the J-cut script, and "Ctrl-L" runs the L-cut script (replacing the Vegas default shortcut to engage "Auto Ripple" -- which I never use from the keyboard anyway). Works great!

Thanks, John, and sorry for being a bit dense. I was so excited by your discovery that I didn't read your post very closely.
johnmeyer wrote on 9/28/2004, 10:46 AM
Brian,

You can download a slightly newer version of the script from jedv's site (he provide the link above, and here it is again:

L and J Cut Script With Message Box

This version asks you each time which type of cut you want. Of course, now that you have created both scripts, you may find it easier to assign them to two shortcut keys and go that route. Your choice.

Marco. wrote on 6/5/2005, 5:36 AM
John, I just realized running this script causes not only a one second time difference on both the event under the cursor and the following one (which of course is intended and fine) but also the following event will be out of sync then.

This happened with Vegas 6.0b. Is this a 6.0b version issue or is this the way the script works (I know what the script does is preparing the L-/J-cut but causing an event to be out of sync then seems to be strange)?

Marco
johnmeyer wrote on 6/5/2005, 8:07 AM
If there is any loss of sync, then something has gone wrong. The original script, posted in this thread, was tested on 5.0b, long before 6.0 was being tested. I've never used the script on 6.0, so I don't know whether it works there. However, just to reiterate, I am certain there is no loss of sync. All that should happen is that the edges of the events are trimmed to form either the L or J cut, and also Vegas is put in a state where you can continue to trim either the audio or the video, on either sets of events, WITHOUT losing the audio sync. That was the whole "magic" of the thing in the first place.
Marco. wrote on 6/5/2005, 8:46 AM
Thanks for your quick reply. Then there's obviously something going wrong with Vegas 6.0b. Seems like the audio of the following event isn't cut for the length of one second but moved instead. Maybe this is related to the Vegas problem with AdjustStartLength!?

Marco
johnmeyer wrote on 6/5/2005, 10:53 AM
Maybe this is related to the Vegas problem with AdjustStartLength!?

I think this is almost certainly the case. The function:
function L_J_CutAtCursor(IsVid : boolean)
contains the following statement:
evnt.AdjustStartLength(evnt.Start, evnt.Length - Timecode.FromSeconds(1), false);
I haven't followed all the discussions about how 6.0 broke this function, other than to point out that this isn't the first time Sony broke it. If someone posted a fix or workaround, you can probably fix this script just by applying that fix or workaround to this one line.
jetdv wrote on 6/5/2005, 10:53 AM
The "AdjustStartLength" command changed so that it CAN create out-of-sync events. You also need to change the take offset to compensate for this change in how that command works.
Marco. wrote on 6/5/2005, 10:56 AM
Thanks John and Ed for the infos.

Marco
Wolfgang S. wrote on 6/5/2005, 11:41 AM
Here is your correction.

Kind regards,
Wolfgang

/**
* PURPOSE OF THIS SCRIPT:
*
* Modify events that lie under the cursor so that the audio and video can be trimmed independently,
* while still retaining grouping between the audio and video. This is used for "J" and "L" cuts.
*
* Copyright © John Meyer 2004
* Written: September 24, 2004
* Corrected for Vegas 6.0b by Wolfgang Schmid
*
**/

import System;
import System.IO;
import System.Windows.Forms;
import System.Collections;
import Sony.Vegas;

try {

//Global declarations
var dStart : Double; // Start of event
var dLength : Double; // Length of event
var dCursor : Double; // Current cursor position
var LJCut : Boolean = true;
var dSlop : Double = 0.1; // Variable needed because Vegas is sloppy and doesn't
// make audio and video exactly the same length

var trackEnum : Enumerator;
var evnt : TrackEvent;

var track = FindSelectedTrack(); // Function to find the first selected track.
var eventEnum = new Enumerator(track.Events); // List of events on this track

if (track.IsVideo()) { // Proceed only if selected track is video track.
var msgBoxResult = MessageBox.Show("Next event's audio preceeds video?", "Make Choice", MessageBoxButtons.YesNo);
if (msgBoxResult == DialogResult.Yes) {
LJCut = !LJCut;
}
if ( L_J_CutAtCursor(LJCut) ) { // Prepare both video event under cursor, and next video event
trackEnum.moveNext(); // If success on video track, go to next track.
if (!trackEnum.atEnd()) { // Only proceed if there is a track below the video track.
track = Track(trackEnum.item());
if (track.IsAudio()) { // Only proceed if this is an audio track.
eventEnum = new Enumerator(track.Events);
L_J_CutAtCursor(!LJCut); // Prepare both audio event under cursor, and next audio event
} // End If track.IsAudio()
} // End If !trackEnum.atEnd()
} // End If L_J_CutAtCursor()

}

else {
MessageBox.Show ("You need to select the video track, not the audio track", "Alert");
} // End track.IsVideo()

Vegas.UpdateUI(); // Update the UI.

} // End try

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;
}


/**
*
* If "IsVid" is true, the following function finds the video event that lies under the cursor
* on the selected track and shortens the END of this event.
* If "IsVid" is false, the following function finds the audio event immediately AFTER the
* audio event that lies under the cursor and shortens the BEGINNING of this event.
*
* By changing the one IF statement from "IsVid" to "!IsVid" the function will create the exact
* opposite effect, thus giving you a "J" cut instead of an "L" cut.
*
**/

function L_J_CutAtCursor(IsVid : boolean) {

var EventFound : boolean = false; // Function returns false if no video media under cursor.

dCursor = Vegas.Cursor.ToMilliseconds(); // Remember the cursor position.

while (!eventEnum.atEnd()) { // Go through each event on the track.
evnt = TrackEvent(eventEnum.item()); // Get next event
evnt.Selected = false; // De-select the event
dStart = evnt.Start.ToMilliseconds(); // Get the event's start and
dLength = evnt.Length.ToMilliseconds(); // length timecode, in milliseconds.

/**
* If the cursor timecode is between the beginning and end of the
* event timecodes, then we have found the event under the cursor.
**/

if ( (dCursor >= dStart) && ( dCursor < (dStart + dLength - dSlop) ) ) {

evnt.Selected = true; // Select this event.
EventFound = true; // Notify calling function that event was found

if (IsVid) { // Do one thing if this is video event, another if it is audio.
// if (!IsVid) { // Use this line rather than one above to change from L to J cut.
// Next line changes event length
evnt.AdjustStartLength(evnt.Start, evnt.Length - Timecode.FromSeconds(1), false);

}
else {
eventEnum.moveNext(); // Go to next event on this timeline.
evnt = TrackEvent(eventEnum.item()); // Next line changes event length
evnt.AdjustStartLength(evnt.Start + Timecode.FromSeconds(1), evnt.Length - Timecode.FromSeconds(1), false);

// error correction for Vegas-6b - for Vegas 5 delete this line
evnt.ActiveTake.Offset = evnt.ActiveTake.Offset + Timecode.FromSeconds(1);

}
} // End If dCursor (etc.)

eventEnum.moveNext(); // Go to next event on this timeline.
}

return EventFound;

}

Desktop: PC AMD 3960X, 24x3,8 Mhz * RTX 3080 Ti (12 GB)* Blackmagic Extreme 4K 12G * QNAP Max8 10 Gb Lan * Resolve Studio 18 * Edius X* Blackmagic Pocket 6K/6K Pro, EVA1, FS7

Laptop: ProArt Studiobook 16 OLED * internal HDR preview * i9 12900H with i-GPU Iris XE * 32 GB Ram) * Geforce RTX 3070 TI 8GB * internal HDR preview on the laptop monitor * Blackmagic Ultrastudio 4K mini

HDR monitor: ProArt Monitor PA32 UCG-K 1600 nits, Atomos Sumo

Others: Edius NX (Canopus NX)-card in an old XP-System. Edius 4.6 and other systems

Marco. wrote on 6/5/2005, 11:48 AM
Yes, this version works fine in V6.0b.

Thanks Wolfgang

Marco
johnmeyer wrote on 6/5/2005, 11:51 AM
Thanks, Wolfgang, for taking the time to fix the script.