On-Screen Tally Light for ProPresenter using software

I wrote a new piece of software recently that I’m really excited about. It’s called ProTally and it is designed to display video tally markers directly on the screen.


What’s tally? In broadcast setups, it is often helpful to be able to tell camera operators, computer graphics workers, etc. when their shot is being used on-air or visible on screens. Most broadcast equipment comes with some sort of tally light that, when connected to the right system, lights up to let the operator know.

With today’s broadcast equipment, a lot of this tally information can be communicated directly over the network, in real time using a variety of protocols. One particular protocol is TSL UMD, from Television Systems Limited for Under Monitor Displays. It is supported by a wide variety of broadcast industry equipment and allows the devices to know the tally state of one another.

In church environments where we use computer software like ProPresenter to send CG content to a video switcher, it can be very helpful to have a tally light that the user can see so they don’t accidentally change a graphic while it is live or on the screen. While there are a variety of external tally lights available for this purpose, I wanted to design something that would allow for a green (in preview) or red (in program/on-air) box directly on the screen that the user can easily see while operating the software, without having to purchase additional hardware.

For this project, I used Node JS and the Electron libraries, along with an existing Node JS module that acts as a TSL 3.1 Protocol server. I was able to whip up a demo in just a few short hours. Then it was just a matter of finessing and adding features.

Using ProTally, you can monitor up to 4 Tally Addresses using TSL UMD 3.1 and keep track of their Preview, Program, and Preview+Program states. You can even customize the colors as needed! The boxes can be resized and moved around on the screen and those positions will be saved and recalled the next time the software launches.

Screen Shot 2018-07-11 at 10.31.00 PM

Screen Shot 2018-07-11 at 10.32.26 PM

I decided to add options to allow the user to choose whether they wanted a filled-in box or a transparent box with a color border. It also reads the label data and stores that as it comes in, to give names to the tally addresses. And, because we use two Carbonite switchers at my church, I also wrote in an object array that uses the TSL UMD protocol implementation described by Ross here: http://help.rossvideo.com/carbonite-device/Topics/Devices/UMD/TSL.html

Screen Shot 2018-07-11 at 10.31.31 PM
The software stores the label names of the devices as they are read in the tally data over time, so as the software runs longer, this drop down list becomes mnemonicly helpful.

Due to some limitations of the Electron framework, I had to make the windows appear “always on top” of other windows, to ensure they would be visible while clicking around in ProPresenter (or ProVideoServer or whatever software being used). This can be a little annoying if you’re using the computer for another task and don’t want to see the tally boxes, so to help with that, I added a “Hide All Boxes” option that can be used rather than quitting the software.

Screen Shot 2018-07-11 at 10.30.45 PM

Here is ProTally in action:


Screen Shot 2018-07-11 at 10.35.13 PM
This is a transparent window with a border sitting on the output window of ProPresenter.



Screen Shot 2018-07-11 at 10.33.51 PM
This is a filled-in box.


This solves a problem for a lot of people who want on-screen tally for ProPresenter, ProVideoServer, or whatever software they may be using. You can even use it to monitor general inputs like cameras, etc. Just assign the tally address, position the box, and you’re set!

I will have this available in my GitHub repository soon. Feel free to check it out and if you use it, let me know how you like it! I plan to add more features to it as I have time.

Elgato Stream Deck as Production Controller

A few months ago, I picked up this nifty device called a Stream Deck made by Elgato Gaming. It’s a 15-button USB keyboard with LCD buttons. It’s primarily marketed towards gamers who live stream so they can have quick access to commands and functions as they stream. The programmer in me couldn’t resist trying it out to help us with our production setup.

The Stream Deck sells for about $140.

Using the base software provided, I was able to fairly quickly implement a workflow to allow volunteers to have easy access to buttons that then fire commands on our Ross Dashboard Production Control ecosystem. If you’ve not used Dashboard before, you can read about how we use it at my church here. It’s fairly easy to set up a custom panel in Dashboard that runs an HTTP web server at a specific port, which in turns allow you to “click” a button on the panel by calling that button’s trigger ID remotely via a specific URL.

Using the “URL” method provided in the base software, we are able to make web calls to the Dashboard custom panels to fire the commands. All the logic/code remains in Dashboard, and this just becomes a method of executing those commands remotely via an HTTP request.

