Skip to content

Instantly share code, notes, and snippets.

@imorrish
Created March 1, 2019 23:19
Show Gist options
  • Save imorrish/518c102736d3aa924074a3958cda6af8 to your computer and use it in GitHub Desktop.
Save imorrish/518c102736d3aa924074a3958cda6af8 to your computer and use it in GitHub Desktop.
# Script created by Ian Morrish
# See https://ianmorrish.wordpress.com/2019/03/02/atem-wireless-multiviewer-with-touch-switching/
# Run Newtek studio monitor first, select input and set to full screen.
# this script requires my switcherlib.dll which you can get from the site above
# after starting this script, <ALT><Tab> to see the multiview live video feed (I will automate this soon)
#Show-Process "overlay"
# Connect to ATEM
function ConnectToATEM()
{
Try{
$ATEMipAddress = (Get-ItemProperty -path 'HKCU:\Software\Blackmagic Design\ATEM Software Control').ipAddress
$DocumentsPath = [Environment]::GetFolderPath("MyDocuments") + '\windowspowershell\SwitcherLib.dll'
add-type -path $DocumentsPath
$Global:atem = New-Object SwitcherLib.Switcher($ATEMipAddress)
$atem.Connect()
}
catch{
write-host "Can't connect to ATEM on $($ATEMipAddrss)."
Write-Host "ATEM controle software must be installed and have connected to switcher at least one time"
Stop
}
}
function CreateATEMObjects()
{
$me=$atem.GetMEs()
$Global:me1=$me[0]
$Global:me2=$me[1]
$Global:activeME = $me1
if($me.count -gt 1){
$Global:activeME = $me[1]
}
$MediaPlayers = $atem.GetMediaPlayers()
$Global:MP1=$MediaPlayers[0]
$Global:MP2=$MediaPlayers[1]
$Global:Auxs=$atem.GetAuxInputs()
$Global:aux1 = $auxs[0]
$Global:USK = $ATEM.GetKeys()
$Global:activeUSK = $USK[0]
$Global:DSK = $ATEM.GetDSKs()
$Global:activeDSK = $DSK[0]
$global:mv=$atem.GetMultiViews()
}
ConnectToATEM
CreateATEMObjects
#Create hash of multiview window sources
$mvSource=@{}
$i=2
for($i; $i -lt 10; $i++){
$mvSource.Add($i, $mv[0].GetWindowInput($i))
}
#ATEM MultiView click overlay
$inputXML = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window"
WindowStyle = "None" WindowState="Maximized"
ResizeMode = "NoResize" Title = "overlay" AllowsTransparency = "True" Background = "Transparent" Opacity = "1" Topmost = "True">
<Grid x:Name = "Grid" Background = "Transparent" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="80" />
</Grid.RowDefinitions>
<Button Name="Cell1" Grid.Row="0" Grid.Column="0" Opacity=".8"/>
<Button Name="Cell2" Grid.Row="0" Grid.Column="1" Opacity=".8"/>
<Button Name="Cell3" Grid.Row="0" Grid.Column="2" Opacity=".8"/>
<Button Name="Cell4" Grid.Row="0" Grid.Column="3" Opacity=".8"/>
<Button Name="Cell5" Grid.Row="1" Grid.Column="0" Opacity="0.01"/>
<Button Name="Cell6" Grid.Row="1" Grid.Column="1" Opacity="0.01" />
<Button Name="Cell7" Grid.Row="1" Grid.Column="2" Opacity="0.01"/>
<Button Name="Cell8" Grid.Row="1" Grid.Column="3" Opacity="0.01"/>
<Button Name="Cell9" Grid.Row="2" Grid.Column="0" Opacity="0.01"/>
<Button Name="Cell10" Grid.Row="2" Grid.Column="1" Opacity="0.01"/>
<Button Name="Cell11" Grid.Row="2" Grid.Column="2" Opacity="0.01"/>
<Button Name="Cell12" Grid.Row="2" Grid.Column="3" Opacity="0.01"/>
<Button Name="Cell13" Grid.Row="3" Grid.Column="0" Opacity="0.01"/>
<Button Name="Cell14" Grid.Row="3" Grid.Column="1" Opacity="0.01"/>
<Button Name="Cell15" Grid.Row="3" Grid.Column="2" Opacity="0.01"/>
<Button Name="Cell16" Grid.Row="3" Grid.Column="3" Opacity="0.01"/>
<Button Name="Cell17" Grid.Row="4" Grid.Column="0" Opacity="0.01"/>
<Button Name="Cell18" Grid.Row="4" Grid.Column="1" Opacity="0.01"/>
<Button Name="Cell19" Grid.Row="4" Grid.Column="2" Opacity="0.01"/>
<Button Name="Cell20" Grid.Row="4" Grid.Column="3" Opacity="0.01"/>
</Grid>
</Window>
"@
$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML
#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{$Window=[Windows.Markup.XamlReader]::Load( $reader )}
catch [System.Management.Automation.MethodInvocationException] {
Write-Warning "We ran into a problem with the XAML code. Check the syntax for this control..."
write-host $error[0].Exception.Message -ForegroundColor Red
if ($error[0].Exception.Message -like "*button*"){
write-warning "Ensure your &lt;button in the `$inputXML does NOT have a Click=ButtonClick property. PS can't handle this`n`n`n`n"}
}
catch{#if it broke some other way :D
Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed."
}
# Create PowerShell object for each WPF button
$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name "WPF$($_.Name)" -Value $Window.FindName($_.Name)}
# Map multiview window click to actual ATEM input ID
function buttonclicked($btnNAme){
write-host $btnNAme
switch($btnNAme){
0{$Script:Window.close();break
}
{1..8 -contains $_}{
#$me1.preview=$_
$me1.preview=$mvSource[$btnNAme+1]
}
}
}
#Create event handlers (tried doing this in a cleaver foreach but it just wouldn't work)
$WPFCell4.add_click({buttonclicked 0})
$WPFCell13.add_click({buttonclicked 1})
$WPFCell14.add_click({buttonclicked 2})
$WPFCell15.add_click({buttonclicked 3})
$WPFCell16.add_click({buttonclicked 4})
$WPFCell17.add_click({buttonclicked 5})
$WPFCell18.add_click({buttonclicked 6})
$WPFCell19.add_click({buttonclicked 7})
$WPFCell20.add_click({buttonclicked 8})
$WPFCell3.add_click({$me1.cut()})
# Turn on WPF overlay display
$Window.ShowDialog() | out-null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment