Monday, March 24, 2025

Overlays.UNO - Update Stats from a Spreadsheet

Would you like to be able to use a spreadsheet data to update some Overlays.UNO fields? 
Here's a bit of a hack aka work around.  Its a work in progress, but I've used it fairly successfully.

What it does is take the values you put into the blue boxes in the sheet and then generate the JSON code that overlays.UNO want to update that element.  By copying/pasting them, it will update all or some of them, depending on what you paste.  In my own deployment, I've used keyboard macro to help speed up the copy/paste of the lines.  I think it would be possible to have this work from the spreadsheet itself, with some google script code or Microsoft excel macroing.

For example, the "Player BIO | Varsity" overlay:



All the data has to be entered in manually normally.  Not really convenient.  You could build a overlay for each person, but its cumbersome. 


Well, it COULD be done through a spreadsheet.

This sheet, again, it's not perfect at this point, but it's a start.

The data can be entered into the blue boxes on the left, and it will generate the appropriate code on the right that you can copy into a CMD prompt and run to update your sheet.  This data could also be scraped data from another scoring system that you could use.  I've done it successfully with Daktronics Dakstats websites.

You can select all the CMDs and paste them all at the same time to update everything, or just 1 at a time if you prefer.


Here's a link to the ODS spreadsheet file.


TO make it work, you'll need to first get your Overlay API and paste it into the sheet


Then you'll need the JSON ID. 

The sheet, when you put in the API value, will automatically generate the code for windows CMD prompt for you to get the JSON ID.  


Paste that syntax circled in red from your sheet into a CMD prompt and press enter.  
Will look something like this:


Once you paste this value into the sheet, you will be able to control the overlay.

Key in the data that you want to display.



Copy these lines if you want to update everything, or just copy the line beside the data you changed.


Then Paste it into a CMD prompt

You may get a warning

This comes up because you are pasting a bunch of lines.

You'll see a bunch of stuff on the CMD prompt window as the JSON code is sent to Overlays.UNO

You should see the data in Overlays now reflect what was in the spreadsheet.




To do the logs, go to your logos that you have uploaded to your account in Overlays.Uno




Copy the URL for the picture you want.

Then paste it in the spreadsheet for the Team Image and the Headshot


Copy/paste the CURL command to the right of it to update them.



Monday, March 17, 2025

Control Overlays.UNO from command line

Control Overlays.UNO alternatively to the GUI?  

  • To interact with Overlays.UNO without needing to rely on the GUI.
  • Control from OBS or vMIX if possible.
  • Avoid needing 3rd party applications or hardware and use basic keyboard hotkeys.

IN A NUT SHELL

Overlays.UNO uses PUT statements using JSON for control.

To make it work with as many systems as possible, the 
CURL command is used which isn't OS dependent outside of minor syntax formatting tweaks for your flavor of OS.  These examples in this document are for Windows CMD prompt, and required to have slashes in front of any quotation inside a curly brace

"{\"JSON CODE\"}"

Overlays.UNO need the URL API and in some cases a specific JSON ID associated to the overlay.

The CURL syntax below is an example of how to send direct commands to Overlays.uno. 

curl -i -H "Content-Type:application/json" -d "{"JSON CODE"}" -X PUT https://app.overlays.uno/apiv2/controlapps/xxxAPI_VALUExxx/api

The above command is reformatted below for Windows CMD with a slash marks as mentioned above:

curl -i -H "Content-Type:application/json" -d "{\"JSON CODE\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/xxxAPI_VALUExxx/api

DEMO

For this demo the overlay "Hockey Scorebug | Standard" is being used.  Load this from overlays.uno and you should be able to apply the information in this doc with your own deployment.


Launch it and the default looks basically like this below:


Click on the question mark and click on API description


Your going to see this:


The API endpoint URL is displayed here at the top, so copy and save that for easy retrieval



For this Overlay example we are using here, the 
JSON ID is required.
Run the following command, substitute your API endpoint value that is in RED

curl -i -H "Content-Type:application/json" -d "{\"command\": \"GetOverlays\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api

Copy the ID that yours returns with as you will need it (yellow)



