Adjust ATEM USK Chroma Key settings with Midi Device

I found it a bit frustrating trying to set up the chroma key using the Blackmagic Design ATEM Software panel. Trying to change the values using the mouse while looking at the preview monitor was not very efficient.

So I used a MIDI device that has some rotary encoders and PowerShell to make the adjustments. See the video below for a demo

Using this almost made it fun playing with the options.

The Behringer CMD DC-1 seems to be on special at https://www.bhphotovideo.com/c/search?Ntt=cmd+dc-1

This was automated using Windows PowerShell but could have just as easily been done with JustMacros.

You can find example code for this here… https://gist.github.com/imorrish/5614d4369ca111f7096aff31d27e4d98

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()
$stream.Write($bytes,0,$bytes.Length)
$stream.close()

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

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

Blackmagic Design TVS HD Flying Key animations

The Blackmagic Design Television Studio HD has added flying key features to the upstream key, something the original TVS did not support.

I created a demo video showing this feature in action using the software panel to control it.

A more seamless experience can achieved using PowerShell to automate the “key fly to” commands.

Example script (assumes you have already used SwitcherLib to connect to the TVS HD.

$key1.Type="Chroma"
$mp1.MediaStill = 2
$key1.InputFill=3010
$key1.InputCut=3011
$key1.Fly = 1
$key1.OnAir = 1
$key1.FlyRunToKeyFrame = [SwitcherLib.FlyKeyFrameDestination]::FlyKeyFrameFull
start-sleep 1
$key1.FlyRunToKeyFrame="FlyKeyFrameB"
start-sleep 1
$key1.FlyRunToKeyFrame="FlyKeyFrameFull"
start-sleep 1
$key1.FlyRunToKeyFrame="FlyKeyFrameA"
start-sleep 1
$key1.OnAir = 0
$key1.Fly = 0

You can see from the video below how well the animation flows.

Using Arduino as an input trigger to PowerShell

I have previously blogged about using the Arduino as an I/O device to set the output pins to drive camera tally lights.

PowerShell can also read the input status of pins on the Arduino using the Solid.Arduino .Net library.

This is an example of using the Arduino to detect the monitor switch on camera RCP units so that you can switch the signal to a scope or monitor.

I have used this for both Sony RCP-1500 and Panasonic AK-HRP200 RCP’s which provide dry contact closures on monitor selection.

The code is very simple and sets up an event to wait for input pin status changes on the Arduino…


add-type -path '.\Documents\WindowsPowerShell\Solid.Arduino.dll'
$connection = New-Object Solid.Arduino.SerialConnection("COM4",[Solid.Arduino.SerialBaudRate]::Bps_57600)
$session = New-Object Solid.Arduino.ArduinoSession($connection, 2000)
$session.SetDigitalPinMode(4,[Solid.Arduino.Firmata.PinMode]::DigitalInput)
#
# Define the function that is called when a digitial pin event happens
#
function inputevent($event){
    #Write-Host "Something happened on port $($event.value.port) Type $($event.value.pins)"
    if($event.value.pins -band 4) #using binary AND incase multiple inputs are activated
    {
        # put code here to switch ATEM Aux or VideoHub routing
        Write-host "Cam 1 preview selected"
    }
}
#
# set up the event to montor digital pin state change
#
$session.SetDigitalReportMode(0,$true) #enable events for pins on port 0
Unregister-Event -SourceIdentifier eventBitChange #incase we are re-running the script
$ArduinoEvent = Register-ObjectEvent -InputObject $session -EventName DigitalStateReceived -SourceIdentifier eventBitChange -Action {inputevent($eventArgs)}

Blackmagic Decklink Device Information from PowerShell Script

I have started working on a providing control of Blackmagic Design Decklink cards from Windows PowerShell scripts.

Just at the initial stage of being able to read the configuration of cards connected to the PC.

Updated: Can now set some card options also. Use $Devices | Get-Member
To find the methods and properties. $devices[0].
Will give you more options for the first device detected.

Example script:

$VideoConnections = @{1 = "SDI"; 2 = "HDMI"; 4 = "Optical SDI"; 8 = "Component"; 16 = "Composit"; 32 = "S-Video" }
$AudioConnections = @{1 = "Embedded" ; 2 = "AESEBU" ; 4 = "Analog"; 8 = "Analog XLR"; 16 = "Analog RCA"; 32 = "Microsophone"; 64 = "Headphones"}
$VideoIOSupport = @{1 = "Capture"; 2 = "Playback"}
add-type -path '\Documents\WindowsPowerShell\decklink.dll'
$cards = new-object VISE_DeckLink.DeckLink
$Devices = $cards.DeckLinkDevices()
write-host "Number of devices detected: $($Devices.Count)"
$devices
foreach ($device in $Devices){
    write-host "$($device.DisplayName)" -ForegroundColor red -BackgroundColor white
    Write-host " IO Support:"
    $VideoIOSupport.Keys | where { $_ -band $device.VideoIOSupport } | foreach { $VideoIOSupport.Get_Item($_)} 
    Write-host " Input Video Connections:"
    $VideoConnections.Keys | where { $_ -band $device.VideoInputConnections } | foreach { $VideoConnections.Get_Item($_)}
    Write-host " Input Audio Connections:"
    $AudioConnections.Keys | where { $_ -band $device.AudioInputConnections } | foreach { $AudioConnections.Get_Item($_)}
    Write-host " Output Video Connections:"
    $VideoConnections.Keys | where { $_ -band $device.VideoOutputConnections } | foreach { $VideoConnections.Get_Item($_)}
    Write-host " Output Audio Connections:"
    $AudioConnections.Keys | where { $_ -band $device.AudioOutputConnections } | foreach { $AudioConnections.Get_Item($_)}

Write-host ""
}

Here is an example the output.

decklinkconfig

Download the decklink.dll file from here https://1drv.ms/u/s!ApGpqMMpRLhijeR1-4SVgqdytAUhmg

Use a Dark PowerShell ISE Theme in Video Production Environment

I use the PowerShell ISE in a lot of dimly lit places and it can be a bit disconcerting to have a very bright computer screen to look at when you are in a dark room.

The default ISE shell supports themes. You can chance to a dark theme from

Which will change the UI to this:

You can also import themes from the Manage Themes dialog box. Here is a nice one I found on GitHub https://github.com/perplexityjeff/PowerShell-ISE-Solarized-Theme

Control Hyperdeck via ATEM with PowerShell script

SwitcherLib now supports Blackmagic Hyperdeck control (version 2.9).

Everything but media file details has been implemented.

Full list of features:
hyperdeckfeatures

Example PowerShell:

add-type -path ‘C:\Users\ian\Documents\WindowsPowerShell\SwitcherLib.dll
$Global:atem = New-Object SwitcherLib.Switcher(“192.168.0.240”)
$atem.Connect()
$HyperDeck=$atem.GetHyperdecks()
$HyperDeck.Capacity
$HyperDeck[0].NetworkAddress
$HyperDeck[0].RemoteAccessEnabled
$HyperDeck[0].Play()
start-sleep 5
$HyperDeck[0].stop()
$HyperDeck[0].CurrentClipTime
Start-Sleep 5
$HyperDeck[0].CurrentClipTime = “00:02:00:25”
start-sleep 5
$HyperDeck[0].Jog(500) #jump 5 seconds (50p)
start-sleep 5
$HyperDeck[0].CurrentClip=1
$HyperDeck[0].Play()
start-sleep 5
$HyperDeck[0].stop()
$HyperDeck[0].CurrentClipTime
$HyperDeck[0].CurrentTimelineTime #time from start of clip 0