Putting an existing videotrack into a trackgroup

W-Music wrote on 1/8/2021, 4:54 PM

I am trying to achieve the following:

I have a trackgroup with one compositing parent and X amount of compositing children, so X+1 tracks. I want to give each of the children one compositing child of their own, to achieve an effect. All of this works, however there is some weird behavior at the bottom of the trackgroup.

When adding a track behind the trackgroup (index is one higher than last member of trackgroup) the track is not part of the trackgroup. This is as expected. It is supposed to be a compositing child however.

Setting the compositingNestingLevel does kind of work, but then the track is both a compositing child (with some weird UI glitches, and not all buttons functioning) and not in the trackgroup. This should not be.

My attempts at adding the track to the trackgroup have proved futile as well. As the Baselist "Add" function gives an error and the "InsertTrack(Track track, int Index)" function somehow moves one of the existing tracks of the trackgroup to the bottom instead of adding the given track.

Is there anyone with experience with this? A way to achieve it without ungrouping and selecting and grouping again?

Comments

jetdv wrote on 1/8/2021, 5:41 PM

Could you please include some screenshots to better describe what you are seeing/doing?

Generally speaking, to create a group of tracks, you just select a series of tracks (they must all be together) and then create a new track group with those tracks.

Step 1: select the tracks. Then:

myvegas.Project.GroupSelectedTracks(); // Group them
TrackGroup tg = myvegas.Project.TrackGroups[myvegas.Project.TrackGroups.Count - 1]; // Find the new "group"
tg.Name = "Track Group Name"; // Change the track group name

If you add a new track below a track and it is supposed to be a "child", you would have to tell the track to become a child after it is added. You would have to change it's CompositeNestingLevel after creation. Something like this to change the nesting level of tempchildtrack to one more that than videoTrack, the track above it in this case:

tempchildtrack.CompositeNestingLevel = videoTrack.CompositeNestingLevel + 1;

 

 

W-Music wrote on 1/9/2021, 2:29 AM

Hey thanks Ed, both of those things on their own I have already implemented. Sorry, I will be much more precise. The following is my code. It checks for a compositing child with my custom data in it. If not found it will create new tracks and make them compositing children. I have marked the important part via comments, about half way down.

public static int PrepareFXTrack(VideoTrack videoTrack, AnimationType animationType, Timecode startTime, Timecode endTime)
        {
            Vegas myVegas = vars.Vegas;
            VideoTrack fxVideoTrack = new VideoTrack();
            int indexOfFX = -1;
            int compositeNesting = videoTrack.CompositeNestingLevel;
            if (videoTrack.IsCompositingParent)
            {
                
                VideoTrack testTrack = myVegas.Project.Tracks[videoTrack.Index + 1] as VideoTrack;
                int childComposite = testTrack.CompositeNestingLevel;

                while (childComposite > compositeNesting && indexOfFX < 0)
                {
                    if (Convert.ToBoolean(testTrack.CustomData.GetObject(vars.fxGuid)))
                    {

                        // if FX track found
                        indexOfFX = testTrack.Index;
                        fxVideoTrack = testTrack;

                        // Check if FX track is already used
                        int eventInTimeframe = vars.GetIndexOfFirstEventInTimeFrame(fxVideoTrack, startTime, endTime);
                        if (eventInTimeframe >= 0)
                        {
                            return -1;
                        }
                        break;
                    }
                    testTrack = myVegas.Project.Tracks[testTrack.Index + 1] as VideoTrack;
                    childComposite = testTrack.CompositeNestingLevel;
                }
            }

            if (indexOfFX < 0)
            {
                fxVideoTrack = vars.CopyVideoTrack(videoTrack, false);

                // if trackgroup is wanted, but cant be found for new track, it is at bottom of one and needs to be added

                // MARKED CODE BEGINNING

                TrackGroup referenceTrackGroup = myVegas.Project.GetTrackGroupOfTrack(videoTrack.Index);

                if (referenceTrackGroup != null)
                {
                    TrackGroup testFXTrackGroup = myVegas.Project.GetTrackGroupOfTrack(fxVideoTrack.Index);
                    if (testFXTrackGroup == null)
                    {

                        // Debug MessageBox 1
                        myVegas.UpdateUI();
                        MessageBox.Show(fxVideoTrack.Name + " is last Track with index " + fxVideoTrack.Index.ToString());

                        referenceTrackGroup.InsertTrack(myVegas.Project.Tracks[fxVideoTrack.Index], -1);        // ?????????????????????

                        // Debug MessageBox 2
                        myVegas.UpdateUI();
                        MessageBox.Show("Inserted last Track");
                    }
                }
                // MARKED CODE END
                
            }
            if (vars.Debug) { MessageBox.Show("CopyVideoTrack done"); }

            // fxVideoTrack is now either a found and free or a newly copied one.
            fxVideoTrack.CompositeNestingLevel = compositeNesting + 1;

            // Create Media and add
            Media colorMedia = vars.GetColorMedia("White") ?? vars.GenerateColor("White");
            VideoEvent mediaEvent = fxVideoTrack.AddVideoEvent(startTime, endTime - startTime);
            mediaEvent.AddTake(colorMedia.GetVideoStreamByIndex(0));

            // Calculate factors and crop
            double target_factor = Convert.ToDouble(fxVideoTrack.CustomData.GetObject(vars.factorGuid));
            VideoMotionVertex scale_vertex = vars.GetScaleVertex(target_factor, (double)vars.ProjectSettings[0] / vars.ProjectSettings[1]);
            mediaEvent.VideoMotion.Keyframes[0].Type = VideoKeyframeType.Hold;
            mediaEvent.VideoMotion.Keyframes[0].ScaleBy(scale_vertex);

            // Copy Effects
            vars.CopyEffectsFromTrackInfo(mediaEvent);
            return fxVideoTrack.Index;
        }

 

