Can't get this script to work :(

Connor-Fadden wrote on 7/14/2023, 3:49 AM

I'm trying to use this custom script in C# for checking titles in a list, and setting them in the timeline one by one. This is my first time using Vegas scripts, but I'm getting errors and have tried a few different ways to fix it, but no luck ><

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

namespace SampleScript1
{
    public class EntryPoint
    {
        public void FromVegas(Vegas vegas)
        {
            // Initialize the titles array
            string[] titles = { "Title 1", "Title 2", "Title 3", "Title 4", "Title 5" };

            // Insert the titles into the timeline
            int trackIndex = 0; // Target track index
            Timecode cursorPosition = vegas.Transport.CursorPosition;
            foreach (string title in titles)
            {
                cursorPosition = AddTitleAt(vegas, title, trackIndex, cursorPosition);
            }

            MessageBox.Show("Titles inserted successfully.");
        }

        private Timecode AddTitleAt(Vegas vegas, string title, int trackIndex, Timecode cursorPosition)
        {
            // Create a new video track if it doesn't exist
            while (vegas.Project.VideoTracks.Count <= trackIndex)
            {
                vegas.Project.AddVideoTrack();
            }

            // Find the text generator plug-in
            PlugInNode plugIn = vegas.Generators.GetChildByName("Sony Titles & Text");
            if (plugIn == null)
            {
                MessageBox.Show("Could not find 'Sony Titles & Text' generator.");
                return cursorPosition;
            }

            // Create a media object with the generator plug-in
            Media media = new Media(plugIn);

            // Set the generator preset to the title text
            media.Generator.Preset = title;

            // Create a new video event in the track
            VideoEvent videoEvent = vegas.Project.VideoTracks[trackIndex].AddVideoEvent(cursorPosition, new Timecode(5.0));

            // Add the take using the generated video stream
            Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0));

            return videoEvent.End;
        }
    }
}

 


Do any of you guys see any glaring faults in the code?

Thanks so much for your help!

Connor

Comments

jetdv wrote on 7/14/2023, 7:32 AM

I don't even see any code...

Connor-Fadden wrote on 7/14/2023, 7:40 AM

I don't even see any code...

Oops! I've added it now!

jetdv wrote on 7/14/2023, 8:36 AM

What version of VEGAS? One error could be "Sony Titles & Text" - You're using "ScriptPortal" which means you're using a Magix version of VEGAS. So the effect is probably not named "Sony". Have you looked at my tutorials?

Connor-Fadden wrote on 7/14/2023, 9:48 AM

What version of VEGAS? One error could be "Sony Titles & Text" - You're using "ScriptPortal" which means you're using a Magix version of VEGAS. So the effect is probably not named "Sony". Have you looked at my tutorials?

I'm using Vegas pro 20. I haven't checked out your tutorials yet!

jetdv wrote on 7/14/2023, 10:06 AM

Take a look at those two tutorials. The first one shows you how to add Titles and Text to the timeline. The second one shows you how to change the text, font, font size, text color, alignment, and position. And this one will show how to fit the background to the text.

So try out these tutorials and you should be able to get it working.

Note: I am not picking a preset. Also, another issue is that you need to actually create the event on the timeline and add it as a take before you can do things like pick a preset or make any other adjustments.

So... get rid of "Sony" (use the method in the tutorial to find the correct one) and make sure you have it fully placed on the timeline before you start making any adjustments.

Connor-Fadden wrote on 7/15/2023, 9:57 AM

Take a look at those two tutorials. The first one shows you how to add Titles and Text to the timeline. The second one shows you how to change the text, font, font size, text color, alignment, and position. And this one will show how to fit the background to the text.

So try out these tutorials and you should be able to get it working.

Note: I am not picking a preset. Also, another issue is that you need to actually create the event on the timeline and add it as a take before you can do things like pick a preset or make any other adjustments.

So... get rid of "Sony" (use the method in the tutorial to find the correct one) and make sure you have it fully placed on the timeline before you start making any adjustments.

Thanks for your response Jet! I've tried implementing some of these changes and following your tutorial but I'm getting this error. https://imgur.com/DPlDaN0

jetdv wrote on 7/15/2023, 10:39 AM

@Connor-Fadden I would need to see your current code. Lines 62 and 82 have an error. You are, apparently, referencing a VideoTrack but have no defined video track. Or you're trying to reference a VideoTrack element but have only defined a "Track" which could be video or audio. Without seeing the code, I have no way of knowing what might be the cause of the error.

P.s., you can load the images direct to this forum using the upload button - third from the right above where you type.

Connor-Fadden wrote on 7/15/2023, 11:17 AM

@Connor-Fadden I would need to see your current code. Lines 62 and 82 have an error. You are, apparently, referencing a VideoTrack but have no defined video track. Or you're trying to reference a VideoTrack element but have only defined a "Track" which could be video or audio. Without seeing the code, I have no way of knowing what might be the cause of the error.

P.s., you can load the images direct to this forum using the upload button - third from the right above where you type.

Thanks Jet! My code is:

 