For demonstration, we'll start by turning the overlay ON and OFF. 

When we got the API endpoint URL above, it also contained some of the possible commands that could be issued, the first two being "ShowOverlay" and "HideOverlay"



HideOverlay 

Modify the command below with your JSON and API data.
Paste into a CMD prompt and press enter.

curl -i -H "Content-Type:application/json" -d "{\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"command\": \"HideOverlay\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
And if you look at overlays.UNO, the overlay should be gone.


ShowOverlay

By following the substitution steps above with the command will allow you to display the Overlay.

curl -i -H "Content-Type:application/json" -d "{\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"command\": \"ShowOverlay\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api



TEAM GOALS

You can "Increment" or "Decrement" the score by a specific value 
OR you can set the goal directly to any value.

Increase Team 2 Goals by 3
curl -i -H "Content-Type:application/json" -d "{\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"command\": \"IncrementOverlayContentField\",\"fieldId\": \"Team 2 Goals\",\"value\": \"3\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
Set Team 1 Goals to 13
curl -i -H "Content-Type:application/json" -d "{\"command\": \"SetOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"Team 1 Goals\",\"value\": \"13\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
CLOCK (Change the time)

Increment the clock by 1 minute
curl -i -H "Content-Type:application/json" -d "{\"command\": \"IncrementOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"Game Clock Minutes\",\"value\": \"1\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
Decrement the seconds by 15
curl -i -H "Content-Type:application/json" -d "{\"command\": \"DecrementOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"Game Clock Seconds\",\"value\": \"15\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
Change the minutes to a specific time "11"    
curl -i -H "Content-Type:application/json" -d "{\"command\": \"SetOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"Game Clock Minutes\",\"value\": \"11\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
Change seconds to a specific time "12"
curl -i -H "Content-Type:application/json" -d "{\"command\": \"SetOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"Game Clock Seconds\",\"value\": \"12\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api

START CLOCK  (Valid commands play, pause, reset and start)