I have marked the important code for you in the comments, as well as the line I tried to use to include the track in the trackgroup.

Here is a typical use case in minimal form. Trackgroup with a 2 by 2 videowall.

This is what happens when the function above is called to create an FX-Track (just another videotrack, where a background color lies). This is at the first debug MessageBox:

The Track has been added correctly. (The rest of the script around this function goes through the trackgroup in reverse order, so last track is added first.)

Name and Index are correct, so I am really attempting to insert the newly created track into the trackgroup. However this happens when Trackgroup.InserTrack() is called with a reference to this track:

(The script crashes afterwards since the change in order is unexpected behavior and messes something up.)

This is obviously not what I expected. Instead of just adding the track that I gave to the function it has somehow moved the second track (topmost compositing child) to the bottom. Does InsertTrack() not work with valid (IsValid()) tracks that are already in the project? Is the function just broken?

I have been daft a few times during this project of extension writing, so am I just a bit daft again? Did I overlook a function?

Here is what happens when the marked code is commented out and not part of the program:

This is the weird behaviour. By commenting it out I have now not even attempted to make it part of the trackgroup. Instead I just set its compositeNestingLevel. First of all it is one off, but that's not the weird one. The track above seems to KNOW that it should have been a compositing child, since the number (Track 9) is cut off. The UI definitely expects it to be its compositing child and the Burger-Button of Track 10 is not clickable for that reason. At the same time the Trackgroup ends at Track 9.

I hope that clears up what the issue is?

 

Edits: Made code clearer to read.

Also I have used "myVegas.Project.Tracks[fxVideoTrack.Index]" here but had also used "fxVideoTrack" before. This was just me trying out different tracks. But even trying to insert the track below it, the same behavior occurs, moving the same track down within the trackgroup.

W-Music wrote on 1/9/2021, 3:22 AM

Update:

I have achieved the result that I wanted. In what I would call a brazen abuse of the GroupSelectedTracks() function. The API describes it as "Create a new Trackgroup". However, by selecting just the last track of the Trackgroup and the Track I want to add and running this function it appears to fix the glitchy UI. It does not immediately show the track to be in the trackgroup, but after setting the compositeNestingLevel the trackgroup looks like desired. So I will call this a botch and just live with saving and resetting the users Track selection.