Merge Track & Delete Empty Tracks Script USEFUL

iEmby wrote on 8/19/2024, 8:36 AM

Hello @jetdv @zzzzzz9125 guys, how are u....

I am thinking about a script which can compress or clean our project by merging tracks and deleting empty tracks after considering some conditions.

First i want you guys understand what i mean on merge tracks. This script will be very useful but is very complicated

okay look what it should be done.
script should move events of a track to upper track if there is any empty space on upper track just like below

in this pic you can see only one event can't move on upper track bcoz that event has an event above it, but others can move bcoz there is empty space on upper track.

thats it this is the simple task of this script. but what is complication in this. that is conditions of movements.

  1. if upper track has track FX then do no move
  2. if upper track has compositing mode other than alpha then do no move
  3. if upper track has opacity value / level is less than 100 then do no move
  4. if upper track is a child track then do no move
  5. if upper track is parent track then do no move
  6. if upper track is adjustment track then do no move
  7. if upper track is mute / solo then do no move.
  8. if upper track has track motion data then default then do no move
  9. if upper track has any envelope with any value other than default value then do no move

and if the current track by self comes under one of above 9 points then do not move

(current track is from where event is moving to upper)

is this possible?

PROCESSOR
     

Operating System: Windows 11 Pro 64-bit (Always Updated)
System Manufacturer: ASUS
12th Gen Intel(R) Core(TM) i7-12700 (20 CPUs), ~2.1GHz - 4.90GHz
Memory: 32GB RAM
Page File: 11134MB used, 7934MB Available
DirectX Version: DirectX 12

-----------------------------------------------

MOTHERBOARD

 

ASUS PRIME H610-CS D4
Intel® H610 (LGA 1700)
Ready for 12th Gen Intel® Processors
Micro-ATX Motherboard with DDR4
Realtek 1 Gb Ethernet
PCH Heatsink
PCIe 4.0 | M.2 slot (32Gbps) 
HDMI® | D-Sub | USB 3.2 Gen 1 ports
SATA 6 Gbps | COM header
LPT header | TPM header
Luminous Anti-Moisture Coating
5X Protection III
(Multiple Hardware Safeguards
For all-round protection)

-----------------------------------------------
EXTERNAL GRAPHIC CARD

-----------------------------------------------

INTERNAL GRAPHIC CARD (iGPU)

------------------------------------------------

LED - MONITOR

Monitor Name: Generic PnP Monitor
Monitor Model: HP 22es
Monitor Id: HWP331B
Native Mode: 1920 x 1080(p) (60.000Hz)
Output Type: HDMI

-----------------------------------------------

STORAGE DRIVE

Drive: C:
Free Space: 182.3 GB
Total Space: 253.9 GB
File System: NTFS
Model: WD Blue SN570 1TB (NVMe)

---------------O----------------

My System Info (PDF File).

https://drive.google.com/open?id=1-eoLmuXzshTRH_8RunAYAuNocKpiLoiV&usp=drive_fs

 

Also Check

Some useful creations by me including VEGAS Scripts

https://getopensofts.blogspot.com/

 

My YouTube Channel Dedicated to Only VEGAS Pro Tutorials

EDITROOM : My YouTube Channel (For VEGAS Tutorials)

Comments

jetdv wrote on 8/19/2024, 9:03 AM

@iEmby, all of those conditions can be checked. Some will work with "Track" and work with both audio and video. Some will require "VideoTrack" and will only work with video.

  1. Track
  2. VideoTrack
  3. VideoTrack
  4. Track
  5. Track
  6. VideoTrack
  7. Track
  8. VideoTrack
  9. Track

Are you planning on only working with video tracks? Or will audio tracks be consolidated as well?

As you indicated, if there something on the "upper" track in the same location as what you're getting ready to move from the "lower" track you don't want to move it. If "one" event can't be moved, there's really no point in moving any of the events as you can't get rid of that track anyway. That would probably be the first thing I checked because of you have overlapping events and can't move them, there's really no point in checking the other conditions.

iEmby wrote on 8/19/2024, 9:12 AM

thanks for response sir..

Are you planning on only working with video tracks?

mainly i am planning for video tracks only yet but if it can be with audio then it will be good.

because of you have overlapping events and can't move them, there's really no point in checking the other conditions.

