logo

Live Production Software Forums


Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

26 Pages«<242526
Options
Go to last post Go to first unread
ajfnetwork  
#501 Posted : Saturday, March 23, 2024 2:59:16 AM(UTC)
ajfnetwork

Rank: Newbie

Groups: Registered
Joined: 3/17/2024(UTC)
Posts: 4
Venezuela
Location: San Carlos Cojedes

Originally Posted by: doggy Go to Quoted Post
Originally Posted by: ajfnetwork Go to Quoted Post
Hello colleagues, I hope you are well... I have the following question...

It would be possible to make a script, I don't know if it already exists, can someone advise me since I'm new to scripts...

Does it allow me to place titles every time a data source is updated by XML? If I can explain myself correctly...

That every time the XML data source is updated, the title overlay is activated.

I hope you can help me... thank you very much


Read content of title by reading the API XML or using the Input.Find() option
Compare to a previously saved content , if different perform action , save new content for next comparison. Rinse and repeat

PLS go through the multiple examples in this thread on how to read info from the api xml
go through the multiple online tutorials on programming in vb.net



Hello friend, how are you? I don't understand much of what you just told me, what is the first thing I should do? Since I don't know.
doggy  
#502 Posted : Saturday, March 23, 2024 3:23:12 AM(UTC)
doggy

Rank: Advanced Member

Groups: Registered
Joined: 12/27/2012(UTC)
Posts: 5,144
Belgium
Location: Belgium

Thanks: 286 times
Was thanked: 932 time(s) in 770 post(s)
Originally Posted by: ajfnetwork Go to Quoted Post
Originally Posted by: doggy Go to Quoted Post
Originally Posted by: ajfnetwork Go to Quoted Post
Hello colleagues, I hope you are well... I have the following question...

It would be possible to make a script, I don't know if it already exists, can someone advise me since I'm new to scripts...

Does it allow me to place titles every time a data source is updated by XML? If I can explain myself correctly...

That every time the XML data source is updated, the title overlay is activated.

I hope you can help me... thank you very much


Read content of title by reading the API XML or using the Input.Find() option
Compare to a previously saved content , if different perform action , save new content for next comparison. Rinse and repeat

PLS go through the multiple examples in this thread on how to read info from the api xml
go through the multiple online tutorials on programming in vb.net



Hello friend, how are you? I don't understand much of what you just told me, what is the first thing I should do? Since I don't know.


as quoted:
Quote:
PLS go through the multiple examples in this thread on how to read info from the api xml
go through the multiple online tutorials on programming in vb.net
videokommando  
#503 Posted : Wednesday, March 27, 2024 6:18:12 AM(UTC)
videokommando

Rank: Advanced Member

Groups: Registered
Joined: 4/2/2013(UTC)
Posts: 48
Man
Location: Hungary

Thanks: 3 times
I have studied XML.
Why are there 8 overlay channels?

<overlay number="1">6</overlay>
<overlay number="2">7</overlay>
<overlay number="3">8</overlay>
<overlay number="4"/>
<overlay number="5"/>
<overlay number="6"/>
<overlay number="7"/>
<overlay number="8"/>

And an other question:
Can I see/read in script the last keystroke?
Is it possible to work with the midi or keyboard keystroke in script?

Thank you.
doggy  
#504 Posted : Wednesday, March 27, 2024 7:00:25 AM(UTC)
doggy

Rank: Advanced Member

Groups: Registered
Joined: 12/27/2012(UTC)
Posts: 5,144
Belgium
Location: Belgium

Thanks: 286 times
Was thanked: 932 time(s) in 770 post(s)
Originally Posted by: videokommando Go to Quoted Post
I have studied XML.
Why are there 8 overlay channels?

<overlay number="1">6</overlay>
<overlay number="2">7</overlay>
<overlay number="3">8</overlay>
<overlay number="4"/>
<overlay number="5"/>
<overlay number="6"/>
<overlay number="7"/>
<overlay number="8"/>