using System;using System.IO;using System.Windows.Forms;using System.Globalization;using System.Drawing;using ScriptPortal.Vegas;
namespace SampleScript1{    public class EntryPoint    {        public void FromVegas(Vegas vegas)        {            // Open a dialog box to select a folder            string selectedFolder = SelectFolder();            if (selectedFolder == null)            {                MessageBox.Show("No folder selected.");                return;            }
            // Find the 'titles.txt' file in the selected folder            string titlesFilePath = Path.Combine(selectedFolder, "titles.txt");            if (!File.Exists(titlesFilePath))            {                MessageBox.Show("Could not find 'titles.txt' in the selected folder.");                return;            }
            // Read the file and extract the titles            string[] titles = File.ReadAllLines(titlesFilePath);
            // Insert the titles into the timeline            int trackIndex = 0; // Target track index            Timecode cursorPosition = vegas.Transport.CursorPosition;            foreach (string title in titles)            {                cursorPosition = AddTitleAt(vegas, title, trackIndex, cursorPosition);            }
            MessageBox.Show("Titles inserted successfully.");        }
        private string SelectFolder()        {            using (var dialog = new FolderBrowserDialog())            {                dialog.Description = "Select a folder";                dialog.ShowNewFolderButton = false;
                if (dialog.ShowDialog() == DialogResult.OK)                {                    return dialog.SelectedPath;                }            }            return null;        }
        private Timecode AddTitleAt(Vegas vegas, string title, int trackIndex, Timecode cursorPosition)        {            // Create a new video track if it doesn't exist            while (vegas.Project.Tracks.Count <= trackIndex)            {                vegas.Project.AddVideoTrack();            }
            // Find the text generator plug-in            PlugInNode plugIn = vegas.Generators.GetChildByName("Titles & Text");            if (plugIn == null)            {                MessageBox.Show("Could not find 'Titles & Text' generator.");                return cursorPosition;            }
            // Create a media object with the generator plug-in            Media media = new Media(plugIn);
            // Set the generator preset to the title text            media.Generator.Preset = title;
            // Create a new video event in the track            VideoEvent videoEvent = vegas.Project.Tracks[trackIndex].AddVideoEvent(cursorPosition, new Timecode(5.0));
            // Add the take using the generated video stream            Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0));
            return videoEvent.End;        }    }}

I changed the 'sony' naming convention, but can't get around this little hitch! I've tried a few different fixes but no luck. Do you have a link to your code from the tutorials?

EDIT: It doesn't seem to format the code nicely on this. Is there a better way I can show it?

jetdv wrote on 7/15/2023, 12:13 PM

@Connor-Fadden The problem line:

VideoEvent videoEvent = vegas.Project.Tracks[trackIndex].AddVideoEvent(cursorPosition, new Timecode(5.0));

vegas.Project.Tracks[trackIndex] is a "Track"

To add a video event, you have to have a "VideoTrack"

Try this instead:

            // Create a new video event in the track
            VideoTrack vidTrack = (VideoTrack)vegas.Project.Tracks[trackIndex];
            VideoEvent videoEvent = vidTrack.AddVideoEvent(cursorPosition, new Timecode(5.0));

This code actually works and adds multiple events to the timeline (they all say "Sample Text") at 1 frame each.
 

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

namespace SampleScript1
{
    public class EntryPoint
    {
        public void FromVegas(Vegas vegas)
        {
            // Open a dialog box to select a folder
            string selectedFolder = SelectFolder();
            if (selectedFolder == null)
            {
                MessageBox.Show("No folder selected.");
                return;
            }
            
            // Find the 'titles.txt' file in the selected folder
            string titlesFilePath = Path.Combine(selectedFolder, "titles.txt");
            if (!File.Exists(titlesFilePath))
            {
                MessageBox.Show("Could not find 'titles.txt' in the selected folder.");
                return;
            }
            
            // Read the file and extract the titles
            string[] titles = File.ReadAllLines(titlesFilePath);
            
            // Insert the titles into the timeline
            int trackIndex = 0;

            // Target track index
            Timecode cursorPosition = vegas.Transport.CursorPosition;
            foreach (string title in titles)
            {
                cursorPosition = AddTitleAt(vegas, title, trackIndex, cursorPosition);
            }
            MessageBox.Show("Titles inserted successfully.");
        }

        private string SelectFolder()
        {
            using (var dialog = new FolderBrowserDialog())
            {
                dialog.Description = "Select a folder"; dialog.ShowNewFolderButton = false;
                if (dialog.ShowDialog() == DialogResult.OK) { return dialog.SelectedPath; }
            }
            return null;
        }

        private Timecode AddTitleAt(Vegas vegas, string title, int trackIndex, Timecode cursorPosition)
        {
            // Create a new video track if it doesn't exist
            while (vegas.Project.Tracks.Count <= trackIndex)
            {
                vegas.Project.AddVideoTrack();
            }

            // Find the text generator plug-in
            PlugInNode plugIn = vegas.Generators.GetChildByName("Titles & Text");
            if (plugIn == null)
            {
                MessageBox.Show("Could not find 'Titles & Text' generator.");
                return cursorPosition;
            }

            // Create a media object with the generator plug-in
            Media media = new Media(plugIn);

            // Set the generator preset to the title text
            media.Generator.Preset = title;

            // Create a new video event in the track
            VideoTrack vidTrack = (VideoTrack)vegas.Project.Tracks[trackIndex];
            VideoEvent videoEvent = vidTrack.AddVideoEvent(cursorPosition, new Timecode(5.0));

            // Add the take using the generated video stream
            Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0));
            return videoEvent.End;
        }
    }
}

This specifies the length: new Timecode(5.0)

That's 5 Milliseconds long! I would change "new Timecode(5.0)" to "Timecode.FromSeconds(5)" so the line would now read:

VideoEvent videoEvent = vidTrack.AddVideoEvent(cursorPosition, Timecode.FromSeconds(5.0));

Then get rid of this - it does NOTHING:

 // Set the generator preset to the title text 
 media.Generator.Preset = title; 

And then use my code to change the text between these two lines:

 Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0)); 
 return videoEvent.End;

 