yes sir you are right .. thats a good catch.. but upper event can be move its own upper track so by this tracks can be empty

PROCESSOR
     

Operating System: Windows 11 Pro 64-bit (Always Updated)
System Manufacturer: ASUS
12th Gen Intel(R) Core(TM) i7-12700 (20 CPUs), ~2.1GHz - 4.90GHz
Memory: 32GB RAM
Page File: 11134MB used, 7934MB Available
DirectX Version: DirectX 12

-----------------------------------------------

MOTHERBOARD

 

ASUS PRIME H610-CS D4
Intel® H610 (LGA 1700)
Ready for 12th Gen Intel® Processors
Micro-ATX Motherboard with DDR4
Realtek 1 Gb Ethernet
PCH Heatsink
PCIe 4.0 | M.2 slot (32Gbps) 
HDMI® | D-Sub | USB 3.2 Gen 1 ports
SATA 6 Gbps | COM header
LPT header | TPM header
Luminous Anti-Moisture Coating
5X Protection III
(Multiple Hardware Safeguards
For all-round protection)

-----------------------------------------------
EXTERNAL GRAPHIC CARD

-----------------------------------------------

INTERNAL GRAPHIC CARD (iGPU)

------------------------------------------------

LED - MONITOR

Monitor Name: Generic PnP Monitor
Monitor Model: HP 22es
Monitor Id: HWP331B
Native Mode: 1920 x 1080(p) (60.000Hz)
Output Type: HDMI

-----------------------------------------------

STORAGE DRIVE

Drive: C:
Free Space: 182.3 GB
Total Space: 253.9 GB
File System: NTFS
Model: WD Blue SN570 1TB (NVMe)

---------------O----------------

My System Info (PDF File).

https://drive.google.com/open?id=1-eoLmuXzshTRH_8RunAYAuNocKpiLoiV&usp=drive_fs

 

Also Check

Some useful creations by me including VEGAS Scripts

https://getopensofts.blogspot.com/

 

My YouTube Channel Dedicated to Only VEGAS Pro Tutorials

EDITROOM : My YouTube Channel (For VEGAS Tutorials)

iEmby wrote on 8/19/2024, 9:46 AM

i created this via completely chat GPT help
but it is not running .. so its all on you sir.. when you will be free

using System;
using System.Collections.Generic;
using ScriptPortal.Vegas;

public class EntryPoint
{
    public void FromVegas(Vegas vegas)
    {
        MergeTracks(vegas);
    }

    private void MergeTracks(Vegas vegas)
    {
        // Get all video tracks
        var videoTracks = new List<Track>();
        foreach (var track in vegas.Project.Tracks)
        {
            if (track.GetType() == typeof(VideoTrack))
            {
                videoTracks.Add(track);
            }
        }

        // Process tracks from the lowest to the highest
        for (int i = videoTracks.Count - 1; i > 0; i--)
        {
            var currentTrack = videoTracks[i];
            var upperTrack = videoTracks[i - 1];

            // Check if the upper track is valid and if the current track is a child
            if (IsValidTrack(upperTrack) && IsChildTrack(currentTrack, videoTracks))
            {
                // Move events from the current track to the upper track
                MoveEvents(currentTrack, upperTrack);
            }
        }
    }

    private bool IsValidTrack(Track track)
    {
        // Check if the track is a video track and meets all conditions
        if (track.GetType() == typeof(VideoTrack))
        {
            return HasTrackFX(track) &&
                   HasEnvelopes(track) &&
                   IsCompositeLevelOne(track) &&
                   IsCompositeModeSrcAlpha(track) &&
                   IsParentTrack(track);
        }
        return false;
    }

    private bool IsChildTrack(Track track, List<Track> allTracks)
    {
        // Check if the track is a child track
        foreach (var potentialParent in allTracks)
        {
            if (potentialParent != track)
            {
                // Assuming tracks are ordered, check if current track is logically a child
                if (IsValidTrack(potentialParent) && allTracks.IndexOf(potentialParent) < allTracks.IndexOf(track))
                {
                    return true;
                }
            }
        }
        return false;
    }

    private bool IsParentTrack(Track track)
    {
        // For VEGAS Pro, this logic might need adjustment if parent-child relationships are managed differently
        // Assuming tracks are ordered, a track above is logically a parent
        return true;
    }

