Track Motion - Crete/Copy Keyframes

Jorge-Vegas wrote on 6/25/2023, 10:05 AM

>> Summary:
I need a script that will copy keyframes from a Track Motion and paste/clone them into different timecodes on the same track, eg timeline markers. (Keyframes are positional)

>> Clarifications:
1) As you can see in the image, I'm talking about "Track Motion" keyframes, and occasionally I'm only interested in position ones. In the image I mark it several times because when I searched for this problem on the internet I only got results of the "Motion Tracking" effect that has nothing to do with it. It is also often confused with the pan/crop options for video events.

2) In the image the Track Motion of Track 1 is open, but the script should work with any Track.

3) I don't need it to work with 3D tracks.

4) I've tried everything and got absolutely nothing, I couldn't even create a new keyframe or anything completely basic, so any help is welcome.

5) All the time I have been working in C# and saving the test files in ".cs" format because it is the only thing I have learned to do, without really knowing how to program, and it has helped me to create several useful scripts.

6) I've tried Vegasaur and it has a couple of options that by combining them I can achieve what I need, so it's proven to be possible, but it's still not practical for me and also I'm running out of time proof. What Vegasaur does is copy all the keyframes that are within a range and then you paste them (with another Vegasaur tool) in the timecodes where you position the cursor, you can even change the track (which I don't need) .

>> Sources of information that I have used:
> The closest thing I found on the internet for what I need is the following video, with which I am supposed to be able to obtain the information of a particular keyframe, I assumed that perhaps after obtaining said information I can use it to create new keyframes, but it is that I didn't even manage to get the mentioned info from any keyframe:
>I've read quite a bit of the Vegas Pro "Scripting FAQs" and "VEGAS Pro Scripting API Summary", which I got here:
https://www.vegascreativesoftware.info/us/forum/vegas-pro-scripting-faqs-resources--104563/

>> Some lines that I thought could help me from the API:
>”BaseTrackMotionKeyframe Class” (Base class for all track motion keyframes.)
>"BaseTrackMotionKeyframeList Class" (Base class for lists of track motion keyframes.)
> "TrackMotion Class"(Provides access to video track motion data.)
>"TrackMotionKeyframe Class" (Represents positional track motion keyframes.)
>"TrackMotionKeyframeList Class" (Represents a list of positional track motion keyframes.)
>"TrackMotionScaleFactors Class" (Represents the scale factors used when accessing the stored track motion keyframe data.)

>> Last words:
I've been all morning, around 12 hours trying things, I appreciate your help.

 

Comments

Robert Johnston wrote on 6/25/2023, 2:30 PM

@Jorge-Vegas

Here's another tutorial from JetDV that contains creating keyframes that might be of help to you.


 

Intel Core i7 10700K CPU @ 3.80GHz (to 4.65GHz), NVIDIA GeForce RTX 2060 SUPER 8GBytes. Memory 32 GBytes DDR4. Also Intel UHD Graphics 630. Mainboard: Dell Inc. PCI-Express 3.0 (8.0 GT/s) Comet Lake. Bench CPU Multi Thread: 5500.5 per CPU-Z.

Vegas Pro 21.0 (Build 108) with Mocha Vegas

Windows 11 not pro

jetdv wrote on 6/25/2023, 3:13 PM

Track Motion was a two part series:

It looks like you were referencing part one above. Adding keyframes for Track Motion would be the same as adding keyframes for Pan/Crop except they're added to the track instead of the event. The video linked by Robert is a good example of that. Here's another Pan/Crop sample:

And if you want to send me the exact specifics on what you're looking to do, I can create a new tutorial specifically for you. Of course, there's another way to do this:

  1. Click on the first keyframe
  2. Shift click on the last keyframe
  3. Press CTRL-C
  4. Move to where the new sequence is supposed to start
  5. Press CTRL-V

 

Jorge-Vegas wrote on 6/25/2023, 6:49 PM

@Jorge-Vegas

Here's another tutorial from JetDV that contains creating keyframes that might be of help to you.


I found that video in the list of videos on the jetdv channel but I entered it to watch it because the title and thumbnail made me understand that I would be working with video events, instead of motion track.  In any case, I just entered and I did not see that the script has created new keyframes, I have not tried to do it either because it happened to me that I manually transcribe the script that I see but some characters I do not distinguish.

Jorge-Vegas wrote on 6/25/2023, 7:14 PM

Track Motion was a two part series:

It looks like you were referencing part one above. Adding keyframes for Track Motion would be the same as adding keyframes for Pan/Crop except they're added to the track instead of the event. The video linked by Robert is a good example of that. Here's another Pan/Crop sample:

And if you want to send me the exact specifics on what you're looking to do, I can create a new tutorial specifically for you. Of course, there's another way to do this:

  1. Click on the first keyframe
  2. Shift click on the last keyframe
  3. Press CTRL-C
  4. Move to where the new sequence is supposed to start
  5. Press CTRL-V

 

Hi Edward, thanks for your response. 

     First of all, the keyboard shortcut method is the one I've been using for years, but now I need to repeat the process over 100 times, and as Vegas runs slower and slower I need to do it instantly with a script.

      Yes, I watched all of Part 1 and just a bit of Part 2 because it's for 3D tracks.  Regarding part 1, I copied and manually wrote the script you were using but still I am missing the first 9 lines that are not seen in the video, I tried to create them myself but I could not get the script to work, also this would only serve to get information from a keyframe, instead of copying it which is what I need.  

    I don't know if the video you shared about "Bounds" is useful for what I need, and also, although it sounds good that adding keyframes in track motion is similar to adding them in a pan/crop, I've never created a script with keyframes yet, so I'll be wrong for another 12 hours probably.  
    In short, what I need is for the script to copy the desired  keyframes (on a motion track) and paste them into each marker timecode in my project (within the same motion track), just like I do with keyboard shortcuts  that you mentioned. I'm mean position Keyframes

jetdv wrote on 6/25/2023, 8:15 PM

Here's a recent tutorial (please also look in the description):

and the original:

 

So, all keyframes before the first marker and duplicate them at each marker? Keeping the timing and values between them the same? Do you consider the "default" keyframe at the beginning of the timeline the "first keyframe" or only the ones after that. In other words, how will the script tell which markers to copy?

For the track, it's simple - only work on selected video tracks.

jetdv wrote on 6/26/2023, 3:07 PM

@Jorge-Vegas, Ok, when dealing with Track Motion keyframes, please make sure you are dealing with a VIDEO track (not just a "track"). Then you can add a new keyframe like this:

VideoTrack vTrack = (VideoTrack)myTrack;
TrackMotionKeyframe newKF = vTrack.TrackMotion.InsertMotionKeyframe(Timecode.FromSeconds(7));

Once you have "newKF", you can adjust the settings to match any other keyframe you wish. The above example adds a keyframe at the 7 second mark on the timeline.

Jorge-Vegas wrote on 6/26/2023, 3:33 PM

Here's a recent tutorial (please also look in the description):

and the original:

 

So, all keyframes before the first marker and duplicate them at each marker? Keeping the timing and values between them the same? Do you consider the "default" keyframe at the beginning of the timeline the "first keyframe" or only the ones after that. In other words, how will the script tell which markers to copy?

For the track, it's simple - only work on selected video tracks.

The first keyframe, the one that each track already includes, I don't have it in the tracks where I will apply the script, I always delete it. 

     What I need to do is to copy all the keyframes that are selected in the track motion, the distance (time) between them should be kept and they should keep all their properties, that is, the zoom and its rotation, and also the color of the keyframe. (i.e. the setting on how they will transition to the next keyframe, this is what gives keyframes their color, eg linear mode, jerky mode etc).

      These copied keyframes must be pasted at each timeline marker, the first keyframe of the "selected group" will be exactly on the marker timecode and the following keyframes of the group that were pasted must be separated from the first and between them the same time the original keyframes were separated. 

     In my projects, the original keyframes are usually anywhere, I need the script to identify which ones I have initially selected, but if it's difficult to do it this way, before executing the script I can move the original keyframes to the beginning, the second 0, that is, the keyframe that is furthest to the left would pass to it exactly at second 0 and the following ones will be separated from it the same as they were initially.  

    The latter would be in case the script can't detect "selected keyframes" and can only copy "all keyframes".  As I mentioned initially, I saw that Vegasaur detected which keyframes you wanted to copy from the active selection, that is, it copied all the keyframes of the active track that were between the start and end timecodes of the last selection (I mean the selection we make when we click and hold on an empty spot on the timeline and move the cursor, which "paints" the entire range light blue)

Jorge-Vegas wrote on 6/26/2023, 3:48 PM

@Jorge-Vegas, Ok, when dealing with Track Motion keyframes, please make sure you are dealing with a VIDEO track (not just a "track"). Then you can add a new keyframe like this:

VideoTrack vTrack = (VideoTrack)myTrack;
TrackMotionKeyframe newKF = vTrack.TrackMotion.InsertMotionKeyframe(Timecode.FromSeconds(7));

Once you have "newKF", you can adjust the settings to match any other keyframe you wish. The above example adds a keyframe at the 7 second mark on the timeline.

I understand, from now on I will express myself better by clarifying that I am talking about a video track.  Well, I'll try these lines that you shared with me shortly, although I still need to investigate how to copy the attributes of a keyframe (the original one) and how to put them on another keyframe (the new one), plus I need to figure out how to get the timecode where the keyframes are found to determine the distance between them and later calculate the time codes of the new keyframes.

jetdv wrote on 6/26/2023, 4:09 PM

I understood you were dealing with video tracks. However, most of my scripts go through "tracks" which can be video or audio. So I'd then do this to verify it's a selected video track:

if (myTrack.Selected && myTrack.IsVideo())

and then you must convert it to a "Video" track instead of a "generic" track in order to see the Track Motion keyframes as I did above:

VideoTrack vTrack = (VideoTrack)myTrack;

Then you start referencing "vTrack" instead of "myTrack" in order to work with the keyframes.

The keyframe.Position property is the timecode on the timeline. So what you need to do to get the new location, assuming it's based on the marker, would be something like:

newLocation = Marker.Position + keyframe.Position

Or if you have to offset the positioning of a "first keyframe" to the beginning (i.e. the first keyframe you want to copy isn't at the beginning of the timeline)

newLocation = Marker.Position + keyframe.Position - FirstKeyframe.Position

 

Jorge-Vegas wrote on 6/26/2023, 5:37 PM

@Jorge-Vegas, Ok, when dealing with Track Motion keyframes, please make sure you are dealing with a VIDEO track (not just a "track"). Then you can add a new keyframe like this:

VideoTrack vTrack = (VideoTrack)myTrack;
TrackMotionKeyframe newKF = vTrack.TrackMotion.InsertMotionKeyframe(Timecode.FromSeconds(7));

Once you have "newKF", you can adjust the settings to match any other keyframe you wish. The above example adds a keyframe at the 7 second mark on the timeline.

Well I just managed to create new keyframes. My script creates keyframes at each marker in my project and each of these keyframes takes the characteristics of the previous keyframe, just like when you click the "+◆" button it creates a keyframe with characteristics similar to the one in the left.

What I'm still trying to do is have the script detect which keyframes I've selected, copy their information, and place it in the new keyframes.

For now I have also managed to get the script to return information about a keyframe at a known location (for example, at the cursor position, at some specific marker, or at a specific second), or even to return information about a keyframe according to its position with respect to the others (I have expressed this last thing a little wrong, I mean that the script analyzes the keyframe that is the fourth, the seventh, or the one I tell it to)

I have not yet tested that the new keyframes get their characteristics from those keyframes that are in point locations because I still can't get the script to detect the keyframes that I have selected, it seems that "keyframe.Selected" or similar does not work, is there a function that detect selected keyframes?.

A question that has arisen to me now is if it will be necessary to tell the script to copy each and every one of the keyframe characteristics, telling it all one by one, or if there is a shortcut that includes all of them, will it be possible?

Jorge-Vegas wrote on 6/27/2023, 12:47 AM

Update: I've had more time to sit down and study and I've made a lot of progress, maybe I'll finish it tomorrow.  For now, I have managed to copy some properties of the keyframes that I want, create new ones and maintain their separation times.  I still need to create copies in all the markers and that all the attributes are copied and not just some.  

Thank you very much for the help!

jetdv wrote on 6/27/2023, 7:28 AM

Just copy over every property individually. You can pop that into a subroutine and pass it the source and destination keyframes and then let that one routine copy everything needed from the source to the destination.

The biggest difficulty is determining the "source" keyframes. The script can't tell if a keyframe is "selected". I suppose you could put a range around the ones you want copied and then all keyframes inside that range are the ones to be copied to each marker.