Reverse (rewind) at Cursor Position Split with one click!

Thiago_Sase wrote on 2/1/2025, 4:12 PM

Hello, this script could be useful for someone. 

* Select the event;

* Set the cursor position;

* run the script.
 

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

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;

        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            SplitEventAtCursorPosition();
            ReverseEvent();
            ExtendEventToTheRighSide();
            SelectAndCalculateAndMoveCursorPositionAndTimecodeReverse();
            SplitEventAtCursorPosition2();
        }

        private void SplitEventAtCursorPosition()
        {
            Timecode cursorPosition = myVegas.Transport.CursorPosition;

            foreach (Track myTrack in myVegas.Project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected && evnt.Start < cursorPosition && evnt.End > cursorPosition)
                        {
                            Timecode splitPoint = cursorPosition - evnt.Start;
                            TrackEvent rightEvent = evnt.Split(splitPoint);

                            // Deselect the left event and select only the right event
                            evnt.Selected = false;
                            rightEvent.Selected = true;

                            return; // Stop after splitting
                        }
                    }
                }
            }
        }


        private void ReverseEvent()
        {
            
            if (myVegas.Project == null || myVegas.Project.Tracks.Count == 0)
            {
                MessageBox.Show("No tracks found in the project.");
                return;
            }

            foreach (Track track in myVegas.Project.Tracks)
            {
                if (track.IsVideo())
                {
                    foreach (TrackEvent evnt in track.Events)
                    {
                        if (evnt.Selected)
                        {
                            Take activeTake = evnt.ActiveTake;
                            if (activeTake != null && activeTake.Media != null)
                            {
                                string mediaPath = activeTake.MediaPath;
                                if (string.IsNullOrEmpty(mediaPath) || !File.Exists(mediaPath))
                                {
                                    MessageBox.Show("Media file not found.");
                                    continue;
                                }

                                // Create a reversed subclip
                                Subclip subclip = new Subclip(
                                    myVegas.Project,
                                    mediaPath,
                                    new Timecode(),
                                    activeTake.MediaStream.Length,
                                    true,  // Reverse = true
                                    Path.GetFileNameWithoutExtension(mediaPath) + "_reversed"
                                );

                                // Get the reversed video stream
                                MediaStream reversedStream = subclip.Streams.GetItemByMediaType(MediaType.Video, 0);
                                if (reversedStream == null)
                                {
                                    MessageBox.Show("Failed to create reversed stream.");
                                    continue;
                                }

                                // Replace the active take with the reversed take
                                evnt.Takes.Clear();  // Remove existing takes
                                evnt.Takes.Add(new Take(reversedStream)); // Add the reversed take
                            }
                        }
                    }
                }
            }
        }


        private void ExtendEventToTheRighSide()
        {
            if (myVegas.Project == null)
            {
                MessageBox.Show("No project is open.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            TrackEvent selectedEvent = null;
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        selectedEvent = evnt;
                        break;
                    }
                }
                if (selectedEvent != null)
                    break;
            }

            if (selectedEvent == null)
            {
                MessageBox.Show("No event selected!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Take activeTake = selectedEvent.ActiveTake;
            if (activeTake == null)
            {
                MessageBox.Show("The selected event has no active take!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Media media = activeTake.Media;
            if (media == null || media.Length == Timecode.FromSeconds(0))
            {
                MessageBox.Show("Invalid media!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Get the take's offset within the media
            Timecode takeOffset = activeTake.Offset;
            Timecode mediaEnd = media.Length;

            // Calculate the maximum possible event length
            Timecode maxLength = mediaEnd - takeOffset;

            // Extend the event length if possible
            if (selectedEvent.Length < maxLength)
            {
                selectedEvent.Length = maxLength;
            }
            else
            {
                MessageBox.Show("Event is already at maximum length!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }


        private void SelectAndCalculateAndMoveCursorPositionAndTimecodeReverse()
        {
            // Step 1: Deselect all events
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    evnt.Selected = false;
                }
            }

            TrackEvent closestLeftEvent = null;
            Timecode cursorPosition = myVegas.Transport.CursorPosition;
            double leftEventDuration = 0; // Store duration for Step 4

            // Step 2: Find the first event to the left of the cursor
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.End <= cursorPosition) // Ensure event is completely to the left
                    {
                        if (closestLeftEvent == null || evnt.End > closestLeftEvent.End)
                        {
                            closestLeftEvent = evnt;
                        }
                    }
                }
            }

            if (closestLeftEvent != null)
            {
                closestLeftEvent.Selected = true;

                // Get original event duration before trimming
                leftEventDuration = (closestLeftEvent.ActiveTake.Offset + closestLeftEvent.Length).ToMilliseconds() / 1000.0;

                // Convert to whole seconds and frames
                int fps = (int)Math.Round(myVegas.Project.Video.FrameRate);
                int wholeSeconds = (int)leftEventDuration;
                int frames = (int)Math.Round((leftEventDuration - wholeSeconds) * fps);

                /*

                MessageBox.Show("Selected event duration: " + wholeSeconds + " seconds and " + frames + " frames",
                                "Event Duration",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);

                */
            }



            // Step 3: Deselect the current event and select the first event to the right
            if (closestLeftEvent != null)
            {
                closestLeftEvent.Selected = false;
            }

            TrackEvent closestRightEvent = null;

            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Start >= cursorPosition) // Ensure event is to the right
                    {
                        if (closestRightEvent == null || evnt.Start < closestRightEvent.Start)
                        {
                            closestRightEvent = evnt;
                        }
                    }
                }
            }

            // Step 3.5: Select the found right event and move the cursor to its end
            if (closestRightEvent != null)
            {
                closestRightEvent.Selected = true;
                myVegas.Transport.CursorPosition = closestRightEvent.End;

                // Step 4: Move the cursor BACKWARDS by the duration of the first selected event
                myVegas.Transport.CursorPosition -= Timecode.FromSeconds(leftEventDuration);
            }
        }

        private void SplitEventAtCursorPosition2()
        {
            Timecode cursorPosition = myVegas.Transport.CursorPosition;

            foreach (Track myTrack in myVegas.Project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected && evnt.Start < cursorPosition && evnt.End > cursorPosition)
                        {
                            Timecode splitPoint = cursorPosition - evnt.Start;
                            TrackEvent rightEvent = evnt.Split(splitPoint);

                            // Deselect the right event and select only the left event
                            evnt.Selected = true;
                            rightEvent.Selected = false;

                            // Delete the selected event (which is the left event)
                            myTrack.Events.Remove(evnt);

                            // Select the first event on the right side of the cursor position
                            TrackEvent selectedEvent = null;
                            foreach (TrackEvent nextEvent in myTrack.Events)
                            {
                                if (nextEvent.Start >= cursorPosition)
                                {
                                    nextEvent.Selected = true;
                                    selectedEvent = nextEvent;
                                    break; // Stop at the first event found
                                }
                            }

                            // Move the selected event to the left until it reaches the first event
                            if (selectedEvent != null)
                            {
                                Timecode newPosition = Timecode.FromSeconds(0); // Start position
                                foreach (TrackEvent firstEvent in myTrack.Events)
                                {
                                    if (firstEvent != selectedEvent && firstEvent.Start < selectedEvent.Start)
                                    {
                                        newPosition = firstEvent.End;
                                    }
                                }

                                // Move the event to the left of the cursor position
                                selectedEvent.Start = newPosition;

                                // Final Step: Move cursor position to the start of the selected event
                                myVegas.Transport.CursorPosition = selectedEvent.Start;
                            }

                            return; // Stop after all steps
                        }
                    }
                }
            }
        }






    }
}

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

 