Screen Shot 2018-05-01 at 8.16.41 PM
Here is a screenshot of the base software provided by Elgato. It’s very functional as is.

We used the base software for a few months without issue, however quickly realized the limitation of not being able to have bi-directional communication between our Dashboard Production Control and the individual Stream Decks. For example, several of our commands act as “toggles”, meaning we can have a few different state options that represent the current status of a device. If I only had one person making changes or operating the system, it wouldn’t be a huge issue. That person would hopefully remember what button they pressed last. However, when there are a lot of moving parts and multiple people controlling systems, the ability to update status on all devices becomes very helpful.

Enter NodeJS. People smarter than me took the time to write a base NodeJS library to control the Stream Deck. I hadn’t written in NodeJS before, but being a programmer, I was ready to learn something new. I downloaded and installed all the necessary libraries, IDE, etc. and quickly whipped up some code using the base library to control our stream decks. In just a few hours, I had something operational and started running it from the command line. I then spent a couple of weeks refining it and now we have a fully functional, self contained app that can run on Mac, Windows or Linux. It’s packaged using the Electron libraries made freely available with the Node platform.

This was the quick icon I whipped up for the software.

My controller software uses a base JSON file which defines the button structure of the stream deck. This makes it very flexible and expandable as our needs grow as I can just modify the JSON file to change the button structure.

Screen Shot 2018-05-01 at 8.25.25 PM
Here’s an example screenshot of one of my button files, written in JavaScript Object Notation. This allows me to add or remove buttons very easily and also programmatically.

The software then parses that JSON and builds the buttons on the Stream Deck in real time. If a button has a trigger action assigned, the command is sent to the corresponding device. I’ve written support for several protocols, including the Dashboard Web Call, RossTalk (good for sending messages to your Ross equipment), OSC, VideoHub routing, and more. You can even do internal stuff like jumping from one button page to another, changing button images during actions, etc. Each button can support an unlimited number of button actions, which I called triggers.

Screen Shot 2018-05-01 at 8.17.40 PM
The app runs completely in the tray with a simple context menu.

It also supports defining a set of devices, so if there’s a device you want to send messages to often, you can define the device in a separate file along with its host, port, type, etc. and then only refer to that device in the button structure. That way, if any of those related variables change,  you only have to change it in one place.

The software also runs a basic TCP listener server on a specific port, and this is where the bi-directional communication comes into play. Anytime a command is run on the master Dashboard Custom Panel Production Control, it relays a message to the remote Stream Deck via the TCP listener and updates the state of the button.

The settings menu allows you to choose the button/device files you want to use as well as whether the TCP listener service and notifications are turned on.
Screen Shot 2018-05-01 at 8.18.13 PM
A sample notification that can appear when a button is pressed. You can determine which triggers sent notifications.

This means that we can run commands from any originating location, whether it is the web-based production control (that I’m still developing), one of the remote Dashboard panels that connects to Production Control, one of the Stream Decks (we currently have 2 of them, one in each control room), or even the Master Control panel and every device will receive an updated status.

I also added a “Virtual Deck” option, which allows you to operate the software with or without having a physical Stream Deck attached. You can also choose to have the Virtual Deck operate independently of your physical Stream Deck, so it’s like having two decks in one!

Screen Shot 2018-05-01 at 8.17.26 PM
Here is a screenshot of the Virtual Deck in action.
Screen Shot 2018-05-01 at 8.18.26 PM
Here is what some buttons that have been toggled look like on the Virtual Deck. It’s very clear to see the current state of those buttons!

I am making this software freely available to anyone who can benefit from it. My hope is that the local church can make use of this to allow their volunteers to more easily operate tech equipment during services.

It’s currently up on GitHub here: https://github.com/josephdadams/StreamDeckProductionController

I’ve only built a Mac binary, but you can easily package it for Windows or Linux if needed.

I am working on an Editor function right now that will allow you to add/edit buttons without having to write them in JSON, but until then, you’ll have to make do with that option. Here’s a good tutorial on learning JSON if you need help: https://www.codecademy.com/courses/javascript-beginner-en-xTAfX/0/1

If I can help you out along the way, don’t hesitate to reach out!