4 overlays and 4 stingers (can see that in the overlay settings number dropdown)

Quote:

And an other question:
Can I see/read in script the last keystroke?


No (unless you create a keylogger which is generally frowned upon)

Quote:

Is it possible to work with the midi or keyboard keystroke in script?

Thank you.


No (not that i am aware of ). Maybe Google has an answer
Video-Chopper  
#505 Posted : Wednesday, March 27, 2024 7:05:38 AM(UTC)
Video-Chopper

Rank: Member

Groups: Registered
Joined: 5/18/2023(UTC)
Posts: 16
United States
Location: Colorado

Thanks: 4 times
Beat me to it, Doggy!
videokommando  
#506 Posted : Wednesday, March 27, 2024 7:25:23 AM(UTC)
videokommando

Rank: Advanced Member

Groups: Registered
Joined: 4/2/2013(UTC)
Posts: 48
Man
Location: Hungary

Thanks: 3 times
Originally Posted by: doggy Go to Quoted Post
Originally Posted by: videokommando Go to Quoted Post
I have studied XML.
4 overlays and 4 stingers (can see that in the overlay settings number dropdown)
Quote:

And an other question:
Can I see/read in script the last keystroke?


No (unless you create a keylogger which is generally frowned upon)

Quote:

Is it possible to work with the midi or keyboard keystroke in script?

Thank you.


No (not that i am aware of ). Maybe Google has an answer



There isn't dropdown if I don't use stinger. But I understand this.

I will use DynamicValue instead of keystrokes.

Thank you.
doggy  
#507 Posted : Tuesday, April 23, 2024 5:44:48 AM(UTC)
doggy

Rank: Advanced Member

Groups: Registered
Joined: 12/27/2012(UTC)
Posts: 5,144
Belgium
Location: Belgium

Thanks: 286 times
Was thanked: 932 time(s) in 770 post(s)
Here is another fun one

displaying Instant Replay Event Tags during replays

Code:
'Display Tag(s) of instant replay(s) playing

'ReplayStartStopRecording  to update XML after adding tags (vMix BUG), or open/close  IR configuration!!
'run script and do a replay , tag will be displayed in title
'made for 4K license ( one replay angle)

' Setup : Edit accordingly =========================
dim RFolder as string = "E:\Replay"           ' Instant Replay Folder 
dim TagTitle as string = "Blue.gtzip"          ' Title name or Input number to display Tag on
dim TagText as string = "Headline.Text"       ' Title TextBlock to hold the Tag
dim EvenText as string = "Description.Text"   ' Title TextBlock to hold the Event name
' ==================================================

dim x as new system.xml.xmldocument
Dim document As XmlDocument = New XmlDocument()

do while true 
    x.loadxml(API.XML())

    'get the events number (to select list )
    dim events as string = x.SelectSingleNode("//input[@type='Replay']//replay/@events").value
    'get the channelmode used 
    dim mode AS string = x.SelectSingleNode("//input[@type='Replay']//replay/@channelMode").value

    dim Rinput as string
    if mode = "B"  'which channel is one using 
       Rinput = "ReplayPreview"
    else
       Rinput = "Replay"
    end if
   
    document.Load(RFolder & "\replay2.xml")  'get XML for retrieving tags

    Dim nodeList As XmlNodeList = document.SelectNodes("//list[" & events & "]/event")
    Dim count As Integer = nodeList.Count
    dim z as integer

    do while true
        x.loadxml(API.XML())
        dim state as string = x.SelectSingleNode("//input[@type='" & Rinput & "']/@state").value  'get the state of replay (Running or Paused), mode dependent

        if state = "Running"

            '********************** Optional  Comment out if not needed *************
            dim eventname as string =document.SelectSingleNode("//list[" & events & "]/@name").innertext
            if eventname = "" 
                eventname= events 'if not name show events number
            end if
            ' Display the EVENTNAME
            API.Function("SetText",Input:=TagTitle,SelectedName:=EvenText,Value:=eventname ) 
            '***********************************

            dim pos as string = x.SelectSingleNode("//input[@type='" & Rinput & "']/@position").value   
            for z  = 1 to count
                dim ins as string = (document.SelectSingleNode("//list[" & events & "]/event["& z & "]/inPoint").innertext)\10000 
                dim outs as string = (document.SelectSingleNode("//list[" & events & "]/event["& z & "]/outPoint").innertext)\10000 
                if (pos > ins) and (pos < outs)
                    dim tag as string = document.SelectSingleNode("//list[" & events & "]/event["& z & "]/description[1]").innertext  
                    API.Function("SetText",Input:=TagTitle,SelectedName:=TagText,Value:=tag )  'display the TAG
                end if 
            next
        else
            API.Function("SetText",Input:=TagTitle,SelectedName:=TagText,Value:=" stopped " )  'clear/done title
            Exit do 
        end if
        sleep(200)
    loop
    sleep(500)