Comments

Steve_Rhoden wrote on 2/2/2025, 6:43 AM

Great script contribution as usual.... What would be impressive is if this script could simply just reverse the entire selected event without the split with one selection, and then with another selection undo the reverse. (Just wishful thinking i guess) lol.

jetdv wrote on 2/2/2025, 7:31 AM

@Steve_Rhoden

Then just press "T" to switch between the two takes - forward and backward

Thiago_Sase wrote on 2/2/2025, 11:29 AM

@Steve_Rhoden Thank you.

What would be impressive is if this script could simply just reverse the entire selected event without the split with one selection, and then with another selection undo the reverse. (Just wishful thinking i guess) lol.

Could you make a video example for a better understanding? I can practice until find the desired result.

Thiago_Sase wrote on 2/2/2025, 11:30 AM

@jetdv Nice tip, Sir. Watching the full video lesson. Thanks.

Steve_Rhoden wrote on 2/3/2025, 2:26 AM

@Thiago_Sase

I just meant press the script once, it reverse the entire selected event. Press it again and it undo the reverse.

Thiago_Sase wrote on 2/3/2025, 6:08 AM

@Steve_Rhoden Thank you, my friend. I'll change the code and practice the next days that toggle reverse /undo reverse. When is done, I post here. 

Steve_Rhoden wrote on 2/3/2025, 7:42 AM

