Adding video FX / FX chains

Niturzion wrote on 5/31/2022, 5:30 PM

Hello. I'm currently learning how to write some scripts for vegas 16, and one thing that I have been struggling to find is how to add effects and fx chains programatically . I have looked at the documentation and I am aware that I need to use:

override void Insert

(

Int32 index,
Effect item

)

However, how do I actually get the instance for this effect so that I can add as a parameter, and is there a way to read in this effect object from an XML file containing the effect? Sorry if this is a terrible question but I'm not really familiar with using api's. Thanks in advance for any help.

 

Here is my current code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

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

namespace Nitty_Pro_18
{
    // Entry point
    public class EntryPoint
    {
        // Run function once vegas has provided instance of itself
        public void FromVegas(Vegas vegas)
        {
            // Get the first track
            Track myTrack = vegas.Project.Tracks[0];

            // For each marker in the project file
            foreach(Marker marker in vegas.Project.Markers)
            {
                // Check each track event to see if one occurs during this marker
                foreach (VideoEvent videoEvent in myTrack.Events)
                {
                    if(videoEvent.Start <= marker.Position && videoEvent.End >= marker.Position)
                    {
                        // Marker is over a valid event
                        // Check the label of the marker

                        // If the label is "k", then we will add a kill effect
                        if (marker.Label.ToLower() == "k")
                        {
                            // Split the event at the position of the marker
                             videoEvent.Split(marker.Position - videoEvent.Start);

                            // Clear video effects and add an FX chain
                            videoEvent.Effects.Clear();
                            videoEvent.Effects.Insert(marker.Position - videoEvent.Start, );
                        
                        }

                        // If the label is "t", then we will add a transition
                        else if (marker.Label.ToLower() == "t")
                        {

                        }
                    }
                }
                
                

          

                // else ignore marker
            }

        }
    }

}
 

Comments

jetdv wrote on 5/31/2022, 6:13 PM

@Niturzion, you might want to take a look at my website at www.jetdv.com.

In your code above, you've never told it WHAT effect to add to the video event. Here's a couple tutorials that might get you started down the right path (there are many more that touch on adjusting effects as well):

 

jetdv wrote on 5/31/2022, 6:17 PM

This would also be a good one to watch:

Niturzion wrote on 5/31/2022, 6:55 PM

@Niturzion, you might want to take a look at my website at www.jetdv.com.

In your code above, you've never told it WHAT effect to add to the video event. Here's a couple tutorials that might get you started down the right path (there are many more that touch on adjusting effects as well):

 

Thank you very much for the response! This was very helpful and it has definitely helped me progress forward with my script. I still have one question though, is it possible to add an FX chain using a similar method, rather than only adding an effect?

jetdv wrote on 6/1/2022, 8:56 AM

@Niturzion No. You can add all of the pieces of the chain individually but you'll have to know what those pieces are. I haven't seen a way to access an actual chain.

Niturzion wrote on 6/1/2022, 9:31 AM

@Niturzion No. You can add all of the pieces of the chain individually but you'll have to know what those pieces are. I haven't seen a way to access an actual chain.