loop
WaltG12  
#508 Posted : Wednesday, April 24, 2024 8:00:15 AM(UTC)
WaltG12

Rank: Advanced Member

Groups: Registered
Joined: 7/4/2021(UTC)
Posts: 201
United States

Thanks: 6 times
Was thanked: 24 time(s) in 24 post(s)
I know absolutely nothing about VB.net scripting.

But, over the years, I’ve been able to piece together scripts and knowledge from here and elsewhere.

So I thought I’d post here to help out anyone having difficulty with figuring out how to check a single element’s status and act based on that element.

Now, again, I know nothing on this subject. These scripts have worked for me, but if there’s a cleaner or better way to achieve the same goal, I’m most open to being corrected.

The API reports status in the form of input numbers for:

active
preview
overlay
mix (active and preview)

The API reports status in the form of “True”/”False” for:

fadeToBlack
recording
external
streaming
playList
multiCorder
fullscreen

(There are probably others in both categories, but these are the ones I worked with. This should be modular enough to adapt easily to others.)

The process of getting and acting based off an input number alone is the exact same as getting and acting based off a True/False status.

The script I use for that is this:

Code:
dim xml as string = API.XML()
dim GetInputNumber as string = ""

dim x as new system.xml.xmldocument
x.loadxml(xml)

GetInputNumber = (x.SelectSingleNode("/vmix/active").InnerText)


if GetInputNumber = "1"

API.Function("Cut")

end if



This is a script you’ve probably seen already.

But I want to break it down to help you modify it.

Code:
GetInputNumber


is a user-defined variable. You can make It what you want it to be, as long as you change it everywhere it comes up to the same thing.

Where it says

Code:
/vmix/active


is what defines which node on the API XML you’re looking at. It can be changed.

If you want to get the input number of the preview, that would be

Code:
/vmix/preview


If you want to get the input number assigned to a specific Overlay channel, that would be

Code:
//overlays/overlay[1]


where the number in brackets corresponds to which instance of nodes called “overlay” under the parent “overlays” you’re looking up.

1 is going to the the first on the list. 8 is going to be last on the list. 2-7 are, obviously, everything in between.

Mix inputs are similar to Overlays, but they’re a little less intuitive.

To get the preview of a Mix input, that’s

Code:
//mix[1]/preview


For the active (output) on a Mix input, just swap the word “active” where it says “preview”.

The number in the brackets corresponds to the instances of nodes called “mix”.

That means that the first Mix input, which calls itself Mix 2 and appears on the API as

Quote:
<mix number="2">


will actually be mix[1] under this system. And on up from there.

In a way this actually helps, because the numbering here reflects the same “one less” numbering used by API function shortcuts that these scripts fire.

Just as a reminder, this only returns input numbers.

So what you’re checking against has to be the input number—not the name or anything else.

Code:
if GetInputNumber = "1"


is a basic “if” statement. It can be followed by “elseif” or “else” statements above the “end if” for more granular control.

