Searching If start or end boundaries were overtaken.

Thiago_Sase wrote on 8/27/2024, 8:31 AM

@jetdv Sir, please, Could you help me on this?
I need that the script will search through selected events if any event has overtaken, exceed their start and end (head and tail) boundaries. If yes, the script will tell me how many were found and will move them to the track above. If not, the script will tell me everything is ok.

I don't know the way to write the lines of code to the script identifies start or end boundaries.

Comments

jetdv wrote on 8/27/2024, 9:28 AM

For the beginning, if the evnt.ActiveTake.Offset != Timecode.FromFrames(0) then you know it does not start at the beginning of the media. However, you don't know if it's simply been "shortened" or has been extended left past the beginning. I suppose you might be able to compare the length using some sort of convoluted process to try and determine which.

As far as determining if it exceeds the end of the media, the only real tool you have is "length" so if the length exceeds the media, you know it's looping. However, that's not always true. What if a playback rate or velocity envelope has been applied, now the "length" has no bearing on where the actual end of the media is located.

I don't really recall an "easy" method of detecting the "media start and end" point as it relates to an event on the timeline.

Thiago_Sase wrote on 8/27/2024, 9:38 AM

@jetdv I watched this tutorial to be a guidance as reference;

And I tried this;

 

using System;
using System.Windows.Forms;
using ScriptPortal.Vegas;

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;

        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            int exceededBoundariesCount = 0;

            foreach (Track track in vegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        if (HasExceededBoundaries(evnt))
                        {
                            exceededBoundariesCount++;
                            MoveEventToTrackAbove(evnt, track, vegas);
                        }
                    }
                }
            }

            if (exceededBoundariesCount > 0)
            {
                MessageBox.Show(exceededBoundariesCount.ToString() + " event(s) found that exceeded boundaries and were moved to the track above.", "Boundaries Check");
            }
            else
            {
                MessageBox.Show("Everything is okay. No events have exceeded their boundaries.", "Boundaries Check");
            }
        }

        private bool HasExceededBoundaries(TrackEvent evnt)
        {
            Timecode mediaLength = evnt.ActiveTake.Media.Length;
            Timecode eventStart = evnt.Start;
            Timecode eventEnd = evnt.End;

            if (eventStart < Timecode.FromNanos(0) || eventEnd > mediaLength)
            {
                return true;
            }
            return false;
        }

        private void MoveEventToTrackAbove(TrackEvent evnt, Track currentTrack, Vegas vegas)
        {
            int trackIndex = -1;

            for (int i = 0; i < vegas.Project.Tracks.Count; i++)
            {
                if (vegas.Project.Tracks[i] == currentTrack)
                {
                    trackIndex = i;
                    break;
                }
            }

            if (trackIndex > 0)
            {
                Track trackAbove = vegas.Project.Tracks[trackIndex - 1];
                evnt.Track = trackAbove;
            }
            else
            {
                Track newTrack = new VideoTrack();
                vegas.Project.Tracks.Add(newTrack);
                evnt.Track = newTrack;
            }
        }
    }
}

public class EntryPoint
{
    public void FromVegas(Vegas vegas)
    {
        Test_Script.Class1 test = new Test_Script.Class1();
        test.Main(vegas);
    }
}

But it is not working as expected. It finds the events that have their boundaries overtaken, but is also detect other events like stretched ones.

But, now the script can find the ones who have their boundaries overtaken. So I can ignore the others one.

Thiago_Sase wrote on 8/27/2024, 9:40 AM

As far as determining if it exceeds the end of the media, the only real tool you have is "length" so if the length exceeds the media, you know it's looping. However, that's not always true. What if a playback rate or velocity envelope has been applied, now the "length" has no bearing on where the actual end of the media is located.

I don't really recall an "easy" method of detecting the "media start and end" point as it relates to an event on the timeline.

@jetdv Yes, Sir, I see it's more complex than I thought. Thank you for the information and for trying to help.

jetdv wrote on 8/27/2024, 9:47 AM

Ok, Frame Boundaries are a different story. If you don't have "Quantize to Frames" turned on, sometimes you can end up with an event that doesn't start or end (or both) on a frame boundary.

But that's a totally different story. Here's you another example. In this case, BOTH use the "full media" and do not exceed the media even though they are two different lengths on the timeline. The top one has simply been "slowed down".

jetdv wrote on 8/27/2024, 9:50 AM

