PowerShell Automation of FFMPEG

Want to create thumbnails from video files or convert from .ts to .mp4? FFMPEG can do it but the command line can be a bit tricky to figure out. There is a nice .Net library for automating ffmpeg that can be used in PowerShell. See NrecoSite

Example PowerShell:

# Download https://www.nrecosite.com/video_converter_net.aspx
# copy ffmpeg.exe to C:\Windows\SysWOW64\WindowsPowerShell\v1.0\
# Documentation - https://www.nrecosite.com/doc/NReco.VideoConverter/
$thumbnail = "D:\Capture\Conference_20170722_090251.png"
$video = "D:\Capture\Conference_20170722_090251.ts"

add-type -path 'C:\Users\imorrish\Documents\WindowsPowerShell\NReco.VideoConverter.dll'
$ffMpeg = new-object NReco.VideoConverter.FFMpegConverter
#Create thumnail
$ffMpeg.GetVideoThumbnail($video, $thumbnail,1653); #seconds from start
#Convert to MP4
$ffMpeg.ConvertMedia($video, "d:\capture\Conference_20170722_090251.mp4", [NReco.VideoConverter.Format]::mp4)

Snapshot ATEM Mixer settings with PowerShell

This is a work in progress and will be added to ISE as a standard menu to provide selective backup/restore of ATEM settings like the BMD Software Panel but using JSON format rather than XML.

Example snippet of code for the ME properties:

add-type -path ‘C:\Users\imorrish\Documents\WindowsPowerShell\SwitcherLib.dll’
$atem = New-Object SwitcherLib.Switcher(“192.168.1.8”)
$atem.Connect()
$ME = $atem.GetMEs()
$me1SnapShot = $me[0] |select-object -property * -ExcludeProperty “me” | ConvertTo-Json

Which produces the following:

{
    “Program”: 1,
    “Preview”: 1,
    “TransitionStyle”: “Mix”,
    “NextTransitionStyle”: “Mix”,
    “InTransition”: false,
    “TransitionFramesRemaining”: 25,
    “TransitionPosition”: 0,
    “FadeToBlackRate”: 25,
    “InFadeToBlack”: false,
    “FadeToBlackInTransition”: null,
    “FadeToBlackFullyBlack”: false,
    “PreviewLive”: false,
    “PreviewTransition”: false,
    “TransitionSelection”: 1,
    “MixRate”: 25,
    “WipeBorderSize”: 0,
    “WipeBorder”: 2001,
    “WipeReverse”: 0,
    “WipeFlipFlop”: 0,
    “WipeSoftness”: 0,
    “WipeSymmetry”: 0.5,
    “WipeHorizontalOffset”: 0.5,
    “WipeVerticalOffset”: 0.5,
    “TransitionWipePattern”: “DiamondIris”,
    “DVERate”: 25,
    “DVELogoRate”: 25,
    “DVEeReverse”: 0,
    “DVEFlipFlop”: 0,
    “DVETransitionStyle”: “PushRight”,
    “DVEInputFill”: 3010,
    “DVEInputCut”: 3011,
    “DVEEnableKey”: 1,
    “DVEClip”: 0.5,
    “DVEGain”: 0.7,
    “DIPRate”: 25,
    “DIPInput”: 2001,
    “index”: 1
}

I still have to sort out some inconsistencies with properties that should be Boolean and making the internal class private.

ATEM SuperSource support in PowerShell

I have not been able to test this except for a brief confirmation that the object is returned. I ran out of time while I had access to a 2 M/E so have implemented all the SuperSource methods and properties as per the API.

I should be able to test this and fix any issues next weekend.
Update: GetSuperSourceBox causes a memory error, requires some more work…

Update: It is now working 🙂

#Get the SuperSource (only one - at the moment)
$Supersources = $atem.GetSuperSource()
$Supersource[0] #this will show all properties and methods of SuperShource

$Supersources[0].InputCut = 3011 # MediaPlayer1 Cut
$Supersources[0].InputFill = 3010 #MediaPlayer1 Fill

#Get the SuperSource boxes
$SSBox = $Atem.GetSuperSourceBox()
$SSBox[0] #this will show all methods and properties of the first box

$SSBox[0].InputSource=2
$SSBox[1].InputSource=3
$SSBox[0].Enabled=1
$SSBox[1].Enabled=1 

This dll is now the current version of SwitcherLib.dll and is available from the downloads page.
I’m looking forward to creating some demos that show how to move the SuperSource boxes around while they are live

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

Description of the chroma key values for Hue, Gain, Y Suppress, Lift and Narrow from the ATEM manual:

Chroma Key parameters

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 eventBitChange -ErrorAction SilentlyContinue #incase we are re-running the script
$ArduinoEvent = Register-ObjectEvent -InputObject $session -EventName DigitalStateReceived -SourceIdentifier eventBitChange -Action {inputevent($eventArgs)}