Copying generated media without creating a reference

AlexE wrote on 5/22/2024, 6:39 AM

Hi.

I've been trying to make my workflow easier by making scripts now, and one of them involves copying a lot of text events and their FX, parameters etc. with them.

However, I haven't really been able to find a good solution for this:
- TrackEvent.Copy() just creates a reference.
- Parameters and effects are read-only variables so I can't just make a new event and copy those directly(?).

Previously I've settled for just pasting a whole bunch of events with Ctrl + B, using the "make a new copy" instead of reference to make VEGAS that part for me, and then make the script just take those to edit. But with new functionality I want to add, this isn't a very good way to do this anymore (and it's also just not ideal to have to do a bunch of math and counting every time).

I just wanted to ask if anyone could think of a better way than the manual pasting. I've thought about just creating a new event and pasting every single parameter, video effect, pan & crop stuff, etc. manually somehow. But I'm just a little worried that doing stuff like that would make the script insanely slow and it just sounds like a really complicated solution.

Surely I'm overthinking this, right? Is there a simple way to copy an event without referencing it using a script? I'm lost.

Thanks.

Comments

Dexcon wrote on 5/22/2024, 7:05 AM

Why do you need a script to copy/paste a title such as Vegas Pro's Titles & Text? For a project, I create an original title with font, font size, color, drop shadow etc, and the title video event has an FX (Layer Dimensionality) which I will use as the base for many other titles throughout the project (e.g. location names). It is so simple to copy that title event on the timeline (R click and select copy or use Ctrl-C) and then paste to the new position on the timeline (R click and select Paste or Ctrl-V) and, in the window that opens, click OK on the default 'Create a new copy of the source media'. This gives an exact copy of the original title with all style elements and FX intact. All that is then needed is to change the text as needed for the new title. The copy/paste process takes but a few seconds. And if you're doing a lot of titles in a row, all that is needed is to continue to use the paste function (no need to copy again) and amend each new pasted title with the new text.

Ditto if you're using NewBlueFX's Titler Pro or BorisFX's Title Studio.

Last changed by Dexcon on 5/22/2024, 7:17 AM, changed a total of 1 times.

Cameras: Sony FDR-AX100E; GoPro Hero 11 Black Creator Edition

Installed: Vegas Pro 15, 16, 17, 18, 19, 20, 21 & 22, HitFilm Pro 2021.3, DaVinci Resolve Studio 19.0.3, BCC 2025, Mocha Pro 2025.0, NBFX TotalFX 7, Neat NR, DVD Architect 6.0, MAGIX Travel Maps, Sound Forge Pro 16, SpectraLayers Pro 11, iZotope RX11 Advanced and many other iZ plugins, Vegasaur 4.0

Windows 11

Dell Alienware Aurora 11:

10th Gen Intel i9 10900KF - 10 cores (20 threads) - 3.7 to 5.3 GHz

NVIDIA GeForce RTX 2080 SUPER 8GB GDDR6 - liquid cooled

64GB RAM - Dual Channel HyperX FURY DDR4 XMP at 3200MHz

C drive: 2TB Samsung 990 PCIe 4.0 NVMe M.2 PCIe SSD

D: drive: 4TB Samsung 870 SATA SSD (used for media for editing current projects)

E: drive: 2TB Samsung 870 SATA SSD

F: drive: 6TB WD 7200 rpm Black HDD 3.5"

Dell Ultrasharp 32" 4K Color Calibrated Monitor

 

LAPTOP:

Dell Inspiron 5310 EVO 13.3"

i5-11320H CPU

C Drive: 1TB Corsair Gen4 NVMe M.2 2230 SSD (upgraded from the original 500 GB SSD)

Monitor is 2560 x 1600 @ 60 Hz

zzzzzz9125 wrote on 5/22/2024, 7:26 AM

For scripting, maybe you can first create a reference with TrackEvent.Copy(), then create a new instance of the Generator, and finally paste the properties of the Generators.

As a hint, to paste the properties of the Generators, I use the following code in another of my scripts:

foreach (OFXParameter otherPara in otherOfxEffect.Parameters)
{
    OFXParameter para = ofxEffect.FindParameterByName(otherPara.Name);
    if (para == null || otherPara.ParameterType != para.ParameterType)
    {
        continue;
    }

    switch (otherPara.ParameterType)
    {
        case OFXParameterType.Boolean:
            ((OFXBooleanParameter)otherPara).Value = ((OFXBooleanParameter)para).Value;
            break;

        case OFXParameterType.Choice:
            ((OFXChoiceParameter)otherPara).Value = ((OFXChoiceParameter)para).Value;
            break;

        case OFXParameterType.Custom:
            ((OFXCustomParameter)otherPara).Value = ((OFXCustomParameter)para).Value;
            break;

        case OFXParameterType.Double2D:
            ((OFXDouble2DParameter)otherPara).Value = ((OFXDouble2DParameter)para).Value;
            break;

        case OFXParameterType.Double3D:
            ((OFXDouble3DParameter)otherPara).Value = ((OFXDouble3DParameter)para).Value;
            break;

        case OFXParameterType.Double:
            ((OFXDoubleParameter)otherPara).Value = ((OFXDoubleParameter)para).Value;
            break;

        case OFXParameterType.Integer2D:
            ((OFXInteger2DParameter)otherPara).Value = ((OFXInteger2DParameter)para).Value;
            break;

        case OFXParameterType.Integer3D:
            ((OFXInteger3DParameter)otherPara).Value = ((OFXInteger3DParameter)para).Value;
            break;

        case OFXParameterType.Integer:
            ((OFXIntegerParameter)otherPara).Value = ((OFXIntegerParameter)para).Value;
            break;

        case OFXParameterType.RGBA:
            ((OFXRGBAParameter)otherPara).Value = ((OFXRGBAParameter)para).Value;
            break;

        case OFXParameterType.RGB:
            ((OFXRGBParameter)otherPara).Value = ((OFXRGBParameter)para).Value;
            break;

        case OFXParameterType.String:
            ((OFXStringParameter)otherPara).Value = ((OFXStringParameter)para).Value;
            break;

        default:
            continue;
            break;
    }
}

I may try to write a complete one soon.

Using VEGAS Pro 22 build 248 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

jetdv wrote on 5/22/2024, 7:27 AM

@AlexE, which titler are you using? Titles & Text should allow you to create a new generated media and then copy all parameters from the original to the newly created one as it is OpenFX. There's several tutorials on my site showing how to adjust some of the various things in Titles & Text.

Or, you could create a preset and then add a new generated media Titles and Text and pick that preset.

I'm not sure if there's a workaround using "copy" to copy to a new event instead of a reference event.

AlexE wrote on 5/22/2024, 7:28 AM

I'm aware that it sounds quite simple but the script in question often moves over 100 text events at a time, not just editing the text but also adding effects, adjusting scale, changing plugin parameters, changing colors of text when needed and other stuff.

It's *a lot* faster than doing it manually (hence why I made it) and I just wanted to see if copying them with the same script was possible to save me the extra trouble of calculating how many I need and pasting them first.

AlexE wrote on 5/22/2024, 7:31 AM

For scripting, maybe you can first create a reference with TrackEvent.Copy(), then create a new instance of the Generator, and finally paste the properties of the Generators.

As a hint, to paste the properties of the Generators, I use the following code in another of my scripts:

foreach (OFXParameter otherPara in otherOfxEffect.Parameters)
{
    OFXParameter para = ofxEffect.FindParameterByName(otherPara.Name);
    if (para == null || otherPara.ParameterType != para.ParameterType)
    {
        continue;
    }

    switch (otherPara.ParameterType)
    {
        case OFXParameterType.Boolean:
            ((OFXBooleanParameter)otherPara).Value = ((OFXBooleanParameter)para).Value;
            break;

        case OFXParameterType.Choice:
            ((OFXChoiceParameter)otherPara).Value = ((OFXChoiceParameter)para).Value;
            break;

        case OFXParameterType.Custom:
            ((OFXCustomParameter)otherPara).Value = ((OFXCustomParameter)para).Value;
            break;

        case OFXParameterType.Double2D:
            ((OFXDouble2DParameter)otherPara).Value = ((OFXDouble2DParameter)para).Value;
            break;

        case OFXParameterType.Double3D:
            ((OFXDouble3DParameter)otherPara).Value = ((OFXDouble3DParameter)para).Value;
            break;

        case OFXParameterType.Double:
            ((OFXDoubleParameter)otherPara).Value = ((OFXDoubleParameter)para).Value;
            break;

        case OFXParameterType.Integer2D:
            ((OFXInteger2DParameter)otherPara).Value = ((OFXInteger2DParameter)para).Value;
            break;

        case OFXParameterType.Integer3D:
            ((OFXInteger3DParameter)otherPara).Value = ((OFXInteger3DParameter)para).Value;
            break;

        case OFXParameterType.Integer:
            ((OFXIntegerParameter)otherPara).Value = ((OFXIntegerParameter)para).Value;
            break;

        case OFXParameterType.RGBA:
            ((OFXRGBAParameter)otherPara).Value = ((OFXRGBAParameter)para).Value;
            break;

        case OFXParameterType.RGB:
            ((OFXRGBParameter)otherPara).Value = ((OFXRGBParameter)para).Value;
            break;

        case OFXParameterType.String:
            ((OFXStringParameter)otherPara).Value = ((OFXStringParameter)para).Value;
            break;

        default:
            continue;
            break;
    }
}

I may try to write a complete one soon.

Thank you, I hadn't thought of this. I will give this a shot when able.

zzzzzz9125 wrote on 5/22/2024, 8:25 AM

Here it is:

using System.Collections.Generic;

using ScriptPortal.Vegas;  // "ScriptPortal.Vegas" for Magix Vegas Pro 14 or above, "Sony.Vegas" for Sony Vegas Pro 13 or below

namespace Test_Script
{
    public class Class
    {
        public Vegas myVegas;
        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            List<VideoEvent> eventList = new List<VideoEvent>();
            foreach (Track myTrack in myVegas.Project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected)
                        {
                            eventList.Add((VideoEvent)evnt);
                        }
                    }
                }
            }

            foreach (VideoEvent vEvent in eventList)
            {
                CopyGenerator(vEvent);
            }
        }

        public static VideoEvent CopyGenerator(VideoEvent vEvent, Track track = null, Timecode start = null, Timecode length = null)
        {
            if(!vEvent.ActiveTake.Media.IsGenerated() || !vEvent.ActiveTake.Media.Generator.IsOFX)
            {
                return null;
            }

            if (track == null)
            {
                track = vEvent.Track;
            }

            if (start == null)
            {
                start = vEvent.End;
            }

            VideoEvent newEvent = (VideoEvent)vEvent.Copy(track, start);

            if (length != null)
            {
                newEvent.Length = length;
            }

            OFXEffect sourceOFX = newEvent.ActiveTake.Media.Generator.OFXEffect;

            Media newMedia = new Media(newEvent.ActiveTake.Media.Generator.PlugIn);

            newEvent.Takes.Clear();
            newEvent.AddTake(newMedia.GetVideoStreamByIndex(0));

            CopyOFX(sourceOFX, newEvent.ActiveTake.Media.Generator.OFXEffect);

            return newEvent;
        }

        public static OFXEffect CopyOFX(OFXEffect sourceOFX, OFXEffect targetOFX)
        {
            foreach (OFXParameter targetPara in targetOFX.Parameters)
            {
                OFXParameter para = sourceOFX.FindParameterByName(targetPara.Name);
                if (para == null || targetPara.ParameterType != para.ParameterType)
                {
                    continue;
                }

                switch (targetPara.ParameterType)
                {
                    case OFXParameterType.Boolean:
                        ((OFXBooleanParameter)targetPara).Value = ((OFXBooleanParameter)para).Value;
                        break;

                    case OFXParameterType.Choice:
                        ((OFXChoiceParameter)targetPara).Value = ((OFXChoiceParameter)para).Value;
                        break;

                    case OFXParameterType.Custom:
                        ((OFXCustomParameter)targetPara).Value = ((OFXCustomParameter)para).Value;
                        break;

                    case OFXParameterType.Double2D:
                        ((OFXDouble2DParameter)targetPara).Value = ((OFXDouble2DParameter)para).Value;
                        break;

                    case OFXParameterType.Double3D:
                        ((OFXDouble3DParameter)targetPara).Value = ((OFXDouble3DParameter)para).Value;
                        break;

                    case OFXParameterType.Double:
                        ((OFXDoubleParameter)targetPara).Value = ((OFXDoubleParameter)para).Value;
                        break;

                    case OFXParameterType.Integer2D:
                        ((OFXInteger2DParameter)targetPara).Value = ((OFXInteger2DParameter)para).Value;
                        break;

                    case OFXParameterType.Integer3D:
                        ((OFXInteger3DParameter)targetPara).Value = ((OFXInteger3DParameter)para).Value;
                        break;

                    case OFXParameterType.Integer:
                        ((OFXIntegerParameter)targetPara).Value = ((OFXIntegerParameter)para).Value;
                        break;

                    case OFXParameterType.RGBA:
                        ((OFXRGBAParameter)targetPara).Value = ((OFXRGBAParameter)para).Value;
                        break;

                    case OFXParameterType.RGB:
                        ((OFXRGBParameter)targetPara).Value = ((OFXRGBParameter)para).Value;
                        break;

                    case OFXParameterType.String:
                        ((OFXStringParameter)targetPara).Value = ((OFXStringParameter)para).Value;
                        break;

                    default:
                        continue;
                        break;
                }
            }
            return targetOFX;
        }
    }
}