👌

jetdv wrote on 2/3/2025, 7:45 AM

@Steve_Rhoden I think you'll find the tutorial does what you want and you can switch back an forth just by pressing "T" to change "takes". The original take will be "forward" and the second take will be "reversed". As reversing creates a sub-clip, it makes more sense to just use "T" to switch between takes.

Thiago_Sase wrote on 3/10/2025, 2:36 PM

Rewind Event update 2;

This script is about to emulate a Rewind effect at cursor position. It's not the traditional Reverse.

* Some bugs fixed;

* Added some warnings messages for better workflow with the script;

* Added the "Un-Rewind" effect if the selected event already has the Rewind Effect.

How to use;

* Select the event;

* Set the cursor position;

* run the script.

* If you want to Undo the Rewind effect, just select the event that was split and run the script again. Like toggle Rewind and non-Rewind.

Here's the code;

using System;
using System.IO;
using System.Collections.Generic;
using System.Windows.Forms;
using ScriptPortal.Vegas;

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;

        private double eventDurationSeconds;
        private int eventDurationFrames;

        private List<Timecode> exceededDurations = new List<Timecode>(); // Store exceeded durations

        public void Main(Vegas vegas)
        {
            myVegas = vegas;

            TrackEvent selectedEvent = GetSelectedEvent();

            if (selectedEvent != null)
            {
                if (IsEventReversed(selectedEvent)) // Check if the event has the reverse effect
                {
                    UnRewindEvent(vegas);
                }
                else
                {
                    RewindEvent(vegas);
                }
            }
            else
            {
                MessageBox.Show("No event selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private bool IsEventReversed(TrackEvent evnt)
        {
            if (evnt.ActiveTake != null)
            {
                string takeName = evnt.ActiveTake.Name;
                return takeName.ToLower().Contains("reversed");
            }
            return false;
        }

        public void RewindEvent(Vegas vegas)
        {
            myVegas = vegas;

            // Stop execution if playback rate is altered
            if (this.ShowMessagePlaybackrateisaltered())
            {
                return;
            }

            // Stop execution if the selected event is grouped
            if (this.ShowMessageIfEventIsGrouped())
            {
                return;
            }

            // Stop execution if there is an event in the track above
            if (this.ShowMessageIfThereIsAnEventOnTheTrackAbove())
            {
                return;
            }

            SplitEventAtCursorPosition();
            ReverseEvent();
            SelectEventInTheRightSide();
            ExtendEventToTheRighSide();
            SelectAndCalculateAndMoveCursorPositionAndTimecodeReverse();
            SplitEventAtCursorPosition2();
            UngroupSelectedEvents();
        }

        public void UnRewindEvent(Vegas myVegas)
        {
            CalculateTheSelectedEventDuration(myVegas);
            DeleteEvent(myVegas);
            DeselectAllEvents(myVegas);
            SelectFirstEventInTheLeftSide(myVegas);
            ExtendEvent(myVegas);
            CalculateExceededDuration(myVegas);
            TrimTailEvent(myVegas);
        }

        private TrackEvent GetSelectedEvent()
        {
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        return evnt; // Return the first selected event
                    }
                }
            }
            return null;
        }

        private void SplitEventAtCursorPosition()
        {
            Timecode cursorPosition = myVegas.Transport.CursorPosition;

            foreach (Track myTrack in myVegas.Project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected && evnt.Start < cursorPosition && evnt.End > cursorPosition)
                        {
                            Timecode splitPoint = cursorPosition - evnt.Start;
                            TrackEvent rightEvent = evnt.Split(splitPoint);

                            // Deselect the left event and select only the right event
                            evnt.Selected = false;
                            rightEvent.Selected = true;

                            return; // Stop after splitting
                        }
                    }
                }
            }
        }

        private void ReverseEvent()
        {

            if (myVegas.Project == null || myVegas.Project.Tracks.Count == 0)
            {
                MessageBox.Show("No tracks found in the project.");
                return;
            }

            foreach (Track track in myVegas.Project.Tracks)
            {
                if (track.IsVideo())
                {
                    foreach (TrackEvent evnt in track.Events)
                    {
                        if (evnt.Selected)
                        {
                            Take activeTake = evnt.ActiveTake;
                            if (activeTake != null && activeTake.Media != null)
                            {
                                string mediaPath = activeTake.MediaPath;
                                if (string.IsNullOrEmpty(mediaPath) || !File.Exists(mediaPath))
                                {
                                    MessageBox.Show("Media file not found.");
                                    continue;
                                }

                                // Create a reversed subclip
                                Subclip subclip = new Subclip(
                                    myVegas.Project,
                                    mediaPath,
                                    new Timecode(),
                                    activeTake.MediaStream.Length,
                                    true,  // Reverse = true
                                    Path.GetFileNameWithoutExtension(mediaPath) + "_reversed"
                                );

                                // Get the reversed video stream
                                MediaStream reversedStream = subclip.Streams.GetItemByMediaType(MediaType.Video, 0);
                                if (reversedStream == null)
                                {
                                    MessageBox.Show("Failed to create reversed stream.");
                                    continue;
                                }

                                // Replace the active take with the reversed take
                                evnt.Takes.Clear();  // Remove existing takes
                                evnt.Takes.Add(new Take(reversedStream)); // Add the reversed take
                            }
                        }
                    }
                }
            }
        }

        private void SelectEventInTheRightSide()
        {
            // Step 1: Deselect all events
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    evnt.Selected = false;
                }
            }

            TrackEvent closestLeftEvent = null;
            Timecode cursorPosition = myVegas.Transport.CursorPosition;

            // Step 3: Deselect the current event and select the first event to the right
            if (closestLeftEvent != null)
            {
                closestLeftEvent.Selected = false;
            }

            TrackEvent closestRightEvent = null;

            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Start >= cursorPosition) // Ensure event is to the right
                    {
                        if (closestRightEvent == null || evnt.Start < closestRightEvent.Start)
                        {
                            closestRightEvent = evnt;
                        }
                    }
                }
            }

            if (closestRightEvent != null)
            {
                closestRightEvent.Selected = true;

                // Calculate the trimmed duration of the right event
                double RightEventDuration = closestRightEvent.Length.ToMilliseconds() / 1000.0;

                // Convert to whole seconds and frames
                int fps = (int)Math.Round(myVegas.Project.Video.FrameRate);
                int wholeSecondsRight = (int)RightEventDuration;
                int framesRight = (int)Math.Round((RightEventDuration - wholeSecondsRight) * fps);

                /*
                MessageBox.Show("Right Event Duration: " + wholeSecondsRight + " seconds and " + framesRight + " frames",
                                "Right Event Duration",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
                */
            }
        }


        private void ExtendEventToTheRighSide()
        {
            if (myVegas.Project == null)
            {
                MessageBox.Show("No project is open.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            TrackEvent selectedEvent = null;
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        selectedEvent = evnt;
                        break;
                    }
                }
                if (selectedEvent != null)
                    break;
            }

            if (selectedEvent == null)
            {
                MessageBox.Show("No event selected!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Take activeTake = selectedEvent.ActiveTake;
            if (activeTake == null)
            {
                MessageBox.Show("The selected event has no active take!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Media media = activeTake.Media;
            if (media == null || media.Length == Timecode.FromSeconds(0))
            {
                MessageBox.Show("Invalid media!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Get the take's offset within the media
            Timecode takeOffset = activeTake.Offset;
            Timecode mediaEnd = media.Length;

            // Calculate the maximum possible event length
            Timecode maxLength = mediaEnd - takeOffset;

            // Extend the event length if possible
            if (selectedEvent.Length < maxLength)
            {
                selectedEvent.Length = maxLength;
            }
            else
            {
                MessageBox.Show("Event is already at maximum length!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            // --- Duration Calculation (Added) ---
            Timecode finalLength = selectedEvent.Length;
            double ExtendedEventDuration = finalLength.ToMilliseconds() / 1000.0;

            // Convert to whole seconds and frames
            int fps = (int)Math.Round(myVegas.Project.Video.FrameRate);
            int wholeSeconds = (int)ExtendedEventDuration;
            int frames = (int)Math.Round((ExtendedEventDuration - wholeSeconds) * fps);

            /*
            // Display the final duration
            MessageBox.Show("Extended Event Duration: " + wholeSeconds + " seconds and " + frames + " frames",
                            "Event Duration",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);
            */
        }

        private void SelectAndCalculateAndMoveCursorPositionAndTimecodeReverse()
        {
            // Step 1: Deselect all events
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    evnt.Selected = false;
                }
            }

            TrackEvent closestLeftEvent = null;
            Timecode cursorPosition = myVegas.Transport.CursorPosition;
            double leftEventDuration = 0; // Store duration for Step 4

            // Step 2: Find the first event to the left of the cursor
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.End <= cursorPosition) // Ensure event is completely to the left
                    {
                        if (closestLeftEvent == null || evnt.End > closestLeftEvent.End)
                        {
                            closestLeftEvent = evnt;
                        }
                    }
                }
            }

            if (closestLeftEvent != null)
            {
                closestLeftEvent.Selected = true;

                // Get original event duration before trimming
                leftEventDuration = (closestLeftEvent.ActiveTake.Offset + closestLeftEvent.Length).ToMilliseconds() / 1000.0;

                // Convert to whole seconds and frames
                int fps = (int)Math.Round(myVegas.Project.Video.FrameRate);
                int wholeSeconds = (int)leftEventDuration;
                int frames = (int)Math.Round((leftEventDuration - wholeSeconds) * fps);

                /*
                MessageBox.Show("Selected event duration: " + wholeSeconds + " seconds and " + frames + " frames",
                                "Event Duration",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
                */
            }

            // Step 3: Deselect the current event and select the first event to the right
            if (closestLeftEvent != null)
            {
                closestLeftEvent.Selected = false;
            }

            TrackEvent closestRightEvent = null;

            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Start >= cursorPosition) // Ensure event is to the right
                    {
                        if (closestRightEvent == null || evnt.Start < closestRightEvent.Start)
                        {
                            closestRightEvent = evnt;
                        }
                    }
                }
            }

            // Step 3.5: Select the found right event and move the cursor to its end
            if (closestRightEvent != null)
            {
                closestRightEvent.Selected = true;
                myVegas.Transport.CursorPosition = closestRightEvent.End;

                // Step 4: Move the cursor BACKWARDS by the duration of the first selected event
                myVegas.Transport.CursorPosition -= Timecode.FromSeconds(leftEventDuration);
            }
        }

        private void SplitEventAtCursorPosition2()
        {
            Timecode cursorPosition = myVegas.Transport.CursorPosition;

            foreach (Track myTrack in myVegas.Project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected && evnt.Start < cursorPosition && evnt.End > cursorPosition)
                        {
                            Timecode splitPoint = cursorPosition - evnt.Start;
                            TrackEvent rightEvent = evnt.Split(splitPoint);

                            // Deselect the right event and select only the left event
                            evnt.Selected = true;
                            rightEvent.Selected = false;

                            // Delete the selected event (which is the left event)
                            myTrack.Events.Remove(evnt);

                            // Select the first event on the right side of the cursor position
                            TrackEvent selectedEvent = null;
                            foreach (TrackEvent nextEvent in myTrack.Events)
                            {
                                if (nextEvent.Start >= cursorPosition)
                                {
                                    nextEvent.Selected = true;
                                    selectedEvent = nextEvent;
                                    break; // Stop at the first event found
                                }
                            }

                            // Move the selected event to the left until it reaches the first event
                            if (selectedEvent != null)
                            {
                                Timecode newPosition = Timecode.FromSeconds(0); // Start position
                                foreach (TrackEvent firstEvent in myTrack.Events)
                                {
                                    if (firstEvent != selectedEvent && firstEvent.Start < selectedEvent.Start)
                                    {
                                        newPosition = firstEvent.End;
                                    }
                                }

                                // Move the event to the left of the cursor position
                                selectedEvent.Start = newPosition;

                                // Final Step: Move cursor position to the start of the selected event
                                myVegas.Transport.CursorPosition = selectedEvent.Start;
                            }

                            return; // Stop after all steps
                        }
                    }
                }
            }
        }


        public void UngroupSelectedEvents()
        {
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    if (trackEvent.Selected && trackEvent.Group != null)
                    {
                        trackEvent.Group.Remove(trackEvent);
                    }
                }
            }

            // Force a UI update to refresh the state
            myVegas.UpdateUI();
        }

        public bool ShowMessagePlaybackrateisaltered()
        {
            // Get the selected event from the timeline
            TrackEvent selectedEvent = GetSelectedEvent();
            if (selectedEvent != null && selectedEvent.PlaybackRate != 1.000)
            {
                MessageBox.Show("Playback rate is altered. You must render the event as a new take.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return true; // Stop execution
            }
            return false; // Continue execution
        }

        public bool ShowMessageIfEventIsGrouped()
        {
            TrackEvent selectedEvent = GetSelectedEvent();
            if (selectedEvent != null && selectedEvent.Group != null)
            {
                Take activeTake = selectedEvent.Takes.Count > 0 ? selectedEvent.Takes[0] : null;
                Media selectedMedia = activeTake != null ? activeTake.Media : null;

                if (selectedMedia == null)
                {
                    MessageBox.Show("The selected Event is grouped. Ungroup it first.",
                                    "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return true; // Stop execution
                }

                // Check if all grouped events come from the same media source
                bool isOnlyOriginalStream = true;
                foreach (TrackEvent groupedEvent in selectedEvent.Group)
                {
                    Take groupedTake = groupedEvent.Takes.Count > 0 ? groupedEvent.Takes[0] : null;
                    Media groupedMedia = groupedTake != null ? groupedTake.Media : null;

                    if (groupedMedia == null || groupedMedia != selectedMedia)
                    {
                        isOnlyOriginalStream = false;
                        break;
                    }
                }

                // Show warning only if the group contains different media sources
                if (!isOnlyOriginalStream)
                {
                    MessageBox.Show("The selected Event is grouped. Ungroup it first.",
                                    "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return true; // Stop execution
                }
            }
            return false; // Continue execution
        }

        public bool ShowMessageIfThereIsAnEventOnTheTrackAbove()
        {
            // Get the selected event from the timeline
            TrackEvent selectedEvent = GetSelectedEvent();
            if (selectedEvent != null)
            {
                int trackIndex = selectedEvent.Track.Index;

                // Check if there is a track above
                if (trackIndex > 0)
                {
                    Track trackAbove = myVegas.Project.Tracks[trackIndex - 1];

                    // Check if there is any event in the track above that overlaps with the selected event
                    foreach (TrackEvent evnt in trackAbove.Events)
                    {
                        if (evnt.Start < selectedEvent.End && evnt.End > selectedEvent.Start)
                        {
                            MessageBox.Show("Event found above the selected Event. Please, remove the event above.",
                                            "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return true; // Stop execution
                        }
                    }
                }
            }
            return false; // Continue execution
        }

        void CalculateTheSelectedEventDuration(Vegas myVegas)
        {
            if (myVegas.Project == null || myVegas.Project.Video == null)
            {
                MessageBox.Show("No project loaded.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            int fps = (int)Math.Round(myVegas.Project.Video.FrameRate);
            TrackEvent selectedEvent = null;

            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        selectedEvent = evnt;
                        break;
                    }
                }
                if (selectedEvent != null)
                    break;
            }

            if (selectedEvent == null)
            {
                MessageBox.Show("No event selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            eventDurationSeconds = selectedEvent.Length.ToMilliseconds() / 1000.0;
            int wholeSeconds = (int)eventDurationSeconds;
            eventDurationFrames = (int)Math.Round((eventDurationSeconds - wholeSeconds) * fps);

           /* MessageBox.Show("Selected event duration: " + wholeSeconds + " seconds and " + eventDurationFrames + " frames",
                            "Event Duration",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);
                            */
        }

        public void DeleteEvent(Vegas vegas)
        {
            // Iterate through all tracks
            foreach (Track track in vegas.Project.Tracks)
            {
                // Create a list of events to remove to avoid modifying the collection while iterating
                List<TrackEvent> eventsToRemove = new List<TrackEvent>();

                // Iterate through all events on the track
                foreach (TrackEvent trackEvent in track.Events)
                {
                    // Check if the event is selected
                    if (trackEvent.Selected)
                    {
                        // Add the selected event to the list of events to remove
                        eventsToRemove.Add(trackEvent);
                    }
                }

                // Remove the selected events from the track
                foreach (TrackEvent eventToRemove in eventsToRemove)
                {
                    track.Events.Remove(eventToRemove);
                }
            }
        }

        public void DeselectAllEvents(Vegas vegas)
        {
            foreach (Track track in vegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    evnt.Selected = false;
                }
            }
        }

        public double GetEventDurationSeconds()
        {
            return eventDurationSeconds;
        }

        public int GetEventDurationFrames()
        {
            return eventDurationFrames;
        }

        private void SelectFirstEventInTheLeftSide(Vegas vegas)
        {
            try
            {
                // Get the cursor position
                Timecode cursorPosition = vegas.Transport.CursorPosition;
                bool eventSelected = false;

                // Iterate through each selected track in the project
                foreach (Track myTrack in vegas.Project.Tracks)
                {
                    if (myTrack.Selected) // Only process selected tracks
                    {
                        TrackEvent closestEvent = null;

                        // Iterate through each event on the selected track
                        foreach (TrackEvent myEvent in myTrack.Events)
                        {
                            // Check if the event ends before the cursor position
                            if (myEvent.End <= cursorPosition)
                            {
                                // Update closestEvent if it's the first found or closer to the cursor
                                if (closestEvent == null || myEvent.End > closestEvent.End)
                                {
                                    closestEvent = myEvent;
                                }
                            }
                        }

                        // Select the closest event on the left side of the cursor position if found
                        if (closestEvent != null)
                        {
                            closestEvent.Selected = true;
                            eventSelected = true;
                        }

                        break; // Stop iterating after processing the first selected track
                    }
                }

                // Display a message if no event was found on the left side of the cursor position on the selected track
                if (!eventSelected)
                {
                    MessageBox.Show("No event found on the left side of the cursor position on the selected track.",
                                    "Event Selection", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occurred: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void ExtendEvent(Vegas vegas)
        {
            try
            {
                foreach (Track track in vegas.Project.Tracks)
                {
                    foreach (TrackEvent evnt in track.Events)
                    {
                        if (evnt.Selected)
                        {
                            evnt.Length += Timecode.FromMilliseconds(eventDurationSeconds * 1000);
                            return;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occurred: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        void CalculateExceededDuration(Vegas vegas)
        {
            exceededDurations.Clear(); // Clear previous values

            foreach (Track track in vegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    if (trackEvent.Selected && trackEvent.ActiveTake != null)
                    {
                        Take take = trackEvent.ActiveTake;
                        Media media = take.Media;

                        if (media != null)
                        {
                            Timecode mediaLength = media.Length;
                            Timecode eventEnd = take.Offset + trackEvent.Length;

                            if (eventEnd > mediaLength)
                            {
                                Timecode exceededDuration = eventEnd - mediaLength;
                                exceededDurations.Add(exceededDuration); // Store exceeded duration

                                /* // Show message
                                MessageBox.Show(
                                    "Event exceeds media boundary by: " + exceededDuration.ToString(),
                                    "Exceeded Duration"
                                );
                                */
                            }
                        }
                    }
                }
            }
        }

        void TrimTailEvent(Vegas vegas)
        {
            int index = 0; // Keep track of the exceeded duration index

            foreach (Track track in vegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    if (trackEvent.Selected && index < exceededDurations.Count)
                    {
                        Timecode trimAmount = exceededDurations[index]; // Get stored exceeded duration
                        trackEvent.Length = trackEvent.Length - trimAmount; // Trim the tail
                        index++; // Move to the next stored duration
                    }
                }
            }
        }

    }
}

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

Last changed by Thiago_Sase on 3/10/2025, 2:44 PM, changed a total of 2 times.

OS: Windows 10 22H2
CPU: Intel Core I7 12700
MEMORY: 32GB DDR4 3200MHz
GHAPHIC CARD: RTX 3060 8GB
HARD DRIVES: SSD for System and M.2 for Media Files

Thiago_Sase wrote on 3/10/2025, 2:39 PM

@Steve_Rhoden Maybe, with the new update you can do the non reverse if you run the script again.

Last changed by Thiago_Sase on 3/10/2025, 2:44 PM, changed a total of 1 times.

OS: Windows 10 22H2
CPU: Intel Core I7 12700
MEMORY: 32GB DDR4 3200MHz
GHAPHIC CARD: RTX 3060 8GB
HARD DRIVES: SSD for System and M.2 for Media Files