jetdv wrote on 7/15/2023, 12:22 PM

@Connor-Fadden - now each one is 5 seconds long and the text gets changed:
 

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

namespace SampleScript1
{
    public class EntryPoint
    {
        public void FromVegas(Vegas vegas)
        {
            // Open a dialog box to select a folder
            string selectedFolder = SelectFolder();
            if (selectedFolder == null)
            {
                MessageBox.Show("No folder selected.");
                return;
            }
            
            // Find the 'titles.txt' file in the selected folder
            string titlesFilePath = Path.Combine(selectedFolder, "titles.txt");
            if (!File.Exists(titlesFilePath))
            {
                MessageBox.Show("Could not find 'titles.txt' in the selected folder.");
                return;
            }
            
            // Read the file and extract the titles
            string[] titles = File.ReadAllLines(titlesFilePath);
            
            // Insert the titles into the timeline
            int trackIndex = 0;

            // Target track index
            Timecode cursorPosition = vegas.Transport.CursorPosition;
            foreach (string title in titles)
            {
                cursorPosition = AddTitleAt(vegas, title, trackIndex, cursorPosition);
            }
            MessageBox.Show("Titles inserted successfully.");
        }

        private string SelectFolder()
        {
            using (var dialog = new FolderBrowserDialog())
            {
                dialog.Description = "Select a folder"; dialog.ShowNewFolderButton = false;
                if (dialog.ShowDialog() == DialogResult.OK) { return dialog.SelectedPath; }
            }
            return null;
        }
        private Timecode AddTitleAt(Vegas vegas, string title, int trackIndex, Timecode cursorPosition)
        {
            // Create a new video track if it doesn't exist
            while (vegas.Project.Tracks.Count <= trackIndex)
            {
                vegas.Project.AddVideoTrack();
            }

            // Find the text generator plug-in
            PlugInNode plugIn = vegas.Generators.GetChildByName("Titles & Text");
            if (plugIn == null)
            {
                MessageBox.Show("Could not find 'Titles & Text' generator.");
                return cursorPosition;
            }

            // Create a media object with the generator plug-in
            Media media = new Media(plugIn);

            // Create a new video event in the track
            VideoTrack vidTrack = (VideoTrack)vegas.Project.Tracks[trackIndex];
            VideoEvent videoEvent = vidTrack.AddVideoEvent(cursorPosition, Timecode.FromSeconds(5.0));

            // Add the take using the generated video stream
            Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0));

            //Get the OFX plugin
            Effect gEffect = videoEvent.ActiveTake.Media.Generator;
            OFXEffect fxo = gEffect.OFXEffect;

            //Modify the text!
            OFXStringParameter tparm = (OFXStringParameter)fxo.FindParameterByName("Text");
            RichTextBox rtfText = new RichTextBox();

            rtfText.Text = title;
            rtfText.SelectAll();
            rtfText.SelectionFont = new Font("Times New Roman", 24, FontStyle.Bold) ;
            tparm.Value = rtfText.Rtf;

            //Apply all changes
            fxo.AllParametersChanged();

            return videoEvent.End;
        }
    }
}

 

jetdv wrote on 7/15/2023, 12:35 PM

@Connor-Fadden And now modified so that:

  1. It does not have to check to see if a new track needs to be created on every title
  2. The "vegas" variable no longer needs to be passed to a subroutine - just use "myVegas" instead in the subroutines
  3. The plugin will now work with any language by using the GUID to find the plugin
  4. The events will be shown as each one is added - this does eliminate the possibility of some later events being placed in the wrong location too
     
using System;
using System.IO;
using System.Windows.Forms;
using System.Globalization;
using System.Drawing;
using ScriptPortal.Vegas;

namespace SampleScript1
{
    public class EntryPoint
    {
        Vegas myVegas;

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

            // Open a dialog box to select a folder
            string selectedFolder = SelectFolder();
            if (selectedFolder == null)
            {
                MessageBox.Show("No folder selected.");
                return;
            }
            
            // Find the 'titles.txt' file in the selected folder
            string titlesFilePath = Path.Combine(selectedFolder, "titles.txt");
            if (!File.Exists(titlesFilePath))
            {
                MessageBox.Show("Could not find 'titles.txt' in the selected folder.");
                return;
            }
            
            // Read the file and extract the titles
            string[] titles = File.ReadAllLines(titlesFilePath);

            // Insert the titles into the timeline
            // Target track index
            int trackIndex = 0;
            // Create a new video track if it doesn't exist
            while (myVegas.Project.Tracks.Count <= trackIndex)
            {
                myVegas.Project.AddVideoTrack();
            }

            Timecode cursorPosition = vegas.Transport.CursorPosition;
            foreach (string title in titles)
            {
                cursorPosition = AddTitleAt(title, trackIndex, cursorPosition);
                myVegas.UpdateUI();
            }
            MessageBox.Show("Titles inserted successfully.");
        }

        private string SelectFolder()
        {
            using (var dialog = new FolderBrowserDialog())
            {
                dialog.Description = "Select a folder"; dialog.ShowNewFolderButton = false;
                if (dialog.ShowDialog() == DialogResult.OK) { return dialog.SelectedPath; }
            }
            return null;
        }