    private void MoveEvents(Track sourceTrack, Track destinationTrack)
    {
        if (sourceTrack.GetType() == typeof(VideoTrack) && destinationTrack.GetType() == typeof(VideoTrack))
        {
            var sourceVideoTrack = (VideoTrack)sourceTrack;
            var destinationVideoTrack = (VideoTrack)destinationTrack;

            // Iterate over events in the source track
            var eventsToMove = new List<TrackEvent>(sourceVideoTrack.Events);

            foreach (var e in eventsToMove)
            {
                // Check if there's no event directly above this event in the destination track
                bool hasEventAbove = false;
                foreach (var ev in destinationVideoTrack.Events)
                {
                    if (ev.Start < e.Start + e.Length && ev.Start + ev.Length > e.Start)
                    {
                        hasEventAbove = true;
                        break;
                    }
                }

                if (!hasEventAbove)
                {
                    // Duplicate the event and add it to the destination track
                    var newEvent = new VideoEvent(e.Start, e.Length);
                    destinationVideoTrack.Events.Add(newEvent);

                    // Remove the event from the source track
                    sourceVideoTrack.Events.Remove(e);
                }
            }
        }
    }

    private bool HasTrackFX(Track track)
    {
        return track.Effects.Count > 0;
    }

    private bool HasEnvelopes(Track track)
    {
        return track.Envelopes.Count > 0;
    }

    private bool IsCompositeLevelOne(Track track)
    {
        if (track.GetType() == typeof(VideoTrack))
        {
            var videoTrack = (VideoTrack)track;
            const float levelThreshold = 0.0001f;
            return Math.Abs(videoTrack.CompositeLevel - 1.0f) < levelThreshold;
        }
        return false;
    }

    private bool IsCompositeModeSrcAlpha(Track track)
    {
        if (track.GetType() == typeof(VideoTrack))
        {
            var videoTrack = (VideoTrack)track;
            return videoTrack.CompositeMode == CompositeMode.SrcAlpha;
        }
        return false;
    }
}



 

PROCESSOR
     

Operating System: Windows 11 Pro 64-bit (Always Updated)
System Manufacturer: ASUS
12th Gen Intel(R) Core(TM) i7-12700 (20 CPUs), ~2.1GHz - 4.90GHz
Memory: 32GB RAM
Page File: 11134MB used, 7934MB Available
DirectX Version: DirectX 12

-----------------------------------------------

MOTHERBOARD

 

ASUS PRIME H610-CS D4
Intel® H610 (LGA 1700)
Ready for 12th Gen Intel® Processors
Micro-ATX Motherboard with DDR4
Realtek 1 Gb Ethernet
PCH Heatsink
PCIe 4.0 | M.2 slot (32Gbps) 
HDMI® | D-Sub | USB 3.2 Gen 1 ports
SATA 6 Gbps | COM header
LPT header | TPM header
Luminous Anti-Moisture Coating
5X Protection III
(Multiple Hardware Safeguards
For all-round protection)

-----------------------------------------------
EXTERNAL GRAPHIC CARD

-----------------------------------------------

INTERNAL GRAPHIC CARD (iGPU)

------------------------------------------------

LED - MONITOR

Monitor Name: Generic PnP Monitor
Monitor Model: HP 22es
Monitor Id: HWP331B
Native Mode: 1920 x 1080(p) (60.000Hz)
Output Type: HDMI

-----------------------------------------------

STORAGE DRIVE

Drive: C:
Free Space: 182.3 GB
Total Space: 253.9 GB
File System: NTFS
Model: WD Blue SN570 1TB (NVMe)

---------------O----------------

My System Info (PDF File).

https://drive.google.com/open?id=1-eoLmuXzshTRH_8RunAYAuNocKpiLoiV&usp=drive_fs

 

Also Check

Some useful creations by me including VEGAS Scripts

https://getopensofts.blogspot.com/

 

My YouTube Channel Dedicated to Only VEGAS Pro Tutorials

EDITROOM : My YouTube Channel (For VEGAS Tutorials)

bvideo wrote on 8/19/2024, 10:03 AM

If there is a transition between events N & N+1 on a lower track, but one of them is blocked by an event on the upper track ...