curl -i -H "Content-Type:application/json" -d "{\"command\": \"ExecuteOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"GameClockControl\",\"value\": \"start\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/apicurl -i -H "Content-Type:application/json" -d "{\"command\": \"ExecuteOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"GameClockControl\",\"value\": \"True\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api

STOP CLOCK

curl -i -H "Content-Type:application/json" -d "{\"command\": \"ExecuteOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"GameClockControl\",\"value\": \"pause\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/apicurl -i -H "Content-Type:application/json" -d "{\"command\": \"ExecuteOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"GameClockControl\",\"value\": \"True\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api



Period
(You can put any txt you want) (1,1st,ShootOut, OT etc, different language versions)
curl -i -H "Content-Type:application/json" -d "{\"command\": \"SetOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"Period\",\"value\": \"2ND\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
ALERT ON/OFF  (replace TRUE with FALSE)
curl -i -H "Content-Type:application/json" -d "{\"command\": \"SetOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"alert\",\"value\": \"true\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
ALERT Text - Custom (Penalty, Timeout, GAME 3)
curl -i -H "Content-Type:application/json" -d "{\"command\": \"SetOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"Alert Text\",\"value\": \"REDS\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
TEAM NAMES

Change Team 1 to "BLUES"
curl -i -H "Content-Type:application/json" -d "{\"command\": \"SetOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"Team 1\",\"value\": \"BLUES\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
Change Team 2 to "REDS"
curl -i -H "Content-Type:application/json" -d "{\"command\": \"SetOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"Team 2\",\"value\": \"REDS\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
LOGOS ACTIVE  (on/off)
curl -i -H "Content-Type:application/json" -d "{\"command\": \"SetOverlayContentField\",\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"fieldId\": \"logosActive\",\"value\": \"false\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api

JSON commands in detail:

Another way to determine some of the JSON values, and syntax that can be helpful is to use "Postman" 
Download Postman | Get Started for Free which is a system to allow you to review JSON code and do interaction to sites like Overlays.  Might help you.  It helped me quite a bit



COMMANDS IN DETAIL

Now the API document that you can find in the help menu will show the command syntax you'll need.  This is helpful...it is very generalized and not super helpful.

Along with the above syntax sequence, you also will need the values in the names.  So how do you increase the 

The names of the fields somewhat match the names they are given in the above picture, but to get a full list, well at least one that you can search through, use this command: "GetOverlayContent"

curl -i -H "Content-Type:application/json" -d "{\"id\": \"45eac98d-cc99-4a8a-b430-872391c30aca\",\"command\": \"GetOverlayContent\"}" -X PUT https://app.overlays.uno/apiv2/controlapps/0mNA1zjHa8jiElWzdWJb0Y/api
You'll get a return like this:


You'll see things that you can adjust, and most names match the gui description, but not all the names are the same.  In the GUI its called "Game Clock Control", but in JSON its "GameClockControl". The above helps to sort out some of the differences.   

Saturday, March 8, 2025

OBS - Advanced Scene Switcher examples

 Advanced Scene Switcher

Here are some of the things I've covered so far

SCENE        CLIPBOARD        CURSOR        DATE        DISPLAY        FILE

FILTER        FOLDER WATCH    HOTKEY        LOG    IDLE                WEBSOCKETS

VARIABLES    SOURCE        OPEN SOUND CONTROL (OSC)

Advanced Scene Switcher | OBS Forums

The basis of Advanced scene switcher is to detect the presence (or lack thereof) of a condition in OBS and follow a set of subsequent steps


Here are some examples:

===== SCENE ======

If a Specific Scene is Displayed -> Setup something in Preview
A real-world condition might be if you go to a camera that is setup as a close up some someone, perhaps you would want to automatically set the preview screen with their name at the bottom.

If Advanced scene Switcher detects a specific scene in program, it can automatically ensure a specific scene is put into the preview monitor.  

Here we have 2 scenes, a closeup shot in preview (left) and a wide shot in program (right)


Using Advanced Scene Switcher we can have a 3rd scene set into preview automatically with their name ready to be cut in using a rule like this:


This rule is 
If the current (program) scene matches (IE Camera 1 Closeup) 
then
Put the scene "Camera 1 Closeup with Name" into the preview window. 

So, without Advanced Scene Switcher running, when you go to the closeup shot in program, the preview window will switch to the old program window. 


BUT with 
Advanced Scene Switcher running with the rule as above, you will get this instead happen:



====== Audio ======

Have a macro kick off based on audio level or settings.

The example below, when the audio goes above -10dB, the hotkey to save the replay buffer is triggered, the system waits 2 seconds, then replays the event automatically.




====== CLIPBOARD ======

Here we've created a scene with a wideshot and the text "This is a news flash"

Now we'll create a rule that if the computers clipboard contains the next "Breaking News", this scene will automatically be displayed.





====== CURSOR ====== 

Trigger something to happen depending on where the cursor is, if it detects motion or if a left, middle or right mouse button is selected.

In this example, we will set OBS to automatically go to the wide shot if the cursor is put into the upper left corner of the screen.

If the cursor moves to position X=0 and Y=0  (upper left corner of screen), it will automatically switch to the wide shot.


Current view



Mouse pointer goes to upper left corner

The shot becomes this:



====== DATE ====== 

   Have something occur at a specific date


In this example, at 13.:44 every day, the system will start recording.

You could then have another macro that would stop the recording every day at 15:00

====== DISPLAY ====== 

If OBS detects a certain display to be part of the system, it can send a specific video to that monitor.



====== FILE ====== 

You can have something occur in OBS if a file is present or contains data. 
 In this example, we have a file called Closeup Activation.txt in the folder
C:\OBS Advanced Scene Switcher

If the content of this file has "Present" in it, OBS will automatically switch to the "Camera 1 Closeup"



The file looks like:


====== Folder Watch ====== 

Trigger an event if an event is detected within a folder. 

If an event happens in a folder, have it do something in OBS.

In this example, although we show several specific options, if OBS detects ANY change in a folder, it will switch the scene to a wide shot.


====== FILTER ====== 

Trigger an event if the "FILTER" on a specific scene or Source is active 

In this example, if the chroma filter is applied to the source called "Closeup Chroma" (which is an image in front of a green screen) then it will switch to a new scene applying a background (winter snow) to the image.  If it's not there, it will disable it.   This uses the "ELSE" function.


The result:


====== HOTKEY ====== 

Trigger an event if a HotKey is pressed.  AdvSS detects the activation of hotkeys that you assign VIA AdvSS.  Meaning, it doesn't listen for a key press, OBS listens for the keypress, AdvSS listens for its own configuration for the action.


So following this example pictured above, AdvSS will listen for "Macro trigger hotkey 15" which OBS listens for via F4

====== IDLE ====== 
If no mouse or keyboard activity is detected for a period of time, run some commands.





====== MIDI ====== 
I've only used this a small hand full of time so far.  But here are a few examples.

With your MIDI controller plugged in, select the model.  We are using "APC MINI 1" which is a multibutton midi pad

Click on "START" listening.

Press a button on your MIDI controller

In our example, while the button is held down on the controller we see this:

So we know that "TYPE" is note on, the channel is 1 and the NOTE value is 56.

While the button is pressed, click "STOP LISTENING"
You can release the button on the controller, and the values will remain in the view.

Now you can assign what you want to happen when this midi value is triggered.  In this case we are switching to "SCENE 2"

(using a Akai APC mini Midi controller, can turn lights on and off/blink on this controller

Value 1 = button ID
Value 2 = Color  
0-off 1-green 2-green blink 3-red 4-blink red 5-yellow 6-yellow blink


You can do something like this:

If the current scene = "Scene 1" then set the value(2) to "1" and make the first light go on

Else set value 2 to "0" so that the light goes out.

====== Media ====== 
Detect the state of media that is being played and base your event on that.


In this example, the system waits for the Instant_replay_Video to end.  This is the video from the replay buffer.  Once it ends, signifying the end of the replay, it will automatically transition back to the main follow camera.  Useful if you are changing your replay durations and play back speed.  It will automatically return once its done without having to alter any other timing functions.

====== LOG ====== 

You can add log entries into your OBS logo (in windows its in %appdata% in obs-studio -> logs)
C:\Users\X\AppData\Roaming\obs-studio\logs



It is a great way for debugging scripts.  Doesn't add load, I've had hundreds of these being sent to the log regularly.

You can send variables states stored in Advanced Scene Switcher in your log files.  The variable name is case sensitive.
add in a ${VarName} to your log message. 



====== IDLE ====== 

If the system detects no key or mouse movements, it will trigger.  

In this example, after 5 seconds, OBS will go to a Wide shot.


====== WEBSOCKETS ====== 
I keep a separate blog for Websockets on this blog.  just click on the link to go there.


====== HTML ====== 


I wanted to send a command from OBS to Vmix.  In this situation, OBS is the switcher, vMIX is the replay, so during a replay, i wanted to remote trigger vmix without needing an operator to do it.


vMIX can take web requests.  So in this example, I'm triggering the request using an HTTP request in the Advanced Scene Switcher.


The configuration looks like this. 


This is the syntax
http://VMIX-IP:PORT/api/?Function=COMMAND

Here's a list of possible commands that could be sent.

vMix User Guide

======  PROCESS ====== 

Trigger if specific process is in focus.  For example, you could be doing a screen capture, but perhaps you only want to record the window you have clicked on, and ONLY if that process is matching.  So this example will only record the screen if it sees a notepad file being worked on.

So here we are detecting if the NOTEPAD.EXE application is running AND is in focus

And if it is

Change the SOURCE item that is being recorded to match the executable " :NAME:NAME.EXE"

Which will make the Source called "Capture Notepad" change to the notepad window to be recorded




======  VARIABLES ====== 

When setting up a variable you can assigned a couple of initialization behaviors.  This occurs when you load OBS/load and/or load a new "scene collection"

Save / load behavior

"Don't save variable value" this means that whenever you exit OBS, that variable state disappears.  When you start the app, the variable value is null

"Save variable value" when you exit OBS, that value is saved and then loaded upon restart of the app

"Set to value" means that when you load OBS and this scene, it will set that value to one of your choosing.


"Set to Scene item name at index"
You can assign a scene item name to a variable.  I use case isn't jumping to my mind just yet, but its an interesting feature that I'm sure could be put to some use.

Here I have a scene that has 3 items, "red", "green" and "blue"


Perhaps I want to store the name of that second element as a variable.


This macro will let you store the name of the second item in "Scene 2", in this case to variable named "ItemColor"

The result of the above macro is Green

Perhaps you want to just get the name of the top 3


Here is some sample code:


The result would be:



This code will give you the first item name of whatever scene is in preview window


"Get User Input" This will prompt the user to type in something 





Here's a way to get the current scene name using a variable lookup.  



This does similar.  Sets the name of the current scene (scene 3 in my example) to the variable "TestVariable"


SEND DATA BETWEEN OBS
This example we can send variable data between OBS instances.


In this example, the source computer, we have a variable name called "TestVar"

The value contained in that is word "YourData".



Create a websocket using the send "Scene Switcher Message", request, and send it to your destination machine.  In this case it's called "GraphicsComputer" for my example.


On the receiving machine, create a macro just like the following:



This will set the value of "TestVar" in the sending machine, and in this case assign it to the variable "RequestID"



The value "YourData" is now assigned to the variable "RequestID"


====== SOURCE ====== 

You can use this to change settings of some items.  There is some really interesting features in this!

In this example, we'll change some settings in a Media Source, we'll toggle LOOP on or off.

First, you can do this to find what settings you probably can mess with

In your "IF" set it to SOURCE then select the source you want to look at.  In my example, I'm using MEDIA SOURCE".   Then select "SETTINGS MATCH".   Then at the bottom, select "Get Current Settings"

In this example, you see we see the current status of change "LOCAL FILE", "LOOPING" and "RESTART_ON_ACTIVE". 

This is what the above looks like.  Let's change the loop by turning it off and on


We'll use the SOURCE item in Advanced Scene Switcher and set it to "FALSE"


When you run this, the "LOOP" feature is turned off.

In this example, we selected "LOOP (BOOL)" but you can change a lot of things in media source.


We could pick "local file (path)" and set it to a completely different file. 

-RESULT-


Something like this would open up the settings of your camera input configuration


Running this gives you this window popping up


======  Open Sound Control (OSC) ====== 

Here's one nobody probably ever needed to do, but just in case!  If you want to use OBS to control QLC, you can do it via OSC.   Here's a bit of tutorial that I wrote to make QLC work with Synesthesia.live using OSC.  The configuration steps are the same, so go here for some details.  I'm just doing a really summed configuration here.

In OBS, in Advanced Scene Switcher, select OSC.  Note, i'm using a simple scene switch to trigger the OSC command

This is the basic command


In the message, I made my /button5  (for no good reason, just cause)
Everything else I pretty much left as is.

Now go to QLC

Create a QLC profile (or open an existing one)

Go to INPUTS/OUTPUTS and select a UNIVERSE.  This example uses Universe 4

Select "OSC 127.0.0.1  INPUT and FEEDBACK" boxes

Double click on the "OSC 127.0.0.1" and set INPUT to port 7700 and the Output Ports to 9000 

Press OK

select the PROFILE tab
select the green button
Give it a Manufacturer name, and Model Name  and then set the TYPE to OSC.

Click on INPUT MAPPING tab at the top
You'll see 4 buttons along the right side of the Input Profile Editor box.  Click on the bottom one.
A box will pop up, click ok
You'll now be in the input profile window.  Its going to listen to your OBS

Goto OBS and run your macro
Observe the QLC window, you should see something like this:


So now QLC received an Open Sound Control call from Advanced Scene Switcher in OBS!

So go to the QLC virtual console and create (or open up an existing) button that you want to have QLC trigger when this macro is run.

In my example I've opened up a basic button



Click on "CHOOSE"

You should see something like this:


Select the button, then click ok

This will be the result



Click on OK and run your QLC Virtual console
Now run your macro

You should see your button toggle on then off, each time you run the macro in OBS.


I'll do up a tutorial soon to show you how to control an audio mixer via OBS and OSC which is far more useful, come back soon.