        private Timecode AddTitleAt(string title, int trackIndex, Timecode cursorPosition)
        {
            // Find the text generator plug-in
            string genUID = "{Svfx:com.vegascreativesoftware:titlesandtext}"; //Magix Titles & Text
            PlugInNode plugIn = null;
            plugIn = myVegas.Generators.GetChildByUniqueID(genUID);
            if (plugIn == null)
            {
                MessageBox.Show("Could not find 'Titles & Text' generator.");
                return cursorPosition;
            }

            // Create a media object with the generator plug-in
            Media media = new Media(plugIn);

            // Create a new video event in the track
            VideoTrack vidTrack = (VideoTrack)myVegas.Project.Tracks[trackIndex];
            VideoEvent videoEvent = vidTrack.AddVideoEvent(cursorPosition, Timecode.FromSeconds(5.0));

            // Add the take using the generated video stream
            Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0));

            //Get the OFX plugin
            Effect gEffect = videoEvent.ActiveTake.Media.Generator;
            OFXEffect fxo = gEffect.OFXEffect;

            //Modify the text!
            OFXStringParameter tparm = (OFXStringParameter)fxo.FindParameterByName("Text");
            RichTextBox rtfText = new RichTextBox();

            rtfText.Text = title;
            rtfText.SelectAll();
            rtfText.SelectionFont = new Font("Times New Roman", 24, FontStyle.Bold) ;
            tparm.Value = rtfText.Rtf;

            //Apply all changes
            fxo.AllParametersChanged();

            return videoEvent.End;
        }
    }
}

 

Connor-Fadden wrote on 7/15/2023, 4:46 PM

@Connor-Fadden And now modified so that:

  1. It does not have to check to see if a new track needs to be created on every title
  2. The "vegas" variable no longer needs to be passed to a subroutine - just use "myVegas" instead in the subroutines
  3. The plugin will now work with any language by using the GUID to find the plugin
  4. The events will be shown as each one is added - this does eliminate the possibility of some later events being placed in the wrong location too
     
using System;
using System.IO;
using System.Windows.Forms;
using System.Globalization;
using System.Drawing;
using ScriptPortal.Vegas;

namespace SampleScript1
{
    public class EntryPoint
    {
        Vegas myVegas;

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

            // Open a dialog box to select a folder
            string selectedFolder = SelectFolder();
            if (selectedFolder == null)
            {
                MessageBox.Show("No folder selected.");
                return;
            }
            
            // Find the 'titles.txt' file in the selected folder
            string titlesFilePath = Path.Combine(selectedFolder, "titles.txt");
            if (!File.Exists(titlesFilePath))
            {
                MessageBox.Show("Could not find 'titles.txt' in the selected folder.");
                return;
            }
            
            // Read the file and extract the titles
            string[] titles = File.ReadAllLines(titlesFilePath);

            // Insert the titles into the timeline
            // Target track index
            int trackIndex = 0;
            // Create a new video track if it doesn't exist
            while (myVegas.Project.Tracks.Count <= trackIndex)
            {
                myVegas.Project.AddVideoTrack();
            }

            Timecode cursorPosition = vegas.Transport.CursorPosition;
            foreach (string title in titles)
            {
                cursorPosition = AddTitleAt(title, trackIndex, cursorPosition);
                myVegas.UpdateUI();
            }
            MessageBox.Show("Titles inserted successfully.");
        }

        private string SelectFolder()
        {
            using (var dialog = new FolderBrowserDialog())
            {
                dialog.Description = "Select a folder"; dialog.ShowNewFolderButton = false;
                if (dialog.ShowDialog() == DialogResult.OK) { return dialog.SelectedPath; }
            }
            return null;
        }

        private Timecode AddTitleAt(string title, int trackIndex, Timecode cursorPosition)
        {
            // Find the text generator plug-in
            string genUID = "{Svfx:com.vegascreativesoftware:titlesandtext}"; //Magix Titles & Text
            PlugInNode plugIn = null;
            plugIn = myVegas.Generators.GetChildByUniqueID(genUID);
            if (plugIn == null)
            {
                MessageBox.Show("Could not find 'Titles & Text' generator.");
                return cursorPosition;
            }

            // Create a media object with the generator plug-in
            Media media = new Media(plugIn);

            // Create a new video event in the track
            VideoTrack vidTrack = (VideoTrack)myVegas.Project.Tracks[trackIndex];
            VideoEvent videoEvent = vidTrack.AddVideoEvent(cursorPosition, Timecode.FromSeconds(5.0));

            // Add the take using the generated video stream
            Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0));

            //Get the OFX plugin
            Effect gEffect = videoEvent.ActiveTake.Media.Generator;
            OFXEffect fxo = gEffect.OFXEffect;

            //Modify the text!
            OFXStringParameter tparm = (OFXStringParameter)fxo.FindParameterByName("Text");
            RichTextBox rtfText = new RichTextBox();

            rtfText.Text = title;
            rtfText.SelectAll();
            rtfText.SelectionFont = new Font("Times New Roman", 24, FontStyle.Bold) ;
            tparm.Value = rtfText.Rtf;

            //Apply all changes
            fxo.AllParametersChanged();

            return videoEvent.End;
        }
    }
}

 

Jet you're a life saver!! It works amazingly! However, when I try to set some things like the outline and animation, it doesn't want to work. I think I'm getting some lingo wrong in the code. Does anything stick out?

jetdv wrote on 7/15/2023, 9:41 PM

@Connor-Fadden - here's a few corrections.

OFXColorParameter is not a valid parameter type. Outline Color is of type OFXRGBAParameter.

For the Choice, you have to do it like the tutorial shows:

anchorPoint.Value = anchorPoint.Choices[0]; <-- you have to use the "number" of the choice you want

Outline Color is named "OutlineColor"

Outline Width is named "OutlineWidth"