The VB.net operator for equivalent is

Code:
=


That means that the input number you’re asking the script to check is the same as the one you specified.

The VB.net operator for inequivalent is

Code:
<>


That means that the script returns anything other than the input number you specified.

So if you only want it to fire the command if the input number returned is NOT 1, you’d use

Code:
if GetInputNumber <> "1"


On items that the API XML shows as empty and self closing (such as overlays), you can specify “nothing” where, instead of checking against a specific input number, you check to see if there’s an input assigned at all, and fire based on that.

The syntax for that is

Code:
if GetInputNumber = nothing


As I previously said, the elements that return True/False values are checked the exact same way, but they return either “True” or “False” instead of a number.

So, using the same variable name for the sake of simplicity, it would be

Code:
if GetInputNumber = "True"


Or, of course, “False” can be substituted for “True”.

Here’s the syntax for all of those, as well as everything previously listed just to put it all in one box.

Code:
//fadeToBlack
//recording
//external
//streaming
//playList
//multiCorder
//fullscreen
/vmix/active
/vmix/preview
//overlays/overlay[1]
//mix[1]/preview
//mix[1]/active


Now, personally, I like working with input names, because I give each input a unique and specific name. Others like working with the GUID/key.

You can get either of these, as well as others, from the same script by adding an extra step.

Here’s the full script I use for that.

Code:
dim xml as string = API.XML()
dim GetInputNumber as string = ""
dim GetInputName as string = ""

dim x as new system.xml.xmldocument
x.loadxml(xml)

GetInputNumber = (x.SelectSingleNode("/vmix/active").InnerText)

GetInputName = (x.SelectSingleNode("//input[@number='"& GetInputNumber &"']/@title").Value)


if GetInputName = "MyVideo"

API.Function("Cut")

end if


You’ll notice this is the same script, just with an additional user-defined variable and an extra step.

You’ll also notice that the name of the previous variable to get the input number is used within that second step, so make sure you also change it there if you change it.

What this is doing is getting the “title” attribute from the specified input node.

That means that you can get any other input attribute by replacing the word “title” with the name of your desired attribute.

These vary by input type, and there are quite a few of them, so I won’t list them all, but I’ll provide a few examples to give you an idea of what you’re looking for. (For the sake of simplicity, I’m going to maintain the same variable name.)

Code:
GetInputName = (x.SelectSingleNode("//input[@number='"& GetInputNumber &"']/@type").Value)


will give you the input type. For example: Mix, Colour, AudioFile, Video, Capture, etc.

So if you want to do something if check if the active input (output) is a camera, you’d use that line, combined with

Code:
if GetInputName = "Capture"


If you want to know if an input is playing or paused

Code:
GetInputName = (x.SelectSingleNode("//input[@number='"& GetInputNumber &"']/@state").Value)


will return either “Paused” or “Running”.

Code:
@loop
@muted
@solo


will all return either “True” or “False”.

There are a lot of options, and, again, they vary by input type. Check out the API—those examples should give you an idea of what you’re looking for.

If you know the input number, and don’t want to fetch it from elsewhere, you can adapt this script to that too.

Code:
dim xml as string = API.XML()
dim GetInputName as string = ""

dim x as new system.xml.xmldocument
x.loadxml(xml)

GetInputName = (x.SelectSingleNode("//input[1]/@title").Value)


if GetInputName = "MyVideo"

API.Function("Cut")

end if


As with above, the number in brackets (which was previously filled by the variable fetched in the previous step) corresponds to where on the list of nodes called “input” the requested element falls.

And, again, you can change the “title” attribute to any attribute within the element node.

(Special thanks to doggy and others for providing the backbone for my being able to scrape this knowledge together.)

WaltG12  
#509 Posted : Friday, April 26, 2024 3:22:24 PM(UTC)
WaltG12

Rank: Advanced Member

Groups: Registered
Joined: 7/4/2021(UTC)
Posts: 201
United States