jetdv wrote on 8/19/2024, 11:19 AM

First of all, simplify things. You don't need (and it's multiple places in your script):

if (track.GetType() == typeof(VideoTrack))

Just use:

if (track.IsVideo())

I'm not sure what the IsChildTrack routine is supposed to be doing. If you want to check to see if a track is a child track and return "true" if it is not:

    private bool IsChildTrack(Track track)
    {
        // Check if the track is a child track
        if (track.IsVideo())
        {
            VideoTrack vidTrack = (VideoTrack)track;
            if (!vidTrack.IsCompositingChild)
            {
                return true;
            }
        }
        return false;
    }

It seem counter-intuitive to me, though, that you're returning "true" when it is NOT the case instead of returning true when it IS the case.

Does it have effects? No so return true???

I sort of understand where you're coming from in that all the "trues" means you can move but It makes more sense to me that "Does it have effects?" No = FALSE and then check for "Not - has effects" instead.

And when you say "doesn't work", what, exactly, does that mean?

You can try taking out some of the checks and then add them back in one at a time to see which one(s) is failing.

iEmby wrote on 8/22/2024, 6:19 AM

@jetdv i completed it sir.. thanks for your guidance.

using System;
using System.Collections.Generic;
using ScriptPortal.Vegas;

public class EntryPoint
{
    public void FromVegas(Vegas vegas)
    {
        MergeTracks(vegas);
        DeleteEmptyTracks(vegas);
    }

    private void MergeTracks(Vegas vegas)
    {
        // Get all video tracks
        var videoTracks = new List<Track>();
        foreach (var track in vegas.Project.Tracks)
        {
            if (track.IsVideo())
            {
                videoTracks.Add(track);
            }
        }

        // Process tracks from the lowest to the highest
        for (int i = videoTracks.Count - 1; i > 0; i--)
        {
            var currentTrack = videoTracks[i];
            var upperTrack = videoTracks[i - 1];

            // Check if both the current track and the upper track are valid
            if (IsValidTrack(currentTrack) && IsValidTrack(upperTrack))
            {
                // Move events from the current track to the upper track
                MoveEvents(currentTrack, upperTrack);
            }
        }
    }

    private bool IsValidTrack(Track track)
    {
        // Check if the track is a video track and meets all conditions
        if (track.IsVideo())
        {
            var videoTrack = (VideoTrack)track;

            return !HasTrackFX(track) &&
                   !HasEnvelopes(track) &&
                   IsCompositeLevelOne(track) &&
                   IsCompositeModeSrcAlpha(track) &&
                   !IsMuted(track) &&
                   !IsSoloed(track) &&
                   !IsAdjustmentTrack(track) &&
                   !videoTrack.IsCompositingChild && // Ensure track is not a child
                   !videoTrack.IsCompositingParent; // Ensure track is a parent
        }
        return false;
    }

    private void MoveEvents(Track sourceTrack, Track destinationTrack)
    {
        if (sourceTrack.IsVideo() && destinationTrack.IsVideo())
        {
            var sourceVideoTrack = (VideoTrack)sourceTrack;
            var destinationVideoTrack = (VideoTrack)destinationTrack;

            // Iterate over events in the source track
            var eventsToMove = new List<TrackEvent>(sourceVideoTrack.Events);

            foreach (var e in eventsToMove)
            {
                // Check if there's no event directly above this event in the destination track
                bool hasEventAbove = false;
                foreach (var ev in destinationVideoTrack.Events)
                {
                    if (ev.Start < e.Start + e.Length && ev.Start + ev.Length > e.Start)
                    {
                        hasEventAbove = true;
                        break;
                    }
                }

                if (!hasEventAbove)
                {
                    // Copy the event to the destination track at the same start position
                    var copiedEvent = e.Copy(destinationVideoTrack, e.Start);

                    // Remove the event from the source track
                    sourceVideoTrack.Events.Remove(e);
                }
            }
        }
    }

    private bool HasTrackFX(Track track)
    {
        return track.Effects.Count > 0;
    }

    private bool HasEnvelopes(Track track)
    {
        return track.Envelopes.Count > 0;
    }