public class EntryPoint
{
    public void FromVegas(Vegas vegas)
    //public void FromVegas(Vegas vegas, String scriptFile, XmlDocument scriptSettings, ScriptArgs args)
    {
        Test_Script.Class test = new Test_Script.Class();
        test.Main(vegas);
    }
}

The bold part is the main functions. You can do this with CopyGenerator(vEvent, track, start, length). If the last three parameters are not specified, the new event will be generated directly behind the old event by default.

Last changed by zzzzzz9125 on 5/22/2024, 8:27 AM, changed a total of 2 times.

Using VEGAS Pro 22 build 248 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

AlexE wrote on 5/23/2024, 3:33 AM

Here it is:

using System.Collections.Generic;

using ScriptPortal.Vegas;  // "ScriptPortal.Vegas" for Magix Vegas Pro 14 or above, "Sony.Vegas" for Sony Vegas Pro 13 or below

namespace Test_Script
{
    public class Class
    {
        public Vegas myVegas;
        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            List<VideoEvent> eventList = new List<VideoEvent>();
            foreach (Track myTrack in myVegas.Project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected)
                        {
                            eventList.Add((VideoEvent)evnt);
                        }
                    }
                }
            }

            foreach (VideoEvent vEvent in eventList)
            {
                CopyGenerator(vEvent);
            }
        }

        public static VideoEvent CopyGenerator(VideoEvent vEvent, Track track = null, Timecode start = null, Timecode length = null)
        {
            if(!vEvent.ActiveTake.Media.IsGenerated() || !vEvent.ActiveTake.Media.Generator.IsOFX)
            {
                return null;
            }

            if (track == null)
            {
                track = vEvent.Track;
            }

            if (start == null)
            {
                start = vEvent.End;
            }

            VideoEvent newEvent = (VideoEvent)vEvent.Copy(track, start);

            if (length != null)
            {
                newEvent.Length = length;
            }

            OFXEffect sourceOFX = newEvent.ActiveTake.Media.Generator.OFXEffect;

            Media newMedia = new Media(newEvent.ActiveTake.Media.Generator.PlugIn);

            newEvent.Takes.Clear();
            newEvent.AddTake(newMedia.GetVideoStreamByIndex(0));

            CopyOFX(sourceOFX, newEvent.ActiveTake.Media.Generator.OFXEffect);

            return newEvent;
        }

        public static OFXEffect CopyOFX(OFXEffect sourceOFX, OFXEffect targetOFX)
        {
            foreach (OFXParameter targetPara in targetOFX.Parameters)
            {
                OFXParameter para = sourceOFX.FindParameterByName(targetPara.Name);
                if (para == null || targetPara.ParameterType != para.ParameterType)
                {
                    continue;
                }

                switch (targetPara.ParameterType)
                {
                    case OFXParameterType.Boolean:
                        ((OFXBooleanParameter)targetPara).Value = ((OFXBooleanParameter)para).Value;
                        break;

                    case OFXParameterType.Choice:
                        ((OFXChoiceParameter)targetPara).Value = ((OFXChoiceParameter)para).Value;
                        break;

                    case OFXParameterType.Custom:
                        ((OFXCustomParameter)targetPara).Value = ((OFXCustomParameter)para).Value;
                        break;

                    case OFXParameterType.Double2D:
                        ((OFXDouble2DParameter)targetPara).Value = ((OFXDouble2DParameter)para).Value;
                        break;

                    case OFXParameterType.Double3D:
                        ((OFXDouble3DParameter)targetPara).Value = ((OFXDouble3DParameter)para).Value;
                        break;

                    case OFXParameterType.Double:
                        ((OFXDoubleParameter)targetPara).Value = ((OFXDoubleParameter)para).Value;
                        break;

                    case OFXParameterType.Integer2D:
                        ((OFXInteger2DParameter)targetPara).Value = ((OFXInteger2DParameter)para).Value;
                        break;

                    case OFXParameterType.Integer3D:
                        ((OFXInteger3DParameter)targetPara).Value = ((OFXInteger3DParameter)para).Value;
                        break;

                    case OFXParameterType.Integer:
                        ((OFXIntegerParameter)targetPara).Value = ((OFXIntegerParameter)para).Value;
                        break;

                    case OFXParameterType.RGBA:
                        ((OFXRGBAParameter)targetPara).Value = ((OFXRGBAParameter)para).Value;
                        break;

                    case OFXParameterType.RGB:
                        ((OFXRGBParameter)targetPara).Value = ((OFXRGBParameter)para).Value;
                        break;

                    case OFXParameterType.String:
                        ((OFXStringParameter)targetPara).Value = ((OFXStringParameter)para).Value;
                        break;

                    default:
                        continue;
                        break;
                }
            }
            return targetOFX;
        }
    }
}

public class EntryPoint
{
    public void FromVegas(Vegas vegas)
    //public void FromVegas(Vegas vegas, String scriptFile, XmlDocument scriptSettings, ScriptArgs args)
    {
        Test_Script.Class test = new Test_Script.Class();
        test.Main(vegas);
    }
}

The bold part is the main functions. You can do this with CopyGenerator(vEvent, track, start, length). If the last three parameters are not specified, the new event will be generated directly behind the old event by default.

Thank you so much for this. All of my life's problems have been solved.