[SOLVED] Timecode Format from "00:00:00,000" to "00:00:00.000"

tf_studio wrote on 12/22/2023, 10:24 AM

Hi,
I'm trying to replicate one of the @jetdv script : "Remove Silent Areas from an Audio Track in VEGAS - Part 2" ( in order to modify it later in a video bass shake effect.

However i have an issue i located but i'm unable to fix it :

- The script works until it reach the first audio value and send the following error :
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.FormatException: Input string was not in a correct format.
   at System.Number.ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt)
   at Test_Script.Class1.ProcessLog(String path)
   at Test_Script.Class1.Main(Vegas vegas)

The faulty code line is this one :  trackVolume = Convert.ToDouble(pieces[2]);
Look like the value is not converted correctly to double.
Is there a solution possible to this issue ?

My Vegas : Vegas version 21 (English)

Here is the entire code :

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using ScriptPortal.Vegas;

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;

        Renderer myRenderer = null;
        RenderTemplate rndrTemplate = null;

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

            FindRenderers();

            string tempFile = myVegas.TemporaryFilesPath + Path.DirectorySeparatorChar + "temp.mp3";
            string tempLog = myVegas.TemporaryFilesPath + Path.DirectorySeparatorChar + "temp_loud.txt";

            foreach (Track myTrack in myVegas.Project.Tracks)
            {
                if (myTrack.IsAudio())
                {
                    RenderTempFile(tempFile);
                    ProcessLog(tempLog);
                }
            }
        }

        public void FindRenderers()
        {
            try
            {
                foreach (Renderer renderer in myVegas.Renderers)
                {
                    if ("adfa6a4b-a99b-42e3-ae1f-081123ada04b" == renderer.ClassID.ToString())
                    {
                        myRenderer = renderer;
                        try
                        {
                            foreach (RenderTemplate renderTemplate in renderer.Templates)
                            {
                                if (renderTemplate.IsValid())
                                {
                                    if ("8ab64a16-81f5-46e6-8155-1611d592088c" == renderTemplate.TemplateGuid.ToString())
                                    {
                                        rndrTemplate = renderTemplate;
                                    }
                                }
                            }
                        }
                        catch
                        {

                        }
                    }
                }
            }
            catch
            {

            }
        }

        public void RenderTempFile(string tempFile)
        {
            RenderArgs args = new RenderArgs();
            args.OutputFile = tempFile;
            args.RenderTemplate = rndrTemplate;
            args.Start = Timecode.FromFrames(0);
            args.Length = myVegas.Project.Length;
            args.IncludeMarkers = false;
            args.StretchToFill = false;
            args.GenerateLoudnessLog = true;

            RenderStatus status = myVegas.Render(args);
        }

        public void ProcessLog(string path)
        {
            Envelope compEnv = new Envelope(EnvelopeType.Composite);
            myVegas.Project.Tracks[0].Envelopes.Add(compEnv);
            compEnv.Points[0].Y = 0.0;

            var lines = File.ReadLines(path);

            bool foundfirst = false;
            foreach (string line in lines)
            {
                if (line.StartsWith("-------------"))
                {
                    break;
                }
                if (line.StartsWith("              Pos."))
                {
                    foundfirst = true;
                }
                else
                {
                    if (foundfirst)
                    {
                        if (line.Length > 5)
                        {
                            string[] pieces = line.Split('\t');
                            Timecode trackTime = Timecode.FromString(pieces[1]);
                            double trackVolume = 0;
                            if (pieces[2].Contains("Inf"))
                            {
                                trackVolume = -100;
                            }
                            else
                            {
                                trackVolume = Convert.ToDouble(pieces[2]);
                            }
                            EnvelopePoint volPoint = new EnvelopePoint(trackTime, 1.0 + (trackVolume / 100));
                            compEnv.Points.Add(volPoint);
                        }
                    }
                }
            }
        }

    }
    public class EntryPoint
    {
        public Vegas myVegas;

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

}

And the file generated :

Comments

jetdv wrote on 12/22/2023, 10:36 AM