    private bool IsCompositeLevelOne(Track track)
    {
        if (track.IsVideo())
        {
            var videoTrack = (VideoTrack)track;
            const float levelThreshold = 0.0001f;
            return Math.Abs(videoTrack.CompositeLevel - 1.0f) < levelThreshold;
        }
        return false;
    }

    private bool IsCompositeModeSrcAlpha(Track track)
    {
        if (track.IsVideo())
        {
            var videoTrack = (VideoTrack)track;
            return videoTrack.CompositeMode == CompositeMode.SrcAlpha;
        }
        return false;
    }

    private bool IsMuted(Track track)
    {
        // Check if the track is muted
        return track.Mute;
    }

    private bool IsSoloed(Track track)
    {
        // Check if the track is soloed
        return track.Solo;
    }
    private void DeleteEmptyTracks(Vegas vegas)
    {
        List<Track> tracksToDelete = new List<Track>();
        foreach (Track track in vegas.Project.Tracks)
        {
            // Check if the track is not an adjustment track and has no events
            if (!IsAdjustmentTrack(track) && track.Events.Count == 0)
            {
                // Check if the track is a video track
                if (track.IsVideo())
                {
                    VideoTrack vTrack = (VideoTrack)track;

                    // Check if the track is a compositing parent or a compositing child
                    if (vTrack.IsCompositingParent || vTrack.IsCompositingChild)
                    {
                        // Skip deletion for compositing parent and child tracks
                        continue;
                    }
                }

                // Check if it's an adjustment track
                if (IsAdjustmentTrack(track))
                {
                    // Skip deletion for adjustment tracks, even if they are empty
                    continue;
                }

                tracksToDelete.Add(track);
            }
        }

        // Delete the tracks from the project
        foreach (Track trackToDelete in tracksToDelete)
        {
            vegas.Project.Tracks.Remove(trackToDelete);
        }

        RemoveEmptyAudioTracks(vegas);
    }

    private bool IsAdjustmentTrack(Track track)
    {
        // Check if the track is a video track and is an adjustment track
        return track.IsVideo() && ((VideoTrack)track).IsAdjustmentTrack;
    }

    private void RemoveEmptyAudioTracks(Vegas vegas)
    {
        List<AudioTrack> emptyAudioTracks = new List<AudioTrack>();

        // Iterate through all tracks
        foreach (Track track in vegas.Project.Tracks)
        {
            if (track.IsAudio() && track.Events.Count == 0)
            {
                emptyAudioTracks.Add((AudioTrack)track);
            }
        }

        // Remove the empty audio tracks
        foreach (AudioTrack audioTrackToRemove in emptyAudioTracks)
        {
            vegas.Project.Tracks.Remove(audioTrackToRemove);
        }
    }
}

 

PROCESSOR
     

Operating System: Windows 11 Pro 64-bit (Always Updated)
System Manufacturer: ASUS
12th Gen Intel(R) Core(TM) i7-12700 (20 CPUs), ~2.1GHz - 4.90GHz
Memory: 32GB RAM
Page File: 11134MB used, 7934MB Available
DirectX Version: DirectX 12

-----------------------------------------------

MOTHERBOARD

 

ASUS PRIME H610-CS D4
Intel® H610 (LGA 1700)
Ready for 12th Gen Intel® Processors
Micro-ATX Motherboard with DDR4
Realtek 1 Gb Ethernet
PCH Heatsink
PCIe 4.0 | M.2 slot (32Gbps) 
HDMI® | D-Sub | USB 3.2 Gen 1 ports
SATA 6 Gbps | COM header
LPT header | TPM header
Luminous Anti-Moisture Coating
5X Protection III
(Multiple Hardware Safeguards
For all-round protection)

-----------------------------------------------
EXTERNAL GRAPHIC CARD

-----------------------------------------------

INTERNAL GRAPHIC CARD (iGPU)

------------------------------------------------

LED - MONITOR

Monitor Name: Generic PnP Monitor
Monitor Model: HP 22es
Monitor Id: HWP331B
Native Mode: 1920 x 1080(p) (60.000Hz)
Output Type: HDMI

-----------------------------------------------

STORAGE DRIVE

Drive: C:
Free Space: 182.3 GB
Total Space: 253.9 GB
File System: NTFS
Model: WD Blue SN570 1TB (NVMe)

---------------O----------------

My System Info (PDF File).