And then you have this situation - does it "start" early? Or does it "end" late? I suppose it might not matter as it goes over a media "end point" either way.

Thiago_Sase wrote on 8/27/2024, 9:52 AM

@jetdv But if I select many events, the script does not work properly.

I can understand the complexity now.  I'm going to avoid this script, it's hard level for me at the moment.

Thank you Sir.
 

jetdv wrote on 8/27/2024, 9:52 AM

When dealing with playback rate changes, you can pretty well calculate what the new length "should" be as it's constant over the entire event. If it has a velocity envelope, it's much harder to calculate as the velocity can change over time and not necessarily in a "linear" fashion"

jetdv wrote on 8/27/2024, 10:02 AM

And this, definitely, won't tell you anything (and could explain why it's only "working" with the "first" selected event:

if (eventStart < Timecode.FromNanos(0) || eventEnd > mediaLength)

It appears you are checking to see if the event starts before the beginning of the timeline. and then if the event ends, ON THE TIMELINE a value greater than the media length. For the second part to come close to working, you'd have to compare the "Event LENGTH" to the media length, not the "END". And the first part will always be false because it will never start before the beginning of the timeline. You'd have to compare the "ActiveTake.Offset" to zero instead but, even then, if it's not zero that doesn't mean it's "beginning too early" - just that it's not starting at the beginning of the media.

Thiago_Sase wrote on 8/27/2024, 10:30 AM
using System;
using System.Windows.Forms;
using ScriptPortal.Vegas;

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;

        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            int exceededBoundariesCount = 0;
            int earlyStartCount = 0;

            foreach (Track track in vegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        if (HasExceededBoundaries(evnt))
                        {
                            exceededBoundariesCount++;
                            MoveEventToTrackAbove(evnt, track, vegas);
                        }

                        // Check if the event's start exceeds the media's start boundary
                        if (ExceedsStartBoundary(evnt))
                        {
                            earlyStartCount++;
                            MoveEventToTrackAbove(evnt, track, vegas);
                        }
                    }
                }
            }

            if (exceededBoundariesCount > 0 || earlyStartCount > 0)
            {
                MessageBox.Show(exceededBoundariesCount.ToString() + " event(s) exceeded end boundaries.\n" +
                                earlyStartCount.ToString() + " event(s) exceeded start boundaries and were moved to the track above.",
                                "Boundaries Check");
            }
            else
            {
                MessageBox.Show("Everything is okay. No events have exceeded their boundaries.", "Boundaries Check");
            }
        }

        private bool HasExceededBoundaries(TrackEvent evnt)
        {
            Take activeTake = evnt.ActiveTake;
            if (activeTake != null)
            {
                Timecode mediaLength = activeTake.Media.Length;
                Timecode eventLength = evnt.Length;
                double playbackRate = evnt.PlaybackRate;

                double eventLengthInSeconds = eventLength.ToMilliseconds() / 1000.0;
                double effectiveEventLengthInSeconds = eventLengthInSeconds / playbackRate;

                Timecode effectiveEventLength = Timecode.FromSeconds(effectiveEventLengthInSeconds);

                if (effectiveEventLength > mediaLength)
                {
                    return true;
                }
            }
            return false;
        }


        private bool ExceedsStartBoundary(TrackEvent evnt)
        {
            Take activeTake = evnt.ActiveTake;
            if (activeTake != null)
            {
                Timecode eventStart = evnt.Start;
                Timecode takeOffset = activeTake.Offset;


                if (eventStart < takeOffset)
                {
                    return true;
                }
            }
            return false;
        }

        private void MoveEventToTrackAbove(TrackEvent evnt, Track currentTrack, Vegas vegas)
        {
            int trackIndex = -1;

            for (int i = 0; i < vegas.Project.Tracks.Count; i++)
            {
                if (vegas.Project.Tracks[i] == currentTrack)
                {
                    trackIndex = i;
                    break;
                }
            }

            if (trackIndex > 0)
            {
                Track trackAbove = vegas.Project.Tracks[trackIndex - 1];
                evnt.Track = trackAbove;
            }
            else
            {
                Track newTrack = new VideoTrack();
                vegas.Project.Tracks.Add(newTrack);
                evnt.Track = newTrack;
            }
        }
    }

    public class EntryPoint
    {
        public void FromVegas(Vegas vegas)
        {
            Test_Script.Class1 test = new Test_Script.Class1();
            test.Main(vegas);
        }
    }
}

It improved the range, but far to be accurate.

Very hard one.