Automating Characterworks from PowerShell

I saw a question on the BMD forum asking about the possibility of triggering an action in Characterworks. A quick check of the Characterworks online help showed that the CW Remote Control Server listens to requests on port 5201 and accepts HTTP POST requests containing JSON-encoded commands.

It would be easy to define a keyboard shortcut or X-Keys button that initiated the Characterworks action and switched the input, or enabled a key, on the Blackmagic ATEM using a PowerShell script.

Below is a simple example PowerShell script showing how to send a command to Characterworks:

$url = "http://localhost:5201/"
$command = '{ "action" : "play_motions", "motions" : [ "Motion 1" ], "channel" : "live1" }'

$bytes = [System.Text.Encoding]::ASCII.GetBytes($command)
$web = [System.Net.WebRequest]::Create($url)
$web.Method = "POST"
$web.ContentLength = $bytes.Length
$web.ContentType = "application/x-www-form-urlencoded"
$stream = $web.GetRequestStream()

$reader = New-Object System.IO.Streamreader -ArgumentList $web.GetResponse().GetResponseStream()

It would be easy to wrap this in a function to take the motions and channel values as parameters and return the response.

Blackmagic Television Studio HD DVE features

I’m loving having DVE capability in the new ATEM TVS HD. It is not as rich as the ATEM 1 and 2 M/E’s but is a big improvement over the old TVS.

Although only a 2D DVE, it provides most of the Key and transition features of the bigger ATEM’s. By far the most useful feature I think is Picture-In-Picture and I was especially surprised to see the TVS HD support flying key.

I have been adding more DVE automation functionality to my PowerShell ATEM Switcher library and will have an update version that supports all TVS HD feature soon (although it will require the 7.0 firmware in all other ATEM’s you might want to automate from PowerShell). A beta 6.9 version of the switcherlib.dll is available from the downloads folder.

Some tips below for people who are new to the DVE capabilities found in the TVS HD.

The position values are defined from the center of the window. Maximum to have the center point hard left or right values are

x:-16.00 to 16.00

y:-9.00 to 9.00

The size of the window

X:0.00 to 1.00

So, if you wanted a ¼ of full screen size (1/2 width and height), the size would be 0.5 (aspect ratio is maintained by default)

And for top left, x= -8 & y= 4.5

In PowerShell I just define these values in an array.


= @(-8,4.5,.5,.5)

= @(8,4.5,.5,.5)

= @(8,-4.5,.5,.5)

= @(-8,-4.5,.5,.5)

Then I have a function you pass the array to




$script:usk1.FlyPositionX = $window[0]

$script:usk1.FlyPositionY = $window[1]

$script:usk1.FlySizeX = $window[2]

$script:usk1.FlySizeY = $window[3]


So to set the IP to top left

setPIPWindow $topLeft

You can also set the border to be a combination of pixels that are inside or outside the DVE window size

The Key Frame option lets you transition the PIP window to a new location.

Unfortunately, you can’t load position and size values directly into the A and B positions. You can only set the current values to one of these 2 so you would have to have the key off air to load up initial values. Once the key is on air you are limited to only the 2 presets, full screen, off screen in one of the 8 directions.

In PowerShell you can save the current position and size with



You can initiate the Fly with




Where the value after :: (which will be shown using intellisense) can be:

  • FlyKeyFrameA
  • FlyKeyFrameB
  • FlyKeyFrameFull
  • FlyKeyFrameInfinityTopLeft
  • FlyKeyFrameInfinityBottomRight
  • FlyKeyFrameInfinityCenter
  • FlyKeyFrameInfinityCenterOfKey
Squeeze the current program item to reveal the preview item.

The DVE transition can be set with PowerShell

$me1.TransitionStyle =

$me1.DVETransitionStyle =

Where the values after the :: can be…

  • SqueezeTopLeft
  • SqueesTop
  • SqueezeTopRight
  • Squeez bottomRight
  • PushTopLeft
  • PushBottomRight

Note: you can’t enable the DVE transition style if the USK key type is set to DVE and is on air.

There is also an option in the DVE transition to have a source that will fly across the screen as part of the transition to preview (Graphic Wipe). This should be a source that has the image you want in the center and transparent background.

The width should be less than 25% of the video standard width with the majority of the image have an alpha transparency (or black background).

For 720p the centre 320 horizontal pixels will be used for vertical strip

I’m yet to implement this in PowerShell.

Xkeys XKR-32 for Blackmagic ATEM TVS operation

I have posted some sample Windows PowerShell scripts for controlling the Blackmagic Design ATEM Television Studio (TVS) on GitHub.

The main thing I did with this sample is define the actions for each key in a JSON file. You can store any combination of PowerShell commands for a button or call a function.

The JSON file is loaded into the script and a hash table is created which holds just the key ID and string to evaluate as code.