Animation is actually named "choice"

            OFXRGBAParameter oparm = (OFXRGBAParameter)fxo.FindParameterByName("OutlineColor");
            oparm.Value = SetColor(0, 0, 0);

            OFXDoubleParameter wparm = (OFXDoubleParameter)fxo.FindParameterByName("OutlineWidth");
            wparm.Value = 5.782;

            OFXChoiceParameter aparm = (OFXChoiceParameter)fxo.FindParameterByName("collection");
            aparm.Value = aparm.Choices[15]; //Use whatever number the choice is in the list minus 1 - I just used a random number here.

And the new "Set Color" routine:

        OFXColor SetColor(int r, int g, int b)
        {
            OFXColor oc = new OFXColor;
            oc.R = r;
            oc.G = g;
            oc.B = b;

            return oc;
        }

 

Connor-Fadden wrote on 7/16/2023, 3:47 AM

@Connor-Fadden - here's a few corrections.

OFXColorParameter is not a valid parameter type. Outline Color is of type OFXRGBAParameter.

For the Choice, you have to do it like the tutorial shows:

anchorPoint.Value = anchorPoint.Choices[0]; <-- you have to use the "number" of the choice you want

Outline Color is named "OutlineColor"

Outline Width is named "OutlineWidth"

Animation is actually named "choice"

            OFXRGBAParameter oparm = (OFXRGBAParameter)fxo.FindParameterByName("OutlineColor");
            oparm.Value = SetColor(0, 0, 0);

            OFXDoubleParameter wparm = (OFXDoubleParameter)fxo.FindParameterByName("OutlineWidth");
            wparm.Value = 5.782;

            OFXChoiceParameter aparm = (OFXChoiceParameter)fxo.FindParameterByName("collection");
            aparm.Value = aparm.Choices[15]; //Use whatever number the choice is in the list minus 1 - I just used a random number here.

And the new "Set Color" routine:

        OFXColor SetColor(int r, int g, int b)
        {
            OFXColor oc = new OFXColor;
            oc.R = r;
            oc.G = g;
            oc.B = b;

            return oc;
        }

Thank you so much for all of these fixes, it really helps! I'm currently getting this error: C:\Users\Connor\Desktop\VS Code Projects\vegas pro scripts\generate_titles.cs(113) : Cannot implicitly convert type 'System.Drawing.Color' to 'ScriptPortal.Vegas.OFXColor'

And I'm confused, is animation 'choice' or 'collection'?

 

jetdv wrote on 7/16/2023, 7:55 AM

@Connor-Fadden You're under a misconception. An "OFXColor" is not the same as a "Color". I did make a mistake in my Set Color routine. It should have been:

        OFXColor SetColor(int r, int g, int b)
        {
            OFXColor oc = new OFXColor();
            oc.R = r / 255;
            oc.G = g / 255;
            oc.B = b / 255;

            return oc;
        }

A "Color" has rgb byte values from 0 to 255. An "OFXColor" has rgb double values from 0 to 1. If you insist on creating a "Color" variable, that can be passed to the SetColor routine instead but you'll still need to convert each individual r, g, and b value from 0-255 to 0-1. In short, a "Color" cannot be simply converted to an "OFXColor" - you need to manually convert each value individually. Here's some modified SetColor routines that would accept either RGB values or a "Color" variable:
 

        OFXColor SetOFXColor(int r, int g, int b)
        {
            OFXColor oc = new OFXColor();
            oc.R = r / 255;
            oc.G = g / 255;
            oc.B = b / 255;

            return oc;
        }

        OFXColor SetOFXColorFromColor(Color myColor)
        {
            OFXColor oc = new OFXColor();
            oc.R = myColor.R / 255;
            oc.G = myColor.G / 255;
            oc.B = myColor.B / 255;
            oc.A = myColor.A / 255;

            return oc;
        }

And then in the main routine you could do this:

            OFXRGBAParameter oparm = (OFXRGBAParameter)fxo.FindParameterByName("OutlineColor");
            oparm.Value = SetOFXColorFromColor(Color.FromArgb(0, 0, 0));

