VP21 Build 314 (Script Issue)

joelsonforte.br wrote on 5/20/2024, 4:13 PM

Can anyone help me with a recent scripting issue I encountered with the new Vegas Pro 21 Build 314?

I get this error message.

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at ScriptPortal.Vegas.Media..ctor(Project project, PlugInNode generator, String presetName)
   at ImportSRTasTextEvents.EntryPoint.AddTextEvent(Vegas vegas, Track myNewTrack, Timecode myEvStart, Timecode myEvLength, String myText)
   at ImportSRTasTextEvents.EntryPoint.FromVegas(Vegas vegas)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at ScriptPortal.Vegas.ScriptHost.ScriptManager.Run(Assembly asm, String className, String methodName)
   at ScriptPortal.Vegas.ScriptHost.RunScript(Boolean fCompileOnly)

This is the script where the error message appears. Is a script that was made to import .srt files as quantized or non-quantized text events into the Vegas timeline. This script works fine in all previous versions of Vegas Pro, including version 21 Build 300. I don't know what changed in Vegas 21 Build 314 that causes this problem in the script. Any help to resolve this issue is welcome.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using ScriptPortal.Vegas;

namespace ImportSRTasTextEvents
{
    public class SrtInfo
    {
        private Timecode startTime;
        private Timecode endTime;
        private List<string> subs;

        public Timecode getStartTime()
        {
            return startTime;
        }

        public Timecode getEndTime()
        {
            return endTime;
        }

        public Timecode getEndMinusStartTime()
        {
            return (endTime - startTime);
        }

        public string getText()
        {
            string s = "";
            int i;

            for (i = 0; i < subs.Count; ++i)
            {
                s += subs[i];
                if (i != subs.Count - 1)
                    s += "\r\n";
            }

            return s;
        }

        public SrtInfo(List<string> input)
        {
            string[] timeStrings = input[1].Split(((string)" ").ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            startTime = new Timecode(timeStrings[0]);
            endTime = new Timecode(timeStrings[2]);

            subs = new List<string>();
            for (int subtitles = 2; subtitles < input.Count; ++subtitles)
            {
                subs.Add(input[subtitles]);
            }
        }

    }

    public class EntryPoint
    {
        Vegas myVegas;
        RulerFormat OrgRulerFormat;

