Rank: Member
Groups: Registered
Joined: 3/10/2021(UTC) Posts: 11 Location: Vicinity of Hamburg/Germany Thanks: 2 times
|
Even your post and script is a long time ago, @Speegs, it was a good base for me. Here I will provide an improved version to the vMix community. Put the name of the currently playing video file list into a Title Input and shows this title as an overlayFeatures:- at script start the user is prompted for Title Input Number, Title text field, Video List Input and Overlay number with predefined values.
- automatically removes preceeding title text like "List - " as well as file extension.
- shows overlay after 1.5 sec after video starts playing and hides overlay 2.5 sec before video ends (times can be changed, see section User Definable Variables).
- overlay to be shown requires the Video List Input is active in vMix program window.
- while the specified overlay is displayed, the vMix operator is free to set another Title Input into that overlay. If the overlay is switched off by the vMix operator, the specifed Title input will be re-displayed automatically.
- if a playing video stopped exactly at it's end and no further video is played, the vMix operator may display any Title Input in the specified overlay without interference by this script.
- runs in Microsoft PowerShell on the vMix computer or an remote computer in the same network (see section "User Definable Variables").
- successfully tested with vMix 4K v25.0.0.34 under Windows 10 Pro v1909, English
- by default, this script can be used "as is" on the local vMix computer
Personal note: even though I had apx 30 years experience in professional software development beginning in early 1980, I never dealt (now I know why ;-) ) with PowerShell, VisualBasic nor XML and .NET stuff. So I need to learn a lot the last days, which took a while at my age. For PowerShell experts there might be some possible optimizations. Beside functionality, automation, I made the variable names more readable, formatted the code for better readabilty (here someone may see my Pascal background ;-) ) as well as a lot of comments. Best regards, OldHans Code:
# Original by: 30-NOV-2015 / Speegs (https://forums.vmix.com/posts/t1177-Auto-update-NOW-PLAYING-graphic-overlay)
# Last change: 29-NOV-2023 / OldHans
#
# Put the name of the currently playing video file list into a Title Input and shows this title as an overlay
#
# Features:
#
# 1. at script start the user is prompted for Title Input Number, Title text field, Video List Input and Overlay
# number with predefined values.
#
# 2. automatically removes preceeding title text like "List - " as well as file extension.
#
# 3. shows overlay after 1.5 sec after video starts playing and hides overlay 2.5 sec before video ends
# (times can be changed, see section User Definable Variables).
#
# 4. overlay to be shown requires the Video List Input is active in vMix program window.
#
# 5. while the specified overlay is displayed, the vMix operator is free to set another Title Input
# into that overlay. If the overlay is switched off by the vMix operator, the specifed Title input
# will be re-displayed automatically.
#
# 6. if a playing video stopped exactly at it's end and no further video is played, the vMix operator
# may display any Title Input in the specified overlay without interference by this script.
#
# 7. runs in Microsoft PowerShell on the vMix computer or an remote computer in the same network
# (see section "User Definable Variables").
#
# 8. successfully tested with vMix 4K v25.0.0.34 under Windows 10 Pro v1909, English
#
# 9. by default, this script can be used "as is" on the local vMix computer
#
# Notes:
#
# 1. in a batch file (.BAT) call this script using (without quotes)
#
# "PowerShell.exe -ExecutionPolicy ByPass -File ./vmix-playlist-mon.ps1"
#
# 2. if script runs in "PowerShell ISE", then launch "PowerShell ISE" using "Run As Administrator", then
# in the Console Windows execute the command "Set-ExecutionPolicy -ExecutionPolicy Bypass".
#
# 3. the desired vMix Preset should be loaded before running this Script
#
# 4. ensure that the text field of the Title Input is not linked to a Data Source
#
# Actual Problems:
#
# 1. Non ASCII characters (often used in german, french, spanisch, etc.) that are allowed in Windows filenames are not
# correctly handled from within PowerShell. This is due to the complexity of dealing with Unicode, UTF8 etc., as well
# as the character set used by PowerShell.
# Using the $TitleText.Replace(unicode, newcode) method will crash the script at least on german Umlauts.
# No generally working solution found yet.
#
#------------------------------------------------------------------------------------------------------------------
# Preset of variables that will actually be entered by the user at script start
param (
[string]$TitleInputNumber = "24",
[string]$TitleInputField = "Description.Text",
[string]$ListInputNumber = "44",
[string]$OvlNumber = "2"
)
#------------------------------------------------------------------------------------------------------------------
# Assembly für Visual Basic in die PowerShell-Umgebung laden.
# Hierdurch können Funktionen in der Visual Basic-Library aufgerufen werden, z.B [Microsoft.VisualBasic.Interaction]::InputBox
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
#------------------------------------------------------------------------------------------------------------------
# Benutzereingabe im Konsolenfenster:
# The input number for the vMix Title to change
$TitleInputNumber = [Microsoft.VisualBasic.Interaction]::InputBox("Number or Name of vMix Input to be displayed in overlay, eg: NewsHD.xaml)", "Number/Title", $TitleInputNumber)
# The name of the title field to modify, e.g. Description.Text or Ticker.Text
$TitleInputField = [Microsoft.VisualBasic.Interaction]::InputBox("Name of the text field in Input $TitleInputNumber to modify (eg: Description.Text)", "Text field to modify", $TitleInputField)
# Nummer des vMix Inputs vom Typ "List" mit den Videos
$ListInputNumber = [Microsoft.VisualBasic.Interaction]::InputBox("Numer of vMix Input of type List with videos", "List Input Nubmer", $ListInputNumber)
# Nummer des vMix Inputs vom Typ "List" mit den Videos
$OvlNumber = [Microsoft.VisualBasic.Interaction]::InputBox("Numer of vMix Overlay", "Overlay Number", $OvlNumber)
#------------------------------------------------------------------------------------------------------------------
# User Definable Variables
# URL to retrieve all data from vMix API in XML format
$xmlurl = "http://localhost:8088/API/"
# URL to set the text in the specified field of a dedicated Title Input
$UrlSetTitleText = $xmlurl + "?Function=SetText&Input=" + $TitleInputNumber + "&SelectedName=" + $TitleInputField + "&Value="
# URL to fade-in the Title Input into Overlay
$UrlSetOvlFadeIn = $xmlurl + "?Function=OverlayInput" + $OvlNumber + "In&Input=" + $TitleInputNumber
# URL to fade-out the Title Input into Overlay
$UrlSetOvlFadeOut = $xmlurl + "?Function=OverlayInput" + $OvlNumber + "Out&Input=" + $TitleInputNumber
# Overlay Control
$OvlControlEnabled = $true # set to $false to disable the overlay fade in/out feature
$OvlFadeInDelay = 1500 # 0 oder Zeit in msec zum Einblenden des Overlays nachdem das Video gestartet ist
$OvlFadeOutDelay = 2500 # 0 oder Zeit in msec zum Ausblenden des Overlays bevor das Video endet
#------------------------------------------------------------------------------------------------------------------
# Internal Variables
$TitleText = "" # current Title Text
$LastTitleText = "" # last Title Text used for comparision with the actual one
$VideoState = "" # state of video "Paused" | "Running"
$VideoDuration = 0 # video duration in msec
$VideoPosition = 0 # video position in msec
$OverlayState = $false # is overlay activated
$ActiveInput = 0 # number of active input (the input shown in "program")
$i = 0 # string index variable
$fileExtPos = 0 # position of file extension in a string
$BeAliveCount = 0 # every 60 seconds write the "be alive dot" in a new line in the PowerShell Console
#------------------------------------------------------------------------------------------------------------------
# Main Program Loop
Write-Host ""
Write-Host "Parameter Summary"
Write-Host "------------------------------------------------------------------"
Write-Host "vMix URL : " $xmlurl
Write-Host "Number of vMix Input shown in overlay: " $TitleInputNumber
Write-Host "Text field for video title : " $TitleInputField
Write-Host "Overlay Number : " $OvlNumber
Write-Host "Overlay Fade-In delay : " $OvlFadeInDelay " msec"
Write-Host "Overlay Fade-Out delay : " $OvlFadeOutDelay " msec"
Write-Host "Input Number with list of videos : " $ListInputNumber
Write-Host "------------------------------------------------------------------"
Write-Host "Press 'q' to quit"
Write-Host ""
# hide the overlay because it might be that some other input is currently displayed
(New-Object System.Net.WebClient).DownloadString("$UrlSetOvlFadeOut")
while ($true)
{
# fetch XML data from vMix Web API
[xml]$XmlData = (New-Object System.Net.WebClient).DownloadString($xmlurl)
# read XML node of the List Input by it's vMix Input Number (or name)
$XmlNode = $XmlData.SelectNodes("/vmix/inputs/input[@number='$ListInputNumber']")
# get the actual title of the vMix List Input that contains the video files. The title consists of 'Name of Input" + " - " + filename currently played.
# In case the specifed vMix List Input does not exist, $TitleText.Length = 0 - so no errors will be displayed, the script will not crash.
$TitleText = ($XmlNode | Select-Object -ExpandProperty title | Out-String)
$VideoState = ($XmlNode | Select-Object -ExpandProperty state | Out-String) # "Paused" | "Running"
$VideoDuration = ($XmlNode | Select-Object -ExpandProperty duration | Out-String) # duration in msec
$VideoPositionTemp = ($XmlNode | Select-Object -ExpandProperty position | Out-String) # current position in msec
# Because there are two properties named "position" in the XML, the variable "$VideoPositionTemp" will not only have the numeric position value but this:
#
# 123456789
#
# panY zoomX zoomY
# ---- ----- -----
# -0.063 0.8 0.8
#
# The first number is the "position"-value we are looking for. The following loop will extract this number in a classic way:
$VideoPosition = ""
$i = 0
while ( ($i -lt $VideoPositionTemp.Length) -and ($VideoPositionTemp.Chars($i) -ge "0") -and ($VideoPositionTemp.Chars($i) -le "9") )
{
$VideoPosition = $VideoPosition + $VideoPositionTemp.Chars($i)
$i = $i + 1
} # while
if ($LastTitleText -ne $TitleText)
# title changed, vMix Title Input needs to be updated
{
# at first place store the new unmodified title as the last inquired title text to detect changes in the next loop
$LastTitleText = $TitleText
# remove the file extension beginning at the last dot found in the name
$fileExtPos = $TitleText.LastIndexOf(".")
if ($fileExtPos -gt 0)
{
$TitleText = $TitleText.Substring(0, $fileExtPos);
}
# the "shortTitle" read from the vMix Input is the same as the text the vMix Input's full title begins with
$ShortTitleText = ($XmlNode | Select-Object -ExpandProperty shortTitle | Out-String)
# but for some unknown reason $ShortTitleText has 2 invisible chars more at the end, so Trim() helps here
$ShortTitleText = $ShortTitleText.Trim()
# return the right part of the title string beginning at index + 3 for " - "
$TitleText = $TitleText.Substring($ShortTitleText.Length + 3)
# in a URL the following characters must be encoded as "%" + hex value
$TitleText = $TitleText -replace "#", "%23" # pound character
$TitleText = $TitleText -replace "&", "%26" # ampersand
$TitleText = $TitleText -replace [char]0x0060, "%60" # grave accent
# write information on the PowerShell Console
write-host ""
write-host "Updating vMix input: $TitleInputNumber - $TitleInputField" -ForegroundColor Yellow
write-host "With: " $TitleText -ForegroundColor Yellow
# temporary create an URL to set the new title text
$TempURL = $UrlSetTitleText + $TitleText
# write information on the PowerShell Console
write-host $TempURL -ForegroundColor Green
# write the new title text into the text object of the vMix Input
(New-Object System.Net.WebClient).DownloadString("$TempURL")
# in PowerShell Console the text "Function completed successfully." will be shown implicitly
} # if ($LastTitleText -ne $TitleText)
if ($OvlControlEnabled = $true)
# handle overlay fade in/out only if generally enabled
{
# check whether there is any vMix Input displayed in the overlay $OvlNumber
#
$OverlayInputNumber = $XmlData.SelectSingleNode("/vmix/overlays/overlay[$OvlNumber]").InnerXml
$OverlayState = ($OverlayInputNumber -ne "")
# get the number of the active input in vMix
$ActiveInput = $XmlData.SelectSingleNode("/vmix/active").InnerXml
# Check if the overlay needs to be shown
# Note: the variables needs to be forced (type casted) to be interpreted as a 64-Bit Integer value. Otherwise they would be treated as strings which will not give the expected results.
if ( (($ActiveInput -ne $ListInputNumber) -and ($OverlayState -eq $true)) -or ( ($OverlayState -eq $true) -and ([int64]$VideoPosition -ge ([int64]$VideoDuration - [int64]$OvlFadeOutDelay)) -and ([int64]$VideoPosition -ne [int64]$VideoDuration) ) )
# if the Video List Input is the active program AND
# the overlay not already visible AND
# the current video position is past the fade-in AND
# before fade-out time, then show the overlay
{
write-host ""
write-host "Overlay $OvlNumber fade IN" -ForegroundColor Yellow
(New-Object System.Net.WebClient).DownloadString("$UrlSetOvlFadeIn")
$OverlayState = $true
}
# Check if the overlay needs to be hidden. If the current video position equals it's duration, this is when the video is at it's end and stopped, the vMix operator may show any Input in the overlay.
# Note: the variables needs to be forced (type casted) to be interpreted as a 64-Bit Integer value. Otherwise they would be treated as strings which will not give the expected results.
if ( (($ActiveInput -ne $ListInputNumber) -and ($OverlayInputNumber -eq $TitleInputNumber)) -or ( ($OverlayState -eq $true) -and ([int64]$VideoPosition -ge ([int64]$VideoDuration - [int64]$OvlFadeOutDelay)) -and ([int64]$VideoPosition -ne [int64]$VideoDuration) ) )
# if the Video List Input is not the active program AND the title input is in the overlay, OR
# the overlay is visible AND
# the current video position has passed the fade-out time before the end AND
# the video position is not exactly at the end, then hide the overlay.
#
# The last condition ("the video position is not exactly at the end") makes sure, that
# the vMix operation may manually show an Title Input in the overlay if a video ended
# and the video list stops. Otherwise the overlay would be immediatly hidden again
# because of the preceeding conditions are true.
{
write-host ""
write-host "Overlay $OvlNumber fade OUT" -ForegroundColor Yellow
(New-Object System.Net.WebClient).DownloadString("$UrlSetOvlFadeOut")
$OverlayState = $false
}
} # if ($OvlControlEnabled = $true)
# Write a dot as a "be alive" signal in the PowerShell Console
$BeAliveCount = $BeAliveCount + 1
if ($BeAliveCount -ge 60)
{
write-host "." # after the 60th dot make a new line
$BeAliveCount = 0
}
else
{
write-host "." -NoNewLine
}
# pause this script for 1 second
Start-Sleep -Seconds 1
# check whether the user has pressed "q" on the keyboard. If yes, then terminate this script.
if ($Host.UI.RawUI.KeyAvailable -and ("q" -eq $Host.UI.RawUI.ReadKey("IncludeKeyUp,NoEcho").Character))
{
Write-Host ""
Write-Host "Exiting now..."
break;
} # if
} # WHILE
#------------------------------------------------------------------------------------------------------------------
|