Batch importing xml files

Soksoa wrote on 4/3/2023, 2:23 PM

I'm using an application called auto-editor to crop my stock footage automaticly crop parts when I don't talk. This app has an option to export processed clips into xml files, for later importing them into vegas or adobe premiere (I don't own adobe premiere).

I run this program with all of my clips resulting in a lot of xml files which I want to import in a single proyect of vegas as normal events. However, I can only import xml files into vegas as complete proyects, and not as normal media. When I try to import an xml in a proyect, it shows up "do you want to save x?" and doesn't let me an option to add it as normal cropped clips.

The workaround I've found is to open two instances of Vegas: one where I create the main project and another where I import xml files. Then, I manually copy events from the imported project into the main project.

I've posted this in scripting as I don't think there is a feature in vegas pro that lets you "batch import" xml files into vegas.

Comments

jetdv wrote on 4/3/2023, 2:34 PM

@Soksoa, I'm sure that can be done with scripting. What is the format of the XML file?

If you haven't you might want to look over my scripting tutorials.

Soksoa wrote on 4/5/2023, 7:02 AM

Hello @jetdv, I've looked through some resources, including yours, but I still have limited knowledge in C# and could use some additional guidance. I would be extremely grateful if you could spare some time to help me with this. Thank you very much in advance!

Soksoa wrote on 4/5/2023, 7:07 AM

Here is an example of a xml I want to work with:

<?xml version="1.0" encoding="UTF-8"?>

-<xmeml version="4">


-<sequence>

<name>Auto-Editor Media Group</name>

<duration>12768</duration>


-<rate>

<timebase>60</timebase>

<ntsc>FALSE</ntsc>

</rate>


-<media>


-<video>


-<format>


-<samplecharacteristics>


-<rate>

<timebase>60</timebase>

<ntsc>FALSE</ntsc>

</rate>

<fielddominance>none</fielddominance>

<colordepth>24</colordepth>

<width>1920</width>

<height>1080</height>

<pixelaspectratio>square</pixelaspectratio>

</samplecharacteristics>

</format>


-<track>


-<clipitem id="clipitem-1">

<masterclipid>masterclip-2</masterclipid>

<name>this</name>

<start>0</start>

<end>50</end>

<in>14</in>

<out>64</out>


-<file id="file-1">

<name>this</name>

<pathurl>C:\Videos\Minecraft\this.mp4</pathurl>


-<rate>

<timebase>60</timebase>

<ntsc>FALSE</ntsc>

</rate>

<duration>12768</duration>


-<media>


-<video>


-<samplecharacteristics>


-<rate>

<timebase>60</timebase>

<ntsc>FALSE</ntsc>

</rate>

<width>1920</width>

<height>1080</height>

<anamorphic>FALSE</anamorphic>

<pixelaspectratio>square</pixelaspectratio>

</samplecharacteristics>

</video>


-<audio>


-<samplecharacteristics>

<depth>16</depth>

<samplerate>48000</samplerate>

</samplecharacteristics>

<channelcount>2</channelcount>

</audio>

</media>

<duration>12768</duration>

</file>


-<link>

<linkclipref>clipitem-1</linkclipref>

<mediatype>video</mediatype>

<trackindex>1</trackindex>

<clipindex>1</clipindex>

</link>


-<link>

<linkclipref>clipitem-64</linkclipref>

<mediatype>audio</mediatype>

<trackindex>1</trackindex>

<clipindex>1</clipindex>

<groupindex>1</groupindex>

</link>


-<link>

<linkclipref>clipitem-127</linkclipref>

<mediatype>audio</mediatype>

<trackindex>2</trackindex>

<clipindex>1</clipindex>

<groupindex>1</groupindex>

</link>

</clipitem>


-<clipitem id="clipitem-2">

<masterclipid>masterclip-2</masterclipid>

<name>this</name>

<start>50</start>

<end>87</end>

<in>125</in>

<out>162</out>

<file id="file-1"/>


-<link>

<linkclipref>clipitem-2</linkclipref>

<mediatype>video</mediatype>

<trackindex>1</trackindex>

<clipindex>2</clipindex>

</link>


-<link>

<linkclipref>clipitem-65</linkclipref>

<mediatype>audio</mediatype>

<trackindex>1</trackindex>

<clipindex>2</clipindex>

<groupindex>1</groupindex>

</link>


-<link>

<linkclipref>clipitem-128</linkclipref>

<mediatype>audio</mediatype>

<trackindex>2</trackindex>

<clipindex>2</clipindex>

<groupindex>1</groupindex>

</link>

</clipitem>


-<clipitem id="clipitem-3">

<masterclipid>masterclip-2</masterclipid>

<name>this</name>

<start>87</start>

<end>401</end>

<in>169</in>

<out>483</out>

<file id="file-1"/>


-<link>

<linkclipref>clipitem-3</linkclipref>

<mediatype>video</mediatype>

<trackindex>1</trackindex>

<clipindex>3</clipindex>

</link>


-<link>

<linkclipref>clipitem-66</linkclipref>

<mediatype>audio</mediatype>

<trackindex>1</trackindex>

<clipindex>3</clipindex>

<groupindex>1</groupindex>

</link>


-<link>

<linkclipref>clipitem-129</linkclipref>

<mediatype>audio</mediatype>

<trackindex>2</trackindex>

<clipindex>3</clipindex>

<groupindex>1</groupindex>

</link>

</clipitem>


-<clipitem id="clipitem-4">

<masterclipid>masterclip-2</masterclipid>

<name>this</name>

<start>401</start>

<end>437</end>

<in>673</in>

<out>709</out>

<file id="file-1"/>


-<link>

<linkclipref>clipitem-4</linkclipref>

<mediatype>video</mediatype>

<trackindex>1</trackindex>

<clipindex>4</clipindex>

</link>


-<link>

<linkclipref>clipitem-67</linkclipref>

<mediatype>audio</mediatype>

<trackindex>1</trackindex>

<clipindex>4</clipindex>

<groupindex>1</groupindex>

</link>


-<link>

<linkclipref>clipitem-130</linkclipref>

<mediatype>audio</mediatype>

<trackindex>2</trackindex>

<clipindex>4</clipindex>

<groupindex>1</groupindex>

</link>

</clipitem>


-<clipitem id="clipitem-5">

<masterclipid>masterclip-2</masterclipid>

<name>this</name>

<start>437</start>

<end>627</end>

<in>715</in>

<out>905</out>

<file id="file-1"/>


-<link>

<linkclipref>clipitem-5</linkclipref>

<mediatype>video</mediatype>

<trackindex>1</trackindex>

<clipindex>5</clipindex>

</link>


-<link>

<linkclipref>clipitem-68</linkclipref>

<mediatype>audio</mediatype>

<trackindex>1</trackindex>

<clipindex>5</clipindex>

<groupindex>1</groupindex>

</link>


-<link>

<linkclipref>clipitem-131</linkclipref>

<mediatype>audio</mediatype>

<trackindex>2</trackindex>

<clipindex>5</clipindex>

<groupindex>1</groupindex>

 

...

jetdv wrote on 4/5/2023, 8:05 AM

Any way you can send the entire file?

It looks like these are the sections you want to keep?

-<clipitem id="clipitem-4">
<masterclipid>masterclip-2</masterclipid>
<name>this</name>
<start>401</start>
<end>437</end>
<in>673</in>
<out>709</out>
<file id="file-1"/>

I don't see any "closing" to the clipitem sections.

And are you using "Start/End" or "in/out"?

And are those numbers frames from the beginning?

 

Soksoa wrote on 4/5/2023, 1:36 PM

The xml I tried to post before was too big. Here is a shorter one with the same structure.

<?xml version='1.0' encoding='utf-8'?>
<xmeml version="4">
    <sequence>
        <name>Auto-Editor Media Group</name>
        <duration>322</duration>
        <rate>
            <timebase>60</timebase>
            <ntsc>FALSE</ntsc>
        </rate>
        <media>
            <video>
                <format>
                    <samplecharacteristics>
                        <rate>
                            <timebase>60</timebase>
                            <ntsc>FALSE</ntsc>
                        </rate>
                        <fielddominance>none</fielddominance>
                        <colordepth>24</colordepth>
                        <width>1920</width>
                        <height>1080</height>
                        <pixelaspectratio>square</pixelaspectratio>
                    </samplecharacteristics>
                </format>
                <track>
                    <clipitem id="clipitem-1">
                        <masterclipid>masterclip-2</masterclipid>
                        <name>video</name>
                        <start>0</start>
                        <end>322</end>
                        <in>0</in>
                        <out>322</out>
                        <file id="file-1">
                            <name>video</name>
                            <pathurl>C:\Videos\Minecraft\video.mp4</pathurl>
                            <rate>
                                <timebase>60</timebase>
                                <ntsc>FALSE</ntsc>
                            </rate>
                            <duration>322</duration>
                            <media>
                                <video>
                                    <samplecharacteristics>
                                        <rate>
                                            <timebase>60</timebase>
                                            <ntsc>FALSE</ntsc>
                                        </rate>
                                        <width>1920</width>
                                        <height>1080</height>
                                        <anamorphic>FALSE</anamorphic>
                                        <pixelaspectratio>square</pixelaspectratio>
                                    </samplecharacteristics>
                                </video>
                                <audio>
                                    <samplecharacteristics>
                                        <depth>16</depth>
                                        <samplerate>48000</samplerate>
                                    </samplecharacteristics>
                                    <channelcount>2</channelcount>
                                </audio>
                            </media>
                            <duration>322</duration>
                        </file>
                        <link>
                            <linkclipref>clipitem-1</linkclipref>
                            <mediatype>video</mediatype>
                            <trackindex>1</trackindex>
                            <clipindex>1</clipindex>
                        </link>
                        <link>
                            <linkclipref>clipitem-2</linkclipref>
                            <mediatype>audio</mediatype>
                            <trackindex>1</trackindex>
                            <clipindex>1</clipindex>
                            <groupindex>1</groupindex>
                        </link>
                        <link>
                            <linkclipref>clipitem-3</linkclipref>
                            <mediatype>audio</mediatype>
                            <trackindex>2</trackindex>
                            <clipindex>1</clipindex>
                            <groupindex>1</groupindex>
                        </link>
                    </clipitem>
                </track>
            </video>
            <audio>
                <numOutputChannels>2</numOutputChannels>
                <format>
                    <samplecharacteristics>
                        <depth>16</depth>
                        <samplerate>48000</samplerate>
                    </samplecharacteristics>
                </format>
                <track currentExplodedTrackIndex="0" premiereTrackType="Stereo">
                    <clipitem id="clipitem-2" premiereChannelType="stereo">
                        <masterclipid>masterclip-2</masterclipid>
                        <name>video</name>
                        <start>0</start>
                        <end>322</end>
                        <in>0</in>
                        <out>322</out>
                        <file id="file-1" />
                        <sourcetrack>
                            <mediatype>audio</mediatype>
                            <trackindex>1</trackindex>
                        </sourcetrack>
                        <labels>
                            <label2>Iris</label2>
                        </labels>
                        <outputchannelindex>1</outputchannelindex>
                    </clipitem>
                </track>
                <track currentExplodedTrackIndex="0" premiereTrackType="Stereo">
                    <clipitem id="clipitem-3" premiereChannelType="stereo">
                        <masterclipid>masterclip-2</masterclipid>
                        <name>video</name>
                        <start>0</start>
                        <end>322</end>
                        <in>0</in>
                        <out>322</out>
                        <file id="file-2">
                            <name>video</name>
                            <pathurl>C:\Videos\Minecraft\video_tracks\1.wav</pathurl>
                            <rate>
                                <timebase>60</timebase>
                                <ntsc>FALSE</ntsc>
                            </rate>
                            <media>
                                <audio>
                                    <samplecharacteristics>
                                        <depth>16</depth>
                                        <samplerate>48000</samplerate>
                                    </samplecharacteristics>
                                    <channelcount>2</channelcount>
                                </audio>
                            </media>
                        </file>
                        <sourcetrack>
                            <mediatype>audio</mediatype>
                            <trackindex>1</trackindex>
                        </sourcetrack>
                        <labels>
                            <label2>Iris</label2>
                        </labels>
                        <outputchannelindex>1</outputchannelindex>
                    </clipitem>
                </track>
            </audio>
        </media>
    </sequence>
</xmeml>

jetdv wrote on 4/6/2023, 7:25 AM

I have no idea what's supposed to be imported based on that file.

Soksoa wrote on 4/6/2023, 12:05 PM


My "autoediting" tool removes parts in video (.mp4) were there is no audio. Instead of exporting a raw .mp4 file, which I cannot further modify, it exports a .xml. I can import the .xml and modify the events in the timeline.
I "autoedit" a lot of videos (200+ clips) resulting in +200 .xml files.
What I want is to import all of these .xml in a single timeline, just as if they were normal media:

Just as I can drag a bunch of videos into a timeline,

I cannot drag .xml files,

The only way to import .xml files (or adobe premiere proyects) is by selecting this option in the menu.

Still, if I try opening files this way, vegas asks me if I want to close the current proyect.
Because I want to put all of my "autoedited" clips in the same timeline, I end up opening two instances of vegas. One where I import xml files as shown in the previous picture. Then, copypasting the cut events into the second instance where I have all of the clips.

Is it possible to create a script to skip this tedious process?

jetdv wrote on 4/6/2023, 1:10 PM

Zip up a few of the XML files with the associated video files and post that zip file somewhere I can download. If the video files are too big, then just zip up a few XML files so I can take a deeper look.

Soksoa wrote on 4/6/2023, 1:31 PM

https://www.mediafire.com/file/3klllxw2o36t9yw/media.zip/file
I don't have footage where I talk aviable now but in this examples you can see what auto-editor does.

jetdv wrote on 4/6/2023, 3:03 PM

Thanks. Will take a look

jetdv wrote on 4/9/2023, 7:12 AM

@Soksoa, please take a look at this. Please note that it will only process from a SINGLE file per XML file. This is a quick version and I did not make it smart enough to handle multiple video files in a single XML file. But it does work with the three XML files you sent me. This is a .CS script so save it under something like "Import Multiple XML.CS"

I manually added the regions in this image to show where each was imported. Basically, they will all be imported back to back.

It also ignores all of the project and clip size/format information so it's up to you to set the project to the proper settings.
 

using System;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Drawing;
using System.Runtime;
using System.Xml;
using ScriptPortal.Vegas;

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;
        private NumberFormatInfo myNumberFormat = NumberFormatInfo.InvariantInfo;
        private string[] filenames;
        private string clipitemFile;
        Timecode baseStartPosition;
        VideoTrack vTrack;
        AudioTrack aTrack;

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

            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Import Files (*.XML)|*.xml|All Files (*.*)|*.*";
            ofd.Multiselect = true;
            ofd.Title = "Select the files to import";
            ofd.InitialDirectory = "D:\\Edward_\\Import"; //Change this to where you want it to look by default
            DialogResult dr = ofd.ShowDialog();
            if (dr == System.Windows.Forms.DialogResult.OK)
            {
                filenames = ofd.FileNames;
                myVegas.NewProject(false, false);
                vTrack = new VideoTrack();
                myVegas.Project.Tracks.Add(vTrack);
                aTrack = new AudioTrack();
                myVegas.Project.Tracks.Add(aTrack);
                myVegas.Transport.CursorPosition = Timecode.FromFrames(0);

                foreach (string file in filenames)
                {
                    baseStartPosition = myVegas.Transport.CursorPosition;
                    processImportFile(file);
                    myVegas.Transport.CursorPosition = myVegas.Project.Length;
                }

            }
        }

        private void processImportFile(string myFile)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(myFile);
            XmlElement root = doc.DocumentElement;
            foreach (XmlElement child in root)
            {
                if (child.Name.ToLower() == "sequence")
                {
                    foreach (XmlElement child2 in child)
                    {
                        if (child2.Name.ToLower() == "media")
                        {
                            foreach (XmlElement child3 in child2)
                            {
                                if (child3.Name.ToLower() == "video" || child3.Name.ToLower() == "audio")
                                {
                                    string mediaType = child3.Name.ToLower();
                                    foreach (XmlElement child4 in child3)
                                    {
                                        if (child4.Name.ToLower() == "track")
                                        {
                                            foreach(XmlElement child5 in child4)
                                            {
                                                if (child5.Name.ToLower() == "clipitem")
                                                {
                                                    processClipItem(child5, mediaType);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        private void processClipItem(XmlElement clipitem, string mediaType)
        {
            double StartFrame = 0;
            double EndFrame = 0;
            double InFrame = 0;
            double OutFrame = 0;
            string MasterClipID = "";

            foreach (XmlElement child in clipitem)
            {
                string childName = child.Name.ToLower();
                switch (childName)
                {
                    case "masterclipid":
                        MasterClipID = child.InnerText;
                        break;
                    case "start":
                        StartFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "end":
                        EndFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "in":
                        InFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "out":
                        OutFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "file":
                        foreach(XmlElement child2 in child)
                        {
                            if (child2.Name.ToLower() == "pathurl")
                            {
                                clipitemFile = child2.InnerText;
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            addClipToTimeline(clipitemFile, StartFrame, EndFrame, InFrame, OutFrame, mediaType);
        }

        private void addClipToTimeline(string fileName, double StartFrame, double EndFrame, double InFrame, double OutFrame, string mediaType)
        {
            //MessageBox.Show(fileName + "  s" + StartFrame + "  e" + EndFrame + "  i" + InFrame + "  o" + OutFrame + "  " + mediaType);

            Media media = new Media(fileName);
            if (mediaType == "video")
            {
                MediaStream stream = media.Streams.GetItemByMediaType(MediaType.Video, 0);
                VideoEvent vEvent = new VideoEvent(Timecode.FromFrames((long)StartFrame) + baseStartPosition, Timecode.FromFrames((long)EndFrame) - Timecode.FromFrames((long)StartFrame));
                vTrack.Events.Add(vEvent);
                Take myNewtake = new Take(stream);
                vEvent.Takes.Add(myNewtake);
                myNewtake.Offset = Timecode.FromFrames((long)InFrame);
            }
            else
            {
                MediaStream stream = media.Streams.GetItemByMediaType(MediaType.Audio, 0);
                AudioEvent aEvent = new AudioEvent(Timecode.FromFrames((long)StartFrame) + baseStartPosition, Timecode.FromFrames((long)EndFrame) - Timecode.FromFrames((long)StartFrame));
                aTrack.Events.Add(aEvent);
                Take myNewtake = new Take(stream);
                aEvent.Takes.Add(myNewtake);
                myNewtake.Offset = Timecode.FromFrames((long)InFrame);
            }
        }

    }
}

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

 

Soksoa wrote on 4/9/2023, 12:00 PM

First and foremost, I would like to express my gratitude for your effort in providing a version of the script. However, I have noticed some minor issues:

It seems that the XML files are not being imported correctly. The script is not selecting the appropriate video regions as it would if the file were imported normally (through the menu).

When attempting to import large files, the script fails to position the XML files correctly, resulting in all of them overlapping each other. You mentioned something about adjusting the correct video settings. Could this be related to the issue at hand?

I have attempted to troubleshoot these issues, but it would be great if you could take a look as well. I now have some media available where I talk for testing the script further. Please note that it is in Spanish, and you can access it here: https://www.mediafire.com/file/hrvb8ckid5v3xuv/More+media.zip/file

jetdv wrote on 4/9/2023, 2:52 PM

@Soksoa It appears I am properly reading the values and properly adding the events. However, my events are twice as long an an imported event. I believe this is because your video is 60fps and my timeline is 30fps.

Ok, this version now reads the framerate, width, and height from the xml file and sets them accordingly. Let's see how that works... My test showed the import seemed to be the same except I added a stereo track and the "import" seems to be left only.
 

using System;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Drawing;
using System.Runtime;
using System.Xml;
using ScriptPortal.Vegas;

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;
        private NumberFormatInfo myNumberFormat = NumberFormatInfo.InvariantInfo;
        private string[] filenames;
        private string clipitemFile;
        Timecode baseStartPosition;
        VideoTrack vTrack;
        AudioTrack aTrack;

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

            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Import Files (*.XML)|*.xml|All Files (*.*)|*.*";
            ofd.Multiselect = true;
            ofd.Title = "Select the files to import";
            ofd.InitialDirectory = "D:\\Edward_\\Import"; //Change this to where you want it to look by default
            DialogResult dr = ofd.ShowDialog();
            if (dr == System.Windows.Forms.DialogResult.OK)
            {
                filenames = ofd.FileNames;
                myVegas.NewProject(false, false);
                vTrack = new VideoTrack();
                myVegas.Project.Tracks.Add(vTrack);
                aTrack = new AudioTrack();
                myVegas.Project.Tracks.Add(aTrack);
                myVegas.Transport.CursorPosition = Timecode.FromFrames(0);

                foreach (string file in filenames)
                {
                    baseStartPosition = myVegas.Transport.CursorPosition;
                    processImportFile(file);
                    myVegas.Transport.CursorPosition = myVegas.Project.Length;
                }

            }
        }

        private void processImportFile(string myFile)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(myFile);
            XmlElement root = doc.DocumentElement;
            foreach (XmlElement child in root)
            {
                if (child.Name.ToLower() == "sequence")
                {
                    foreach (XmlElement child2 in child)
                    {
                        if (child2.Name.ToLower() == "media")
                        {
                            foreach (XmlElement child3 in child2)
                            {
                                if (child3.Name.ToLower() == "video" || child3.Name.ToLower() == "audio")
                                {
                                    string mediaType = child3.Name.ToLower();
                                    foreach (XmlElement child4 in child3)
                                    {
                                        if (child4.Name.ToLower() == "format")
                                        {
                                            setProjectProperties(child4);
                                        }
                                        if (child4.Name.ToLower() == "track")
                                        {
                                            foreach(XmlElement child5 in child4)
                                            {
                                                if (child5.Name.ToLower() == "clipitem")
                                                {
                                                    processClipItem(child5, mediaType);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        private void setProjectProperties(XmlElement root)
        {
            foreach(XmlElement child in root)
            {
                if (child.Name.ToLower() == "samplecharacteristics")
                {
                    foreach (XmlElement child2 in child)
                    {
                        if (child2.Name.ToLower() == "rate")
                        {
                            foreach (XmlElement child3 in child2)
                            {
                                if (child3.Name.ToLower() == "timebase")
                                {
                                    myVegas.Project.Video.FrameRate = Convert.ToDouble(child3.InnerText);
                                }
                            }
                        }
                        if (child2.Name.ToLower() == "width")
                        {
                            myVegas.Project.Video.Width = Convert.ToInt16(child2.InnerText);
                        }
                        if (child2.Name.ToLower() == "height")
                        {
                            myVegas.Project.Video.Height = Convert.ToInt16(child2.InnerText);
                        }
                    }
                }
            }
        }

        private void processClipItem(XmlElement clipitem, string mediaType)
        {
            double StartFrame = 0;
            double EndFrame = 0;
            double InFrame = 0;
            double OutFrame = 0;
            string MasterClipID = "";

            foreach (XmlElement child in clipitem)
            {
                string childName = child.Name.ToLower();
                switch (childName)
                {
                    case "masterclipid":
                        MasterClipID = child.InnerText;
                        break;
                    case "start":
                        StartFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "end":
                        EndFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "in":
                        InFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "out":
                        OutFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "file":
                        foreach(XmlElement child2 in child)
                        {
                            if (child2.Name.ToLower() == "pathurl")
                            {
                                clipitemFile = child2.InnerText;
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            addClipToTimeline(clipitemFile, StartFrame, EndFrame, InFrame, OutFrame, mediaType);
        }

        private void addClipToTimeline(string fileName, double StartFrame, double EndFrame, double InFrame, double OutFrame, string mediaType)
        {
            //MessageBox.Show(fileName + "  s" + StartFrame + "  e" + EndFrame + "  i" + InFrame + "  o" + OutFrame + "  " + mediaType);

            Media media = new Media(fileName);
            if (mediaType == "video")
            {
                MediaStream stream = media.Streams.GetItemByMediaType(MediaType.Video, 0);
                VideoEvent vEvent = new VideoEvent(Timecode.FromFrames((long)StartFrame) + baseStartPosition, Timecode.FromFrames((long)EndFrame) - Timecode.FromFrames((long)StartFrame));
                vTrack.Events.Add(vEvent);
                Take myNewtake = new Take(stream);
                vEvent.Takes.Add(myNewtake);
                myNewtake.Offset = Timecode.FromFrames((long)InFrame);
            }
            else
            {
                MediaStream stream = media.Streams.GetItemByMediaType(MediaType.Audio, 0);
                AudioEvent aEvent = new AudioEvent(Timecode.FromFrames((long)StartFrame) + baseStartPosition, Timecode.FromFrames((long)EndFrame) - Timecode.FromFrames((long)StartFrame));
                aTrack.Events.Add(aEvent);
                Take myNewtake = new Take(stream);
                aEvent.Takes.Add(myNewtake);
                myNewtake.Offset = Timecode.FromFrames((long)InFrame);
            }
        }

    }
}

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

 

Soksoa wrote on 4/9/2023, 4:33 PM

Yay! It's working, but there's one weird thing. The program starts overlapping all of the clips after reach 2 minutes in the timeline.

jetdv wrote on 4/9/2023, 6:56 PM

@Soksoa Ok, I have that fixed now. VEGAS was not sending the proper information back to the script because it had not properly updated. Please change this:

 

                foreach (string file in filenames)
                {
                    baseStartPosition = myVegas.Transport.CursorPosition;
                    processImportFile(file);
                    myVegas.Transport.CursorPosition = myVegas.Project.Length;
                }

to this (adding the bolded line):

               foreach (string file in filenames)
                {
                    baseStartPosition = myVegas.Transport.CursorPosition;
                    processImportFile(file);
                    myVegas.UpdateUI();

                    myVegas.Transport.CursorPosition = myVegas.Project.Length;
                }

It's at the top around lines 45 - 50...

Soksoa wrote on 4/9/2023, 8:28 PM

It works flawlessly now, you truly saved me hours! I can't thank you enough for your assistance, @jetdv.
Please let me know if there's anything I can do to return the favor, please don't hesitate to ask.
Thanks again for everything, and have a great day!

Soksoa wrote on 6/27/2023, 1:15 PM

Hey there! I've been using this program for a while now. It still works without any issue. However, it would be great if the corresponding video and audio tracks grouped together after being imported (just as if they were added to the timeline normally). Could you help me on this @jetdv?
Here is the code:

 

using System;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Drawing;
using System.Runtime;
using System.Xml;
using ScriptPortal.Vegas;

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;
        private NumberFormatInfo myNumberFormat = NumberFormatInfo.InvariantInfo;
        private string[] filenames;
        private string clipitemFile;
        Timecode baseStartPosition;
        VideoTrack vTrack;
        AudioTrack aTrack;

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

            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Import Files (*.XML)|*.xml|All Files (*.*)|*.*";
            ofd.Multiselect = true;
            ofd.Title = "Select the files to import";
            ofd.InitialDirectory = "D:\\Edward_\\Import"; //Change this to where you want it to look by default
            DialogResult dr = ofd.ShowDialog();
            if (dr == System.Windows.Forms.DialogResult.OK)
            {
                filenames = ofd.FileNames;
                myVegas.NewProject(false, false);
                vTrack = new VideoTrack();
                myVegas.Project.Tracks.Add(vTrack);
                aTrack = new AudioTrack();
                myVegas.Project.Tracks.Add(aTrack);
                myVegas.Transport.CursorPosition = Timecode.FromFrames(0);

                foreach (string file in filenames)
                {
                    baseStartPosition = myVegas.Transport.CursorPosition;
                    processImportFile(file);
                    myVegas.UpdateUI();
                    myVegas.Transport.CursorPosition = myVegas.Project.Length;
                }

            }
        }

        private void processImportFile(string myFile)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(myFile);
            XmlElement root = doc.DocumentElement;
            foreach (XmlElement child in root)
            {
                if (child.Name.ToLower() == "sequence")
                {
                    foreach (XmlElement child2 in child)
                    {
                        if (child2.Name.ToLower() == "media")
                        {
                            foreach (XmlElement child3 in child2)
                            {
                                if (child3.Name.ToLower() == "video" || child3.Name.ToLower() == "audio")
                                {
                                    string mediaType = child3.Name.ToLower();
                                    foreach (XmlElement child4 in child3)
                                    {
                                        if (child4.Name.ToLower() == "format")
                                        {
                                            setProjectProperties(child4);
                                        }
                                        if (child4.Name.ToLower() == "track")
                                        {
                                            foreach(XmlElement child5 in child4)
                                            {
                                                if (child5.Name.ToLower() == "clipitem")
                                                {
                                                    processClipItem(child5, mediaType);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        private void setProjectProperties(XmlElement root)
        {
            foreach(XmlElement child in root)
            {
                if (child.Name.ToLower() == "samplecharacteristics")
                {
                    foreach (XmlElement child2 in child)
                    {
                        if (child2.Name.ToLower() == "rate")
                        {
                            foreach (XmlElement child3 in child2)
                            {
                                if (child3.Name.ToLower() == "timebase")
                                {
                                    myVegas.Project.Video.FrameRate = Convert.ToDouble(child3.InnerText);
                                }
                            }
                        }
                        if (child2.Name.ToLower() == "width")
                        {
                            myVegas.Project.Video.Width = Convert.ToInt16(child2.InnerText);
                        }
                        if (child2.Name.ToLower() == "height")
                        {
                            myVegas.Project.Video.Height = Convert.ToInt16(child2.InnerText);
                        }
                    }
                }
            }
        }

        private void processClipItem(XmlElement clipitem, string mediaType)
        {
            double StartFrame = 0;
            double EndFrame = 0;
            double InFrame = 0;
            double OutFrame = 0;
            string MasterClipID = "";

            foreach (XmlElement child in clipitem)
            {
                string childName = child.Name.ToLower();
                switch (childName)
                {
                    case "masterclipid":
                        MasterClipID = child.InnerText;
                        break;
                    case "start":
                        StartFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "end":
                        EndFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "in":
                        InFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "out":
                        OutFrame = Convert.ToDouble(child.InnerText);
                        break;
                    case "file":
                        foreach(XmlElement child2 in child)
                        {
                            if (child2.Name.ToLower() == "pathurl")
                            {
                                clipitemFile = child2.InnerText;
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            addClipToTimeline(clipitemFile, StartFrame, EndFrame, InFrame, OutFrame, mediaType);
        }

        private void addClipToTimeline(string fileName, double StartFrame, double EndFrame, double InFrame, double OutFrame, string mediaType)
        {
            //MessageBox.Show(fileName + "  s" + StartFrame + "  e" + EndFrame + "  i" + InFrame + "  o" + OutFrame + "  " + mediaType);

            Media media = new Media(fileName);
            if (mediaType == "video")
            {
                MediaStream stream = media.Streams.GetItemByMediaType(MediaType.Video, 0);
                VideoEvent vEvent = new VideoEvent(Timecode.FromFrames((long)StartFrame) + baseStartPosition, Timecode.FromFrames((long)EndFrame) - Timecode.FromFrames((long)StartFrame));
                vTrack.Events.Add(vEvent);
                Take myNewtake = new Take(stream);
                vEvent.Takes.Add(myNewtake);
                myNewtake.Offset = Timecode.FromFrames((long)InFrame);
            }
            else
            {
                MediaStream stream = media.Streams.GetItemByMediaType(MediaType.Audio, 0);
                AudioEvent aEvent = new AudioEvent(Timecode.FromFrames((long)StartFrame) + baseStartPosition, Timecode.FromFrames((long)EndFrame) - Timecode.FromFrames((long)StartFrame));
                aTrack.Events.Add(aEvent);
                Take myNewtake = new Take(stream);
                aEvent.Takes.Add(myNewtake);
                myNewtake.Offset = Timecode.FromFrames((long)InFrame);
            }
        }

    }
}

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

 

jetdv wrote on 6/27/2023, 4:53 PM

@Soksoa Can we just group everything that is in each XML file together? So each XML file would be grouped? If yes, that's a fairly easy change. Otherwise, the importing is "really dumb". It's not looking at the details to see if one audio event goes with a specific video event. But being able to group the entire XML file being imported would be doable very quickly.

BTW, a 3 part tutorial on this will be out starting at the end of August.