Thanks: 6 times
Was thanked: 24 time(s) in 24 post(s)
I wanted to share my new script using the new “ZoomSelectParticipantByName” shortcut, in conjunction with Dynamic Input 1 and vMix Social, to automatically add Zoom guests to the next available Zoom input.

First, a few caveats:

1) This only works if you add every guest by using it. If you keep the first at “Default” or manually add people using the Zoom Manager, this script will do more harm than good.

2) As I mentioned in other posting above, I give my inputs unique names and prefer to use scripts that utilize those. This is one of them, and it explicitly requires that your first two Zoom inputs have unique and defined names.

3) This script, as you can tell by reading it, requires your Zoom inputs be right next to each other in order to function on the first run(s).

4) Make sure your vMix Social title mapping is correct. If you’re using Social for its intended purpose, you can adapt the script to that, but in doing so, you’ll probably want to curate your feed manually and add a step that wipes/otherwise resets the title.

Unless/until vMix adds more Zoom info to the API XML, this is the best I can think to do.

Code:
dim xml as string = API.XML()
dim CurrentDynamicInput1 as string = ""
dim SecondZoomInputNumber as string = ""

‘ In quotes is the name of the title input that contains the guest name(s)
dim GuestNameTitle as string = "GuestNameTitle"

‘ In quotes is the name of the text field in the title input that contains the guest name you want to assign to the Zoom input
dim GuestNameTextField as string = "GuestNameTextField.Text"

‘ In quotes is the unique name for your first Zoom input
dim FirstZoomInput as string = "Zoom1"

‘ In quotes is the unique name for your second Zoom input, no need to identify beyond that
dim SecondZoomInput as string = "Zoom2"

dim x as new system.xml.xmldocument
x.loadxml(xml)

CurrentDynamicInput1 = (x.SelectSingleNode("//dynamic/input1").InnerText)

dim GuestName as string = Input.Find(GuestNameTitle).Text(GuestNameTextField)

If CurrentDynamicInput1 = nothing OrElse CurrentDynamicInput1 = FirstZoomInput
API.Function("ZoomSelectParticipantByName",Input:=FirstZoomInput,Value:=GuestName)
Sleep(200)
SecondZoomInputNumber = (x.SelectSingleNode("//input[@title='"& SecondZoomInput &"']/@number").Value)
Sleep(100)
API.Function("SetDynamicInput1",Value:=SecondZoomInputNumber)

Else

API.Function("ZoomSelectParticipantByName",Input:=”Dynamic1”,Value:=GuestName)
Sleep(200)
dim NewDynamicInput1 as integer = cint(CurrentDynamicInput1)
NewDynamicInput1 +=1
API.Function("SetDynamicInput1",Value:=NewDynamicInput1)


End if


EDIT:

I just did another one that I like a bit better.

This one uses DynamicValues to track guest names, so it’ll be best for those with smaller productions (up to 4 guests) who aren’t already using Dynamic Values.

It can be adapted to use Titles instead of DynamicValues, to the same end, but it does require that every Zoom input be explicitly identified to work. So, again, it’s best for smaller productions.

But it does have the added benefit of double checking to make sure that a guest isn’t already in an input before adding them, which is why I prefer it to the other one.

It also accounts for if you accidentally run it before sending the guest name to the title by ruling out the placeholder text.

As the API XML doesn’t have any particular Zoom-specific information, you do still need to use it to add everyone in order for it to work properly, since it only knows who was added to an input because it logs who it adds to an input.


Code:
dim xml as string = API.XML()
dim DynamicValue1 as string = ""
dim DynamicValue2 as string = ""
dim DynamicValue3 as string = ""
dim DynamicValue4 as string = ""

‘ In quotes is the name of the title input that contains the guest name(s)
dim GuestNameTitle as string = "GuestNameTitle"

‘ In quotes is the name of the text field in the title input that contains the guest name you want to assign to the Zoom input
dim GuestNameTextField as string = "GuestNameText.Text"