As for the "Animation" parameter - it is a "Choice" parameter. However, the internal NAME of that parameter is "collection" (Why it was named "collection" and not "Animation" I can't say.) When searching for the parameter, you have to search for the name of that parameter and Animation just happens to be named "collection".

Here's all of the Titles and Text parameters read directly from Titles and Text:

Track 1  Event at 00:00:00;00
Titles & Text      Parameter Name: Text     Parameter Label: Text     of type: String
Titles & Text      Parameter Name: TextColor     Parameter Label: Text color     of type: RGBA
Titles & Text      Parameter Name: collection     Parameter Label: Animation     of type: Choice

Titles & Text      Parameter Name: AnimationName     Parameter Label: Animation Name     of type: String
Titles & Text      Parameter Name: Scale     Parameter Label: Scale     of type: Double
Titles & Text      Parameter Name: Location     Parameter Label: Location     of type: Double2D
Titles & Text      Parameter Name: Alignment     Parameter Label: Anchor Point     of type: Choice
Titles & Text      Parameter Name: AdvancedGroup     Parameter Label: Advanced     of type: Group
Titles & Text      Parameter Name: FitBackgroundColor     Parameter Label: Crop background to text     of type: Boolean
Titles & Text      Parameter Name: Background     Parameter Label: Background     of type: RGBA
Titles & Text      Parameter Name: Tracking     Parameter Label: Tracking     of type: Double
Titles & Text      Parameter Name: LineSpacing     Parameter Label: Line spacing     of type: Double
Titles & Text      Parameter Name: OutlineGroup     Parameter Label: Outline     of type: Group
Titles & Text      Parameter Name: OutlineWidth     Parameter Label: Outline width     of type: Double

Titles & Text      Parameter Name: OutlineColor     Parameter Label: Outline color     of type: RGBA

Titles & Text      Parameter Name: ShadowGroup     Parameter Label: Shadow     of type: Group
Titles & Text      Parameter Name: ShadowEnable     Parameter Label: Shadow enable     of type: Boolean
Titles & Text      Parameter Name: ShadowColor     Parameter Label: Shadow color     of type: RGBA
Titles & Text      Parameter Name: ShadowOffsetX     Parameter Label: Shadow offset X     of type: Double
Titles & Text      Parameter Name: ShadowOffsetY     Parameter Label: Shadow offset Y     of type: Double
Titles & Text      Parameter Name: ShadowBlur     Parameter Label: Shadow blur     of type: Double
Titles & Text      Parameter Name: Controls     Parameter Label:      of type: Page

 

jetdv wrote on 7/16/2023, 8:08 AM

@Connor-Fadden I also see (from the image) that it appear you are using Visual Studio Code to enter your code? If you use Visual Studio instead (the "Community" version is free to use), you can get code completion. So when you type in OFX, for example, you would see:

Then you simply need to scroll down to the proper entry. And this was an easy way to also tell that "OFXColorParameter" did not exist. Please see here on how to make that functional:

Also, did you download the API?

https://www.vegascreativesoftware.com/fileadmin/user_upload/non_product/downloads/vegas_scripting_api.zip

 

Connor-Fadden wrote on 7/16/2023, 9:18 AM

@Connor-Fadden I also see (from the image) that it appear you are using Visual Studio Code to enter your code? If you use Visual Studio instead (the "Community" version is free to use), you can get code completion. So when you type in OFX, for example, you would see:

Then you simply need to scroll down to the proper entry. And this was an easy way to also tell that "OFXColorParameter" did not exist. Please see here on how to make that functional:

Also, did you download the API?

https://www.vegascreativesoftware.com/fileadmin/user_upload/non_product/downloads/vegas_scripting_api.zip

 

Where exactly should the Set color routine be placed? I'm placing it before the oparm outline color setting, but it seems to break everything ;(

 

I just downloaded the API, I'll take a look through it

jetdv wrote on 7/16/2023, 12:11 PM

It's a subroutine the same as SelectFolder and AddTitleAt. It cannot be placed in the middle of another subroutine. Here's where I put them for my testing:

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

namespace SampleScript1
{
    public class EntryPoint
    {
        Vegas myVegas;

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

            // Open a dialog box to select a folder
            string selectedFolder = SelectFolder();
            if (selectedFolder == null)
            {
                MessageBox.Show("No folder selected.");
                return;
            }
            
            // Find the 'titles.txt' file in the selected folder
            string titlesFilePath = Path.Combine(selectedFolder, "titles.txt");
            if (!File.Exists(titlesFilePath))
            {
                MessageBox.Show("Could not find 'titles.txt' in the selected folder.");
                return;
            }
            
            // Read the file and extract the titles
            string[] titles = File.ReadAllLines(titlesFilePath);

            // Insert the titles into the timeline
            // Target track index
            int trackIndex = 0;
            // Create a new video track if it doesn't exist
            while (myVegas.Project.Tracks.Count <= trackIndex)
            {
                myVegas.Project.AddVideoTrack();
            }

            Timecode cursorPosition = vegas.Transport.CursorPosition;
            foreach (string title in titles)
            {
                cursorPosition = AddTitleAt(title, trackIndex, cursorPosition);
                myVegas.UpdateUI();
            }
            MessageBox.Show("Titles inserted successfully.");
        }

        private string SelectFolder()
        {
            using (var dialog = new FolderBrowserDialog())
            {
                dialog.Description = "Select a folder"; dialog.ShowNewFolderButton = false;
                if (dialog.ShowDialog() == DialogResult.OK) { return dialog.SelectedPath; }
            }
            return null;
        }

        private Timecode AddTitleAt(string title, int trackIndex, Timecode cursorPosition)
        {
            // Find the text generator plug-in
            string genUID = "{Svfx:com.vegascreativesoftware:titlesandtext}"; //Magix Titles & Text
            PlugInNode plugIn = null;
            plugIn = myVegas.Generators.GetChildByUniqueID(genUID);
            if (plugIn == null)
            {
                MessageBox.Show("Could not find 'Titles & Text' generator.");
                return cursorPosition;
            }

            // Create a media object with the generator plug-in
            Media media = new Media(plugIn);

            // Create a new video event in the track
            VideoTrack vidTrack = (VideoTrack)myVegas.Project.Tracks[trackIndex];
            VideoEvent videoEvent = vidTrack.AddVideoEvent(cursorPosition, Timecode.FromSeconds(5.0));

            // Add the take using the generated video stream
            Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0));

            //Get the OFX plugin
            Effect gEffect = videoEvent.ActiveTake.Media.Generator;
            OFXEffect fxo = gEffect.OFXEffect;

            //Modify the text!
            OFXStringParameter tparm = (OFXStringParameter)fxo.FindParameterByName("Text");
            RichTextBox rtfText = new RichTextBox();

            OFXRGBAParameter oparm = (OFXRGBAParameter)fxo.FindParameterByName("OutlineColor");
            oparm.Value = SetOFXColorFromColor(Color.FromArgb(0, 0, 0));
            oparm.Value = SetOFXColor(0, 0, 0);

            OFXDoubleParameter wparm = (OFXDoubleParameter)fxo.FindParameterByName("OutlineWidth");
            wparm.Value = 5.782;

            OFXChoiceParameter aparm = (OFXChoiceParameter)fxo.FindParameterByName("collection");
            aparm.Value = aparm.Choices[15]; //Use whatever number the choice is in the list minus 1

            rtfText.Text = title;
            rtfText.SelectAll();
            rtfText.SelectionFont = new Font("Times New Roman", 24, FontStyle.Bold) ;
            tparm.Value = rtfText.Rtf;

            //Apply all changes
            fxo.AllParametersChanged();

            return videoEvent.End;
        }

        private OFXColor SetOFXColor(int r, int g, int b)
        {
            OFXColor oc = new OFXColor();
            oc.R = r / 255;
            oc.G = g / 255;
            oc.B = b / 255;

            return oc;
        }

        private OFXColor SetOFXColorFromColor(Color myColor)
        {
            OFXColor oc = new OFXColor();
            oc.R = myColor.R / 255;
            oc.G = myColor.G / 255;
            oc.B = myColor.B / 255;
            oc.A = myColor.A / 255;

            return oc;
        }
    }
}