Ok :( Thats a real shame, this would be an amazing addition to the api as using chains is a huge time saver, but i guess ill just write it manually. Thanks for your help

jetdv wrote on 6/1/2022, 9:36 AM

You *can* create your own chaining system in code. And you can read the effect information that has been applied to save your own chain information. But I agree it would be nice to be able to access the built-in chains.

And remember you can only adjust parameters on OFX effects. If you have an older DirectX effect, you can still add it and choose a preset but you can't adjust the individual parameters.

Niturzion wrote on 6/1/2022, 6:20 PM

You *can* create your own chaining system in code. And you can read the effect information that has been applied to save your own chain information. But I agree it would be nice to be able to access the built-in chains.

And remember you can only adjust parameters on OFX effects. If you have an older DirectX effect, you can still add it and choose a preset but you can't adjust the individual parameters.

Hello, im sorry to keep bothering you but i just want to ask a quick question, I do not know how I can change the fade type of the parameters, because i dont seem to be making any key frames, i am only setting the value of the parameters. But im not really sure what i should be changing to form a keyframe instead.

 

Here is the code:

PlugInNode sShakePG = effects.GetChildByUniqueID("{Svfx:com.genarts.sapphire.Distort.S_Shake}");
                        Effect sShake = new Effect(sShakePG);
                        videoEvent.Effects.Add(sShake);
                        sShake.Preset = "tarohighlightshake";

                        OFXEffect ofxShake = sShake.OFXEffect;
                        OFXDoubleParameter amplitude = (OFXDoubleParameter)ofxShake["Amplitude"];
                        amplitude.IsAnimated = true;

// How can I make it so that the values below use the slow fade?
                        amplitude.SetValueAtTime(Timecode.FromFrames(4), (double)0.00);
                        amplitude.SetValueAtTime(Timecode.FromFrames(8), (double)1.00);

jetdv wrote on 6/2/2022, 9:37 AM

@Niturzion You are creating keyframes! Both of these lines creates a new keyframe:

                        amplitude.SetValueAtTime(Timecode.FromFrames(4), (double)0.00);
                        amplitude.SetValueAtTime(Timecode.FromFrames(8), (double)1.00);

You're going to have to know the keyframe number. So if those are the only two keyframes being set (with the default "0" keyframe at the beginning), you would do something like:

                        amplitude.SetValueAtTime(Timecode.FromFrames(4), (double)0.00);
                        amplitude.Keyframes[1].Interpolation = OFXInterpolationType.Slow;
                        amplitude.SetValueAtTime(Timecode.FromFrames(8), (double)1.00);
                        amplitude.Keyframes[2].Interpolation = OFXInterpolationType.Linear;

Or you could always assume it's the "last" keyframe - which will be true unless you are adding them out of time sequence. In your example, it would be true.

                        amplitude.SetValueAtTime(Timecode.FromFrames(4), (double)0.00);
                        amplitude.Keyframes[aplitude.Keyframes.Count - 1].Interpolation = OFXInterpolationType.Fast;
                        amplitude.SetValueAtTime(Timecode.FromFrames(8), (double)1.00);
                        amplitude.Keyframes[aplitude.Keyframes.Count - 1].Interpolation = OFXInterpolationType.Sharp;

Or if you wanted every keyframe to be the same interpolation, after creating all of the keyframes, you could do this:

                        amplitude.SetValueAtTime(Timecode.FromFrames(4), (double)0.00);
                        amplitude.SetValueAtTime(Timecode.FromFrames(8), (double)1.00);
                        foreach (OFXKeyframe myKF in amplitude.Keyframes)
                        {
                            myKF.Interpolation = OFXInterpolationType.Smooth;
                        }

As another option, you could create a subroutine that does it all and then just call the subroutine each time:

                        setOFXParameter(amplitude, Timecode.FromFrames(4), (double)0.00, OFXInterpolationType.Slow);
                        setOFXParameter(amplitude, Timecode.FromFrames(8), (double)1.00, OFXInterpolationType.Slow);


        // the new subroutine called by the modified lines from your original code
        public void setOFXParameter(OFXDoubleParameter ofxParm, Timecode keyTime, Double keyValue, OFXInterpolationType interpolation)
        {
            ofxParm.IsAnimated = true;
            ofxParm.SetValueAtTime(keyTime, keyValue);
            foreach(OFXKeyframe myKF in ofxParm.Keyframes)
            {
                if (myKF.Time == keyTime)
                {
                    myKF.Interpolation = interpolation;
                }
            }
        }

I listed five of the possible examples for the interpolation types. Hold is also an available option.

So as you can see, there's many options available to you. You might also want to take a look at this video which also shows how to access the interpolation on each keyframe.

 

jetdv wrote on 6/2/2022, 9:44 AM

And, depending on what you are really doing, this free tool I gave away at Christmas may do what you're really wanting to do! And it will set you set up "chains" that can be reused over and over again as well as set up the proper interpolations between keyframes.You would just modify the .config XML file to be the effects, parameters (Double only), interpolations, and "chains" you want to use.

 

Niturzion wrote on 6/2/2022, 6:44 PM

And, depending on what you are really doing, this free tool I gave away at Christmas may do what you're really wanting to do! And it will set you set up "chains" that can be reused over and over again as well as set up the proper interpolations between keyframes.You would just modify the .config XML file to be the effects, parameters (Double only), interpolations, and "chains" you want to use.

 

I managed to write it in another way before i saw this reply, but this definitely seems a lot cleaner. I really appreciate all the work you do for the vegas scripting community which nobody else is putting in, you are truly amazing (p.s i sent you a donation on your website)

jetdv wrote on 6/2/2022, 8:01 PM

@Niturzion That is much appreciated. Thank you.