https://drive.google.com/open?id=1-eoLmuXzshTRH_8RunAYAuNocKpiLoiV&usp=drive_fs

 

Also Check

Some useful creations by me including VEGAS Scripts

https://getopensofts.blogspot.com/

 

My YouTube Channel Dedicated to Only VEGAS Pro Tutorials

EDITROOM : My YouTube Channel (For VEGAS Tutorials)

jetdv wrote on 8/22/2024, 8:28 AM

@iEmby why are you handling audio tracks separate from video tracks for removal? Both can be handled just fine in DeleteEmptyTracks. In fact, just scanning the video checking part, it appears that audio tracks may already be being removed before calling the RemoveEmptyAudioTracks routine? Remove this line and see if the audio is already gone after running it:

RemoveEmptyAudioTracks(vegas);

I always aim for simplicity. Let's look at this routine:

        private void RemoveEmptyAudioTracks(Vegas vegas)
        {
            List<AudioTrack> emptyAudioTracks = new List<AudioTrack>();

            // Iterate through all tracks
            foreach (Track track in vegas.Project.Tracks)
            {
                if (track.IsAudio() && track.Events.Count == 0)
                {
                    emptyAudioTracks.Add((AudioTrack)track);
                }
            }

            // Remove the empty audio tracks
            foreach (AudioTrack audioTrackToRemove in emptyAudioTracks)
            {
                vegas.Project.Tracks.Remove(audioTrackToRemove);
            }
        }

We can get rid of all the "list" stuff and just do this - because you're removing tracks, you DO need to go "backwards":

        private void RemoveEmptyAudioTracks(Vegas vegas)
        {
            for (int i = vegas.Project.Tracks.Count - 1; i >= 0; i--)
            {
                Track track = vegas.Project.Tracks[i];

                if (track.IsAudio() && track.Events.Count == 0)
                {
                    vegas.Project.Tracks.Remove(track);
                }
            }
        }

 

iEmby wrote on 8/22/2024, 9:39 PM

agreed sir,, but separate because. if there will be an video track which has fx but no event will be not deleted bcoz it can be an adjustment track.

but if there will be an audio track which has FX and no audio event then even it will be deleted.

thats why i did that..

but you are right.

may be i should just skip 'Adjustment Tracks' from delete empty tracks

PROCESSOR
     

Operating System: Windows 11 Pro 64-bit (Always Updated)
System Manufacturer: ASUS
12th Gen Intel(R) Core(TM) i7-12700 (20 CPUs), ~2.1GHz - 4.90GHz
Memory: 32GB RAM
Page File: 11134MB used, 7934MB Available
DirectX Version: DirectX 12

-----------------------------------------------

MOTHERBOARD

 

ASUS PRIME H610-CS D4
Intel® H610 (LGA 1700)
Ready for 12th Gen Intel® Processors
Micro-ATX Motherboard with DDR4
Realtek 1 Gb Ethernet
PCH Heatsink
PCIe 4.0 | M.2 slot (32Gbps) 
HDMI® | D-Sub | USB 3.2 Gen 1 ports
SATA 6 Gbps | COM header
LPT header | TPM header
Luminous Anti-Moisture Coating
5X Protection III
(Multiple Hardware Safeguards
For all-round protection)

-----------------------------------------------
EXTERNAL GRAPHIC CARD

-----------------------------------------------

INTERNAL GRAPHIC CARD (iGPU)

------------------------------------------------

LED - MONITOR

Monitor Name: Generic PnP Monitor
Monitor Model: HP 22es
Monitor Id: HWP331B
Native Mode: 1920 x 1080(p) (60.000Hz)
Output Type: HDMI

-----------------------------------------------

STORAGE DRIVE

Drive: C:
Free Space: 182.3 GB
Total Space: 253.9 GB
File System: NTFS
Model: WD Blue SN570 1TB (NVMe)

---------------O----------------

My System Info (PDF File).

https://drive.google.com/open?id=1-eoLmuXzshTRH_8RunAYAuNocKpiLoiV&usp=drive_fs

 

Also Check

Some useful creations by me including VEGAS Scripts

https://getopensofts.blogspot.com/

 

My YouTube Channel Dedicated to Only VEGAS Pro Tutorials

EDITROOM : My YouTube Channel (For VEGAS Tutorials)