function LoadXkeys(){
$xkFile = ConvertFrom-Json (get-content "documents\WindowsPowerShell\xkr32.json" -raw)
$Global:xkCommands = @{}
foreach($key in $xkFile.keys){

This means you can edit the JSON file and just re-run the LoadXKeys function to make changes on the fly.

I’ll probably change the format of the JSON file but for now it looks like this:

“keys”: [
“Type”: “Script”,
“KeyID”: 0,
“Command”: ” “,
“Script”: “$ActiveME.Program=1”,
“Caption”: “Prog 1”,
“Description”: “CUT”
“Type”: “Script”,
“KeyID”: 1,
“Command”: ” “,
“Script”: “if($Global:KeypadMode -eq \”\”){$ActiveME.Preview=1} else {keypad 1}”,
“Caption”: “Prev 1”,
“Description”: “ME1 Auto Transition”

You can find the full code here

The bottom row of buttons function as preview selection by default but if you select Macro or Color then the bottom row allows selecting a macro from 1-10 or one of 10 predefined colors (ROYGBIV, White, Grey, Black in that order).

If MP1 or MP2 is already on preview, selecting it again then lets you pick the slot from the media pool to load into the currently previewed media player.

I did get a few ideas from the new TVS HD panel so might make an expanded version of this with only preview selection and making 1-20 for data input.

Picture in picture (pnp) with Blackmagic Television Studio and PowerPoint.

The Blackmagic TVS doesn’t have a picture in picture function like the 1 or 2 M/E units. If you want a PowerPoint (or other windowed application (even YouTube video would work) then you can use the DSK with mask to

Setup your secondary monitor to match the resolution of your ATEM

In PowerPoint, select the “Slide Show” tab and Set Up Slide Show icon.

Change the Show Type to “Browsed by an individual (window)” as shown above. When you start the presentation (press ) you can resize the player and use the keyboard arrows or space bar to change slides.

Use the Down Stream Keyer in the ATEM to specify the input source for the key as your computer screen input and set the mask coordinates to block out he unwanted window border.

Just be careful not to move the mouse pointer over the PowerPoint presentation.

Using a Raspberry Pi as an operations clock

I know this is not a “World Clock” but for general event coordination, even across multiple venues, is a useful tool. We use it for multi-campus coordination of live linking.

Rather than relying on iPads and people phones (which always seem to go flat) to display the time, we can use a Raspberry Pi running a browser in Kiosk mode to generate an accurate clock and feed this into our video hub for distribution.

Overview of setting up your Raspberry Pi

There are many resources on the Internet for performing these tasks so I won’t go into the detail here but the basic steps are:

Install noob onto SD card as per instructions
I did do the standard update to ensure the latest stuff was installed.
The default seems to be to boot into the graphical UI.

I changed the config.txt to force the HDMI mode to match my ATEM video standard of 720p 50Hz

From the desktop, run a terminal session and from that run leafpad.
Press down arrow to get the path box to display and type


Add the following to the blank file and then save.

@chromium-browser –disable-session-crashed-bubble –disable-infobars  –kiosk
@xset s off
@xset -dpms
@xset noblank


You can experiment with the display options to change font and color, then update the url for Chromium.

Instant Replay, Time Shift on the cheap

A poor mans Time Shift, delayed live stream or instant video replay solution.

Just a science experiment at this but seems to be reliable.

Using a combination of the following:

  • Blackmagic TVS or H.264 hardware encoder
  • MXPTiny to capture to Transport Stream file on SSD
  • VLC to simultaneously play back recording file
  • DVI Extender to produce SDI output
  • PowerShell to remote control VLC
  • X-Keys to provide shortcuts

The delay can be anything from 1 second to many hours (dependent on disk space, maximum file size and stability of Windows (assuming Windows Update has been disabled).
Video showing a very boring test involving a digital clock.

My X-keys XK-60 layout includes a shift function to repurpose the numeric keypad to control VLC.


X-keys editor to create JSON file

I have started working on a JSON schema to support the X-keys options that can be performed in PowerShell for each button. Originally I was thinking of doing this with an XML file, which would have worked fine, but the purpose of exercise is also to learn some new technology.

The JSON file format looks like this:

"keys": [
"Type": "Script",
"KeyID": 0,
"Command": " ",
"Script": " $me[0].Program=1",
"Caption": "Prog 1",
"Description": " Set Program bus to input 1"
"Type": "Script",
"KeyID": 1,
"Command": " ",
"Script": " $me[0].Preview=2",
"Caption": "Preview 2",
"Description": "Set Preview bus to input 2"

And the tool that saves you from having to create this in Notepad can be downloaded from here

It is very simple and just a temporary solution until my full WPF based host is ready (long term project so I’m not holding my breath, neither should you).


The JSON file can be loaded in PowerShell and converted to a Hashtable with the following code…

$xk60File = ConvertFrom-Json (get-content "C:\Users\imorrish\OneDrive\PowerShell\V-ISE\test.json" -raw)
$xk60Commands = @{}
foreach($key in $xk60File.keys){
# this is the function called by the KeyDown event handler
function HandleXkey($key) {
invoke-expression  $xk60Commands.Get_Item($key)

Note: if you want to store a file path or anything with a \ character, you have to double it up.
If you want to learn more about JSON, check out this article