But they could have been placed in other places and still worked such as above the line private string SelectFolder() or above the line private Timecode AddTitleAt(string title, int trackIndex, Timecode cursorPosition)

 

Connor-Fadden wrote on 7/16/2023, 5:01 PM

It's a subroutine the same as SelectFolder and AddTitleAt. It cannot be placed in the middle of another subroutine. Here's where I put them for my testing:

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

namespace SampleScript1
{
    public class EntryPoint
    {
        Vegas myVegas;

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

            // Open a dialog box to select a folder
            string selectedFolder = SelectFolder();
            if (selectedFolder == null)
            {
                MessageBox.Show("No folder selected.");
                return;
            }
            
            // Find the 'titles.txt' file in the selected folder
            string titlesFilePath = Path.Combine(selectedFolder, "titles.txt");
            if (!File.Exists(titlesFilePath))
            {
                MessageBox.Show("Could not find 'titles.txt' in the selected folder.");
                return;
            }
            
            // Read the file and extract the titles
            string[] titles = File.ReadAllLines(titlesFilePath);

            // Insert the titles into the timeline
            // Target track index
            int trackIndex = 0;
            // Create a new video track if it doesn't exist
            while (myVegas.Project.Tracks.Count <= trackIndex)
            {
                myVegas.Project.AddVideoTrack();
            }

            Timecode cursorPosition = vegas.Transport.CursorPosition;
            foreach (string title in titles)
            {
                cursorPosition = AddTitleAt(title, trackIndex, cursorPosition);
                myVegas.UpdateUI();
            }
            MessageBox.Show("Titles inserted successfully.");
        }

        private string SelectFolder()
        {
            using (var dialog = new FolderBrowserDialog())
            {
                dialog.Description = "Select a folder"; dialog.ShowNewFolderButton = false;
                if (dialog.ShowDialog() == DialogResult.OK) { return dialog.SelectedPath; }
            }
            return null;
        }

        private Timecode AddTitleAt(string title, int trackIndex, Timecode cursorPosition)
        {
            // Find the text generator plug-in
            string genUID = "{Svfx:com.vegascreativesoftware:titlesandtext}"; //Magix Titles & Text
            PlugInNode plugIn = null;
            plugIn = myVegas.Generators.GetChildByUniqueID(genUID);
            if (plugIn == null)
            {
                MessageBox.Show("Could not find 'Titles & Text' generator.");
                return cursorPosition;
            }

            // Create a media object with the generator plug-in
            Media media = new Media(plugIn);

            // Create a new video event in the track
            VideoTrack vidTrack = (VideoTrack)myVegas.Project.Tracks[trackIndex];
            VideoEvent videoEvent = vidTrack.AddVideoEvent(cursorPosition, Timecode.FromSeconds(5.0));

            // Add the take using the generated video stream
            Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0));

            //Get the OFX plugin
            Effect gEffect = videoEvent.ActiveTake.Media.Generator;
            OFXEffect fxo = gEffect.OFXEffect;

            //Modify the text!
            OFXStringParameter tparm = (OFXStringParameter)fxo.FindParameterByName("Text");
            RichTextBox rtfText = new RichTextBox();

            OFXRGBAParameter oparm = (OFXRGBAParameter)fxo.FindParameterByName("OutlineColor");
            oparm.Value = SetOFXColorFromColor(Color.FromArgb(0, 0, 0));
            oparm.Value = SetOFXColor(0, 0, 0);

            OFXDoubleParameter wparm = (OFXDoubleParameter)fxo.FindParameterByName("OutlineWidth");
            wparm.Value = 5.782;

            OFXChoiceParameter aparm = (OFXChoiceParameter)fxo.FindParameterByName("collection");
            aparm.Value = aparm.Choices[15]; //Use whatever number the choice is in the list minus 1

            rtfText.Text = title;
            rtfText.SelectAll();
            rtfText.SelectionFont = new Font("Times New Roman", 24, FontStyle.Bold) ;
            tparm.Value = rtfText.Rtf;

            //Apply all changes
            fxo.AllParametersChanged();

            return videoEvent.End;
        }

        private OFXColor SetOFXColor(int r, int g, int b)
        {
            OFXColor oc = new OFXColor();
            oc.R = r / 255;
            oc.G = g / 255;
            oc.B = b / 255;

            return oc;
        }

        private OFXColor SetOFXColorFromColor(Color myColor)
        {
            OFXColor oc = new OFXColor();
            oc.R = myColor.R / 255;
            oc.G = myColor.G / 255;
            oc.B = myColor.B / 255;
            oc.A = myColor.A / 255;

            return oc;
        }
    }
}