@tf_studio, first of all, make sure you know what you're looking at. We assume that "pieces[2]" has that value. But does it really? On the line after the split command, add a:

MessageBox.Show("Timecode = " + pieces[1] + "    Value = " + pieces[2]);

Or even something like:

MessageBox.Show("0=" + pieces[0] + "   1=" + pieces[1] + " 2=" + pieces[2] + " 3=" + pieces[3] + " 4=" + pieces[4]);

You may have to press enter a BUNCH of times but, eventually, you should see the "bad" value.

I'm guessing that the issue has to do with your timeline format. Based on what I'm seeing, I'm guessing it's set to "Time"? What if you change it to "Time and Frames". I'm thinking the "," in the timecode may be throwing it off.

 

tf_studio wrote on 12/22/2023, 1:10 PM

@tf_studio, first of all, make sure you know what you're looking at. We assume that "pieces[2]" has that value. But does it really? On the line after the split command, add a:

MessageBox.Show("Timecode = " + pieces[1] + "    Value = " + pieces[2]);

Or even something like:

MessageBox.Show("0=" + pieces[0] + "   1=" + pieces[1] + " 2=" + pieces[2] + " 3=" + pieces[3] + " 4=" + pieces[4]);

You may have to press enter a BUNCH of times but, eventually, you should see the "bad" value.

I'm guessing that the issue has to do with your timeline format. Based on what I'm seeing, I'm guessing it's set to "Time"? What if you change it to "Time and Frames". I'm thinking the "," in the timecode may be throwing it off.

 

Thanks for the tips 👍, i was suspecting the timecode format to be the issue, and now i'm pretty sure as "pieces[2]"  return the excepted values (by using the messagebox). But even after changing the project Timecode from "Time" to "Time and Frame" (which also has a "," in it for some reasons) , the file use the "Time" timecode format. Is there a way to force the temporary file to be generated with a custom timecode format ?
(or change the "," by another character) 😅

jetdv wrote on 12/22/2023, 4:06 PM

@tf_studio What language is your VEGAS set to? Set to US English, it uses a ";" or "." instead of "," (depending on the timecode format.) The one time I had a really hard to track down error in Excalibur was from another country running another language that used a "," for the decimal point instead of a ".".