        public void FromVegas(Vegas vegas)
        {
            myVegas = vegas;
            OrgRulerFormat = myVegas.Project.Ruler.Format;
            myVegas.Project.Ruler.Format = RulerFormat.Time;
            myVegas.UpdateUI();

            vegas.UnloadScriptDomainOnScriptExit = true;

            Project proj = vegas.Project;
            List<SrtInfo> subs = new List<SrtInfo>();
            string s = "";
            int currentLineIndex = 0;

            //load all the lines from the *.srt to a linked list
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.CheckFileExists = true;
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                // read in the file            
                List<string> inputStrings = new List<string>();
                using (StreamReader sr = new StreamReader(fileDialog.FileName, Encoding.UTF8))
                {
                    try
                    {
                        bool isNotEmptySubtitle = false;

                        while ((s = sr.ReadLine()) != null)
                        {
                            currentLineIndex++;
                            if (s.Length != 0)
                            {
                                inputStrings.Add(s);
                                isNotEmptySubtitle = true;
                            }
                            else if (inputStrings.Count > 1)
                            {
                                subs.Add(new SrtInfo(inputStrings));
                                inputStrings.Clear();
                                isNotEmptySubtitle = false;
                            }
                        }

                        if (isNotEmptySubtitle && inputStrings.Count > 1)
                        {
                            subs.Add(new SrtInfo(inputStrings));
                        }
                    }
                    catch (Exception e)
                    {
                        CustomMessageBox.Show(String.Format("Error reading the file. Maybe an invalid *.srt file. Error occurred at line: {0}\r\nError message: {1}\r\nDetailed error message for debugging: {2}", currentLineIndex, e.Message, e.ToString()), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        CustomMessageBox.Show(String.Format("There has been an error while importing the subtitles. The subtitles and their timings may not be loaded correctly. Look it up, what could be the problem in your *.srt file around line {0}.\r\nFor example too many empty lines or the timecode format is wrong.", currentLineIndex), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }

                // Ask user if they want to quantize text events
                DialogResult quantizeResult = MessageBox.Show("Do You Want Quantize Text Events to Frames?", "Quantize Text Events", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                //a new Track with TrackEvents
                myVegas.Project.Ruler.Format = OrgRulerFormat;
                VideoTrack track = new VideoTrack();
                proj.Tracks.Add(track);

                foreach (SrtInfo x in subs)
                {
                    try
                    {
                        if (x.getStartTime().ToMilliseconds() == x.getEndTime().ToMilliseconds())
                        {
                            throw new Exception(String.Format("Error! Some subtitles have the same timecodes for the times they should appear and disappear. Check the subtitle at {0} -> {1}, because it may not have been loaded at the correct timecode!\r\nAlso, it may have loaded as a Marker instead of a Region.", x.getStartTime().ToString(), x.getEndTime().ToString()));
                        }
                    }
                    catch (Exception e)
                    {
                        CustomMessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                    if (quantizeResult == DialogResult.Yes)
                    {
                        AddTextEventQuantized(myVegas, track, x.getStartTime(), x.getEndMinusStartTime(), x.getText());
                    }
                    else
                    {
                        AddTextEvent(myVegas, track, x.getStartTime(), x.getEndMinusStartTime(), x.getText());
                    }
                }
                // Aqui é onde você pode adicionar a mensagem de conclusão do processo
                //CustomMessageBox.Show("Subtitles Imported Successfully!", "Message!", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        void AddTextEvent(Vegas vegas, Track myNewTrack, Timecode myEvStart, Timecode myEvLength, string myText)
        {
            // Set Titles & Text for VEGAS Pro 17 or Higher
            string genUID = "{Svfx:com.vegascreativesoftware:titlesandtext}"; //VEGAS Titles & Text  

            // Set Titles & Text for VEGAS Pro 14-16
            if (myVegas.Version.Contains("14") || myVegas.Version.Contains("15") || myVegas.Version.Contains("16"))
            { genUID = "{Svfx:com.sonycreativesoftware:titlesandtext}"; } //Sony Titles & Text      

            // find the text generator plug-in
            //MessageBox.Show(vegas.Generators.GetChildByName("VEGAS Titles & Text").ToString());        
            PlugInNode plugIn = null;
            plugIn = myVegas.Generators.GetChildByUniqueID(genUID);

            Media media = new Media(plugIn);
            MediaStream stream = media.Streams.GetItemByMediaType(MediaType.Video, 0);
            //VideoEvent newEvent = new VideoEvent(myVegas.Transport.CursorPosition, Timecode.FromSeconds(15)); //15 seconds long !!!
            VideoEvent newEvent = new VideoEvent((myVegas.Transport.CursorPosition + myEvStart), myEvLength);
            myNewTrack.Events.Add(newEvent);
            Take take = new Take(stream);
            newEvent.Takes.Add(take);
            newEvent.ActiveTake.Media.Length = myEvLength;

            //get the actual OFX effect  (gEffect: generated effect)
            Effect gEffect = newEvent.ActiveTake.Media.Generator;

            //add preset to generated event
            gEffect.Preset = "STT - Default Subtitle";
            OFXEffect fxo = gEffect.OFXEffect;

            //get current preset info and parse
            OFXStringParameter tparm = (OFXStringParameter)fxo.FindParameterByName("Text");
            var f = tparm.Value;

            //get font
            string fontName;
            var idx0 = f.IndexOf("\\fcharset0");
            var fontSTR = f.Substring(idx0 + 10);
            var idx1 = fontSTR.IndexOf(';');
            fontName = f.Substring(idx0 + 10, idx1).Trim();
            //MessageBox.Show(fontName);

            //get font size
            int fontSize;
            idx0 = f.IndexOf("\\fs");
            var sizSTR = f.Substring(idx0 + 3);
            idx1 = sizSTR.IndexOf(" ");
            fontSize = (int.Parse(f.Substring(idx0 + 3, idx1)) / 2);
            //MessageBox.Show(fontSize.ToString());

            //get bold and italic
            bool bold = f.Contains("\\b\\");
            bool italic = f.Contains("\\i\\");
            //MessageBox.Show("Bold " + bold.ToString(), "Italic " + italic.ToString());

            //set fontstyle
            FontStyle fs = new FontStyle();
            if (bold && italic) fs = FontStyle.Bold | FontStyle.Italic;
            if (bold && !italic) fs = FontStyle.Bold;
            if (!bold && italic) fs = FontStyle.Italic;
            if (!bold && !italic) fs = FontStyle.Regular;

            //create new ricktextbox
            RichTextBox rtfText = new RichTextBox();
            rtfText.Text = myText;
            rtfText.SelectAll();
            rtfText.SelectionFont = new Font(fontName, fontSize, fs);

            //set horizonal alignment
            rtfText.SelectionAlignment = HorizontalAlignment.Left;
            if (f.Contains("\\qc\\")) rtfText.SelectionAlignment = HorizontalAlignment.Center;
            if (f.Contains("\\qr\\")) rtfText.SelectionAlignment = HorizontalAlignment.Right;

            //set tparm value
            tparm.Value = rtfText.Rtf;

            //Apply all changes
            fxo.AllParametersChanged();
        }

        void AddTextEventQuantized(Vegas vegas, Track myNewTrack, Timecode myEvStart, Timecode myEvLength, string myText)
        {
            // Ensure quantization to video frame
            Timecode quantizedEvStart = QuantizeToFrame(myEvStart, myVegas.Project.Video.FrameRate);
            Timecode quantizedEvEnd = QuantizeToFrame(myEvStart + myEvLength, myVegas.Project.Video.FrameRate) - quantizedEvStart;

            AddTextEvent(vegas, myNewTrack, quantizedEvStart, quantizedEvEnd, myText);
        }

        Timecode QuantizeToFrame(Timecode time, double frameRate)
        {
            double frameDuration = 1.0 / frameRate;
            double timeInSeconds = time.ToMilliseconds() / 1000.0;
            double quantizedTimeInSeconds = Math.Round(timeInSeconds / frameDuration) * frameDuration;
            return Timecode.FromMilliseconds(quantizedTimeInSeconds * 1000);
        }
    }

    public class CustomMessageBox : Form
    {
        public CustomMessageBox(string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)
        {
            // Configurações da janela
            Text = caption;
            Size = new System.Drawing.Size(200, 150);
            FormBorderStyle = FormBorderStyle.FixedDialog;
            StartPosition = FormStartPosition.CenterScreen;
            BackColor = System.Drawing.Color.Black; // Fundo preto
            ForeColor = System.Drawing.Color.White; // Fonte branca
            ControlBox = true; // Manter o botão de fechar
            MinimizeBox = false; // Desabilitar o botão de minimizar
            MaximizeBox = false; // Desabilitar o botão de maximizar

            // Label para exibir a mensagem
            Label label = new Label();
            label.Text = message;
            label.AutoSize = true;
            label.TextAlign = ContentAlignment.MiddleCenter; // Centralizar texto horizontalmente
            label.Location = new System.Drawing.Point((ClientSize.Width - label.PreferredWidth) / 2, (ClientSize.Height - label.PreferredHeight - 50) / 2); // Centralizar horizontalmente e verticalmente

            // Botão OK
            Button button = new Button();
            button.Text = "OK";
            button.DialogResult = DialogResult.OK;
            button.Size = new Size(75, 23); // Tamanho do botão
            button.Location = new System.Drawing.Point((ClientSize.Width - button.Width) / 2, label.Bottom + 30); // Posicionar abaixo do label e centralizar horizontalmente
            button.BackColor = System.Drawing.Color.White; // Corrigindo o fundo para branco
            button.ForeColor = System.Drawing.Color.Black; // Texto preto

            // Adiciona controles à janela
            Controls.Add(label);
            Controls.Add(button);
        }

        // Método estático para exibir a caixa de mensagem
        public static DialogResult Show(string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)
        {
            CustomMessageBox messageBox = new CustomMessageBox(message, caption, buttons, icon);
            return messageBox.ShowDialog();
        }
    }
}

 

Comments

jetdv wrote on 5/20/2024, 4:21 PM

Ok, the issue is here:

if (myVegas.Version.Contains("14") || myVegas.Version.Contains("15") || myVegas.Version.Contains("16"))             { genUID = "{Svfx:com.sonycreativesoftware:titlesandtext}"; } //Sony Titles & Text

The newest build of VEGAS returns "Version 21.0 (Build 314)" so it has a 14 and is changing the plugin ID to "sony". In the above change the "14", "15", and "16" to "14.0", "15.0", and "16.0" and it should then be fine.

joelsonforte.br wrote on 5/20/2024, 11:55 PM

@jetdv Thanks! That was exactly it.

ccscotty wrote on 7/6/2024, 11:32 AM

Are you using version 21 in debugging mode with Visual Studio? Mine refuses to start up the application when I try to do that.

jetdv wrote on 7/6/2024, 11:47 AM

I typically don't use "debugging mode" anymore. I've found I can usually debug just as easily with a few message boxes thrown in the code. If it dies between two message boxes, I know the section of code to look at.