But they could have been placed in other places and still worked such as above the line private string SelectFolder() or above the line private Timecode AddTitleAt(string title, int trackIndex, Timecode cursorPosition)

 

That seems to work amazingly! Except the outline color is set at 0 opacity for some reason, and it won't let me add in a 4th value for the color to set alpha to 1.

The animation also just doesn't seem to be set at all. I've tried messing around with the Choices value but it never seems to set an animation on the titles.

Connor-Fadden wrote on 7/16/2023, 5:02 PM

Also do you know if it's possible to automatically apply a custom pan/crop setting to every media item I add to the timeline?

jetdv wrote on 7/16/2023, 8:55 PM

@Connor-Fadden You need to specify the alpha. I don't know which line you're using. I tested with the second line where I added the alpha value which required changing the SetOFXColor routine.

            oparm.Value = SetOFXColorFromColor(Color.FromArgb(255, 0, 0, 0));
            oparm.Value = SetOFXColor(0, 0, 0, 255);

Notice the change to this routine: , int a added in the definition and the oc.A = a / 255; in the main body:

        private OFXColor SetOFXColor(int r, int g, int b, int a)
        {
            OFXColor oc = new OFXColor();
            oc.R = r / 255;
            oc.G = g / 255;
            oc.B = b / 255;
            oc.A = a / 255;

            return oc;
        }

That appears to set the alpha properly in my testing.

You are correct that the "Choice" does not appear to be changed. I'm not sure why that's happening. Here's my current version with the alpha properly setting:

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

namespace SampleScript1
{
    public class EntryPoint
    {
        Vegas myVegas;

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

            // Open a dialog box to select a folder
            string selectedFolder = SelectFolder();
            if (selectedFolder == null)
            {
                MessageBox.Show("No folder selected.");
                return;
            }
            
            // Find the 'titles.txt' file in the selected folder
            string titlesFilePath = Path.Combine(selectedFolder, "titles.txt");
            if (!File.Exists(titlesFilePath))
            {
                MessageBox.Show("Could not find 'titles.txt' in the selected folder.");
                return;
            }
            
            // Read the file and extract the titles
            string[] titles = File.ReadAllLines(titlesFilePath);

            // Insert the titles into the timeline
            // Target track index
            int trackIndex = 0;
            // Create a new video track if it doesn't exist
            while (myVegas.Project.Tracks.Count <= trackIndex)
            {
                myVegas.Project.AddVideoTrack();
            }

            Timecode cursorPosition = vegas.Transport.CursorPosition;
            foreach (string title in titles)
            {
                cursorPosition = AddTitleAt(title, trackIndex, cursorPosition);
                myVegas.UpdateUI();
            }
            MessageBox.Show("Titles inserted successfully.");
        }

        private string SelectFolder()
        {
            using (var dialog = new FolderBrowserDialog())
            {
                dialog.Description = "Select a folder"; dialog.ShowNewFolderButton = false;
                if (dialog.ShowDialog() == DialogResult.OK) { return dialog.SelectedPath; }
            }
            return null;
        }

        private Timecode AddTitleAt(string title, int trackIndex, Timecode cursorPosition)
        {
            // Find the text generator plug-in
            string genUID = "{Svfx:com.vegascreativesoftware:titlesandtext}"; //Magix Titles & Text
            PlugInNode plugIn = null;
            plugIn = myVegas.Generators.GetChildByUniqueID(genUID);
            if (plugIn == null)
            {
                MessageBox.Show("Could not find 'Titles & Text' generator.");
                return cursorPosition;
            }

            // Create a media object with the generator plug-in
            Media media = new Media(plugIn);

            // Create a new video event in the track
            VideoTrack vidTrack = (VideoTrack)myVegas.Project.Tracks[trackIndex];
            VideoEvent videoEvent = vidTrack.AddVideoEvent(cursorPosition, Timecode.FromSeconds(5.0));

            // Add the take using the generated video stream
            Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0));

            //Get the OFX plugin
            Effect gEffect = videoEvent.ActiveTake.Media.Generator;
            OFXEffect fxo = gEffect.OFXEffect;

            //Modify the text!
            OFXStringParameter tparm = (OFXStringParameter)fxo.FindParameterByName("Text");
            RichTextBox rtfText = new RichTextBox();

            OFXRGBAParameter oparm = (OFXRGBAParameter)fxo.FindParameterByName("OutlineColor");
            oparm.Value = SetOFXColor(0, 0, 0, 255);

            OFXDoubleParameter wparm = (OFXDoubleParameter)fxo.FindParameterByName("OutlineWidth");
            wparm.Value = 5.782;

            OFXChoiceParameter aparm = (OFXChoiceParameter)fxo.FindParameterByName("collection");
            aparm.Value = aparm.Choices[1]; //Use whatever number the choice is in the list minus 1

            rtfText.Text = title;
            rtfText.SelectAll();
            rtfText.SelectionFont = new Font("Times New Roman", 24, FontStyle.Bold) ;
            tparm.Value = rtfText.Rtf;

            //Apply all changes
            fxo.AllParametersChanged();

            return videoEvent.End;
        }

        private OFXColor SetOFXColor(int r, int g, int b, int a)
        {
            OFXColor oc = new OFXColor();
            oc.R = r / 255;
            oc.G = g / 255;
            oc.B = b / 255;
            oc.A = a / 255;

            return oc;
        }

    }
}

Also do you know if it's possible to automatically apply a custom pan/crop setting to every media item I add to the timeline?

Yes it is! Several tutorials on my YouTube channel deal with that topic. Start here:

There are several others but these two will get you started. Please do go through the tutorials on my channel - I think you'll find them interesting.