What if you try adding a "replace" command here? (See the bold line):

            if (line.Length > 5)
            {
                line.Replace(",", ".");

                string[] pieces = line.Split('\t');
                Timecode trackTime = Timecode.FromString(pieces[1]);

 

tf_studio wrote on 12/22/2023, 4:38 PM

I started programming with my Vegas in French, but i reinstalled it yesterday in English to see if that change the timecode but it stayed the same, however my system is still in French. As some of the libraries are set by windows it could also be the source of the problem. (and "." is "," in french)

I'm going to try fixing it by replacing the "," by a "." 👍

tf_studio wrote on 12/23/2023, 8:26 AM

Problem solved ! Switching Windows to English as main language changed the timecode format of the videos 👍
Many Thanks !

tf_studio wrote on 3/30/2025, 11:20 AM

@tf_studio What language is your VEGAS set to? Set to US English, it uses a ";" or "." instead of "," (depending on the timecode format.) The one time I had a really hard to track down error in Excalibur was from another country running another language that used a "," for the decimal point instead of a ".".

What if you try adding a "replace" command here? (See the bold line):

            if (line.Length > 5)
            {
                line.Replace(",", ".");

                string[] pieces = line.Split('\t');
                Timecode trackTime = Timecode.FromString(pieces[1])

Hi, me again.

So i resumed my work on this "Audio Volume to Video Scale" script, and it's almost working perfectly.

In short, the script analyses the audio master of the project, generate a log file (temp_loud.txt) and the data inside it are used to create keyframe on a picture-in-picture effect on a selected event on the timeline.

(on the screenshot there are the double amount of keyframe ((tested something but doesn't work lol)))

The only issue i got is the number of keyframe on the picture-in-picture effect.
Even with the better audio format, the log file has only 20 samples per seconds in it, which is not enough.


I would like to know if there is a way to generate an audio log file that match the video framerate of the project (60fps), so the script could generate 1 keyframe for each frames of the video and get a smooth and precise result.

Here's the code of the script

Have a nice day and thx in advance,
Clement F.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using ScriptPortal.Vegas;

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;

        Renderer myRenderer = null;
        RenderTemplate rndrTemplate = null;

        private double x = 0.00; 
        private double y = 0.00; 
        private double x1 = 0.00; 
        private double y1 = 0.00; 

        private static OFXInterpolationType ParseOFXCurveType(String val)
        {
            switch (val)
            {
                case "Sharp":
                    return OFXInterpolationType.Sharp;
                case "Slow":
                    return OFXInterpolationType.Slow;
                case "Linear":
                    return OFXInterpolationType.Linear;
                case "Fast":
                    return OFXInterpolationType.Fast;
                case "Smooth":
                    return OFXInterpolationType.Smooth;
                case "Hold":
                    return OFXInterpolationType.Hold;
                case "Manual":
                    return OFXInterpolationType.Manual;
                case "Split":
                    return OFXInterpolationType.Split;
                default:
                    throw new ApplicationException("Unknown CurveType: " + val);
            }
        }

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

            FindRenderers();

            string tempFile = myVegas.TemporaryFilesPath + Path.DirectorySeparatorChar + "temp.wav";
            string tempLog = myVegas.TemporaryFilesPath + Path.DirectorySeparatorChar + "temp_loud.txt"; 

            //Apply Effects on Selected Events
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected && evnt.IsVideo())
                    {
                        RenderTempFile(tempFile);
                        PlugInNode trans = myVegas.Transitions;
                    }
                }
                foreach (TrackEvent trackEvent in track.Events)
                {
                    // Picture-In-Picture
                    if (trackEvent.Selected && trackEvent.IsVideo())
                    {
                        ProcessLog(tempLog);
                    }
                }
            }
        }

        public void FindRenderers()
        {
            try
            {
                foreach (Renderer renderer in myVegas.Renderers)
                {
                    if ("3cbba9c1-75ad-11d3-a483-00105a24aa37" == renderer.ClassID.ToString())
                    {
                        myRenderer = renderer;
                        try
                        {
                            foreach (RenderTemplate renderTemplate in renderer.Templates)
                            {
                                if (renderTemplate.IsValid())
                                {
                                    if ("40b83654-d0cf-36b2-b5fb-6360cd32d519" == renderTemplate.TemplateGuid.ToString())
                                    {
                                        rndrTemplate = renderTemplate;
                                    }
                                }
                            }
                        }
                        catch
                        {

                        }
                    }
                }
            }
            catch
            {

            }
        }

        public void RenderTempFile(string tempFile)
        {
            RenderArgs args = new RenderArgs();
            args.OutputFile = tempFile;
            args.RenderTemplate = rndrTemplate;
            args.Start = Timecode.FromFrames(0);
            args.Length = myVegas.Project.Length;
            args.IncludeMarkers = false;
            args.StretchToFill = false;
            args.GenerateLoudnessLog = true;

            RenderStatus status = myVegas.Render(args);
        }

        public void ProcessLog(string path)
        {
            var lines = File.ReadLines(path);
            bool foundfirst = false;
            string fxPictureUID = "{Svfx:com.vegascreativesoftware:pictureinpicture}";
            string fxDeformationUID = "{Svfx:com.genarts.sapphire.Distort.S_WarpTransform}";

            //Apply Picture-In-Picture on Selected Events between Cookie Cutter & Layer Dimensionality
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    //Determine The First and Last Keyframe of each Events
                    Timecode startFrame = trackEvent.Start;
                    Timecode endFrame = trackEvent.End;

                    // Picture-In-Picture
                    if (trackEvent.Selected && trackEvent.IsVideo())
                    {

                        VideoEvent videoEventDeformation = (VideoEvent)trackEvent;
                        VideoEvent videoEventPicture = (VideoEvent)trackEvent;

                        PlugInNode fxList = myVegas.VideoFX;
                        PlugInNode fxChildPicture = fxList.GetChildByUniqueID(fxPictureUID);
                        PlugInNode fxChildDeformation = fxList.GetChildByUniqueID(fxDeformationUID);

                        Effect effectPicture = new Effect(fxChildPicture);
                        Effect effectDeformation = new Effect(fxChildDeformation);

                        videoEventPicture.Effects.Add(effectPicture);
                        videoEventDeformation.Effects.Add(effectDeformation);

                        if (effectPicture.PlugIn.IsOFX && effectDeformation.PlugIn.IsOFX)
                        {
                            OFXEffect ofxpicture = effectPicture.OFXEffect;
                            OFXEffect ofxdeformation = effectDeformation.OFXEffect;


                            //DEFORM : Setup Y_Scale
                            //PICTURE : Setup Scale of Picture
                            foreach (string line in lines)
                            {
                                if (line.StartsWith("-------------"))
                                {
                                    break;
                                }
                                if (line.StartsWith("              Pos."))
                                {
                                    foundfirst = true;
                                }
                                else
                                {
                                    if (foundfirst)
                                    {
                                        if (line.Length > 5)
                                        {
                                            string a = line.Replace("\t" , "A");
                                            string b = a.Replace("AA" , "A");
                                            string c = b.Replace("-","");
                                            string[] pieces = b.Split('A');
                                            double trackVolume = 0;
                                            Timecode trackTime = Timecode.FromString(pieces[1]);
                                            if (pieces[2].Contains("Inf"))
                                            {
                                                trackVolume = 0;
                                            }
                                            else
                                            {
                                                trackVolume = Convert.ToDouble(pieces[2]);
                                            }
                                            if (trackVolume < -20.00)
                                            {
                                                x = 1.45;
                                                y = 1.45;
                                            }
                                            else
                                            {
                                                x = 1.0 /*+ (trackVolume / 140)*/;
                                                y = 1.0 - (trackVolume / 44);      
                                                //x1 = 1.0;
                                                y1 = 1.0 - (trackVolume / 40);                                          
                                            }
                                            if (trackTime > startFrame)
                                            {
                                                Timecode effectTime = (trackTime - startFrame);
                                                Timecode effectTime1 = (effectTime + Timecode.FromFrames(1) );
                                                OFXDoubleParameter ofxScaleY = (OFXDoubleParameter)ofxdeformation["Scale Y"];
                                                ofxScaleY.IsAnimated = true;
                                                setOFXDoubleParameter (ofxdeformation, "Scale Y", effectTime, y);
                                                setOFXDoubleParameter (ofxdeformation, "Scale Y", effectTime1, y1);
                                                foreach(OFXDoubleKeyframe elemnt in ofxScaleY.Keyframes)
                                                {
                                                    elemnt.Interpolation = OFXInterpolationType.Fast;
                                                }

                                                OFXDoubleParameter ofxScale = (OFXDoubleParameter)ofxpicture["Scale"];
                                                ofxScale.IsAnimated = true;
                                                setOFXDoubleParameter (ofxpicture, "Scale", effectTime, x);
                                                foreach(OFXDoubleKeyframe elemnt in ofxScale.Keyframes)
                                                {
                                                    elemnt.Interpolation = OFXInterpolationType.Fast;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        } 
                    }
                }
            }

        }

        public void setOFXDoubleParameter(OFXEffect ofx, string Parameter, Timecode keyTime, double keyValue)
        {
            OFXDoubleParameter ofxParm = (OFXDoubleParameter)ofx[Parameter];
            ofxParm.IsAnimated = true;
            ofxParm.SetValueAtTime(keyTime, keyValue);
        }
    }

    public class EntryPoint
    {
        public Vegas myVegas;

        public void FromVegas(Vegas vegas)
        {
            Test_Script.Class1 test = new Test_Script.Class1();

            myVegas = vegas;
            test.Main(vegas);
        }
    }
}

 

tf_studio wrote on 3/30/2025, 11:39 AM


One solution could be to generate the log file 3 times with different start times (gonna test that)