‘ In quotes is the unique name for your first Zoom input
dim FirstZoomInput as string = "Zoom1"

‘ In quotes is the unique name for your second Zoom input
dim SecondZoomInput as string = "Zoom2"

‘ In quotes is the unique name for your third Zoom input
dim ThirdZoomInput as string = "Zoom3"

‘ In quotes is the unique name for your fourth Zoom input
dim FourthZoomInput as string = "Zoom4"

dim x as new system.xml.xmldocument
x.loadxml(xml)

dim GuestName as string = Input.Find(GuestNameTitle).Text(GuestNameTextField)

DynamicValue1 = (x.SelectSingleNode("//dynamic/value1").InnerText)

DynamicValue2 = (x.SelectSingleNode("//dynamic/value2").InnerText)

DynamicValue3 = (x.SelectSingleNode("//dynamic/value3").InnerText)

DynamicValue4 = (x.SelectSingleNode("//dynamic/value4").InnerText)

‘ I use the words Guest Name for the placeholder text in my title

If DynamicValue1 = nothing OrElse DynamicValue1 = GuestName OrElse DynamicValue1 = “Guest Name”
API.Function("SetDynamicValue1",Value:=GuestName)
Sleep(200)
API.Function("ZoomSelectParticipantByName",Input:=FirstZoomInput,Value:=GuestName)

Elseif DynamicValue2 = nothing OrElse DynamicValue2 = GuestName OrElse DynamicValue2 = “Guest Name”
API.Function("SetDynamicValue2",Value:=GuestName)
Sleep(200)
API.Function("ZoomSelectParticipantByName",Input:=SecondZoomInput,Value:=GuestName)

Elseif DynamicValue3 = nothing OrElse DynamicValue3 = GuestName OrElse DynamicValue3 = “Guest Name”
API.Function("SetDynamicValue3",Value:=GuestName)
Sleep(200)
API.Function("ZoomSelectParticipantByName",Input:=ThirdZoomInput,Value:=GuestName)

Elseif DynamicValue4 = nothing OrElse DynamicValue4 = GuestName OrElse DynamicValue4 = “Guest Name”
API.Function("SetDynamicValue4",Value:=GuestName)
Sleep(200)
API.Function("ZoomSelectParticipantByName",Input:=FourthZoomInput,Value:=GuestName)

End if
richardgatarski  
#510 Posted : Friday, June 28, 2024 8:41:34 AM(UTC)
richardgatarski

Rank: Advanced Member

Groups: Registered
Joined: 2/18/2014(UTC)
Posts: 1,833
Location: Stockholm

Thanks: 141 times
Was thanked: 295 time(s) in 249 post(s)
Here is a "dummy" script that illustrates how to send commands to Companion.

Code:
' Example, setting variables to something in Companion via TCP
' Illustrates how Companion can be commanded many times in a single client session
' By Richard Gatarski, 2024-06-28

' Prepare for TCP
    Dim tcpCompanionIP as string = "127.0.0.1"
    Dim tcpCompanionPort as integer = "16759"
    Dim client As New System.Net.Sockets.TcpClient(tcpCompanionIP, tcpCompanionPort)
    Dim stream As System.Net.Sockets.NetworkStream = client.GetStream()

' Define variables
    Dim content As String = "Default"
    Dim numberOfTimes as Integer = 4

' Loop a number of times
    For aNumber as Integer = 1 to numberOfTimes
        Dim customVariableName As String = "Var" & aNumber.ToString()
        Dim companionCommand as String = "CUSTOM-VARIABLE " & customVariableName  & " SET-VALUE " & content
        Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(companionCommand & Environment.NewLine)
        stream.Write(data, 0, data.Length)
    Next

' Close TCP
    stream.Close()
    client.Close()
thanks 1 user thanked richardgatarski for this useful post.
doggy on 6/28/2024(UTC)
Users browsing this topic
26 Pages«<242526
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.