The VMA Video Analyser Package has an important new addition: a transversal macro language that can be used to automate processes in VMA Stream Reader, VMA Transport Stream Analyser, VMA Mosaic and VMA Video Analyser.
One single macro can interact with all applications!
The macro language gives access to all controls (buttons, textboxes, lists, etc.) and adds typical functions like IF-THEN-GOTO, IF-THEN-ELSE-ENDIF, FOR-NEXT, FOREACH-ENDFOREACH, GOTO-LABEL. Also included are functions to manipulate lists and strings, output to a user window or to a file and screenshot functions.
This way, any user can greatly extend the already vast functionality of the VMA Video Analyser Package.
Here is an example: how about a way to automatically scan the selected satellite: do a spectrum sweep, automatically perform a scan of all transponders and then render a list with the services of each transponder, preferably with a screenshot?
Here is the required macro:
;
; VMA Stream Reader Macro
;
; =========== CHANNEL SCAN → SATNAME.html + screenshots ===========
OUTPUT.SHOW
OUTPUT.CLEAR
PRINT "------------------"
PRINT "Channel Scan Macro"
PRINT "------------------"
; --- Resolve satellite name and output locations ---
VMA.READER.MACRO: GET cmbSatellite AS satName
VMA.READER.MACRO: GET cmbPol AS polarity
LET satSafe "${satName}"
STR.REPLACE_REGEX "${satSafe}" "[\\/:*?'<>|]" "_" AS satSafe
; HTML path: C:\Temp\SATNAME.html
FORMAT "C:\Temp\{0} - {1}.html" "${satSafe}" "${polarity}" AS htmlPath
; Screenshot root: C:\Temp\SATNAME
FORMAT "C:\Temp\{0}" "${satSafe}" AS shotsRoot
LET outPath "C:\Temp\ChannelScan.csv"
CLICK Button2
TAB.SELECT "Auto Scan"
PRINT "Starting AUTO SCAN SPECTRUM..."
CLICK Button4
; --- Start fresh HTML ---
FILE.WRITE "${htmlPath}" "<!DOCTYPE html>"
FILE.APPEND "${htmlPath}" "<html><head><meta charset='utf-8'><title>${satSafe}</title>"
FILE.APPEND "${htmlPath}" "<style>body{font-family:Segoe UI,Arial,sans-serif;background:#111;color:#eee;padding:12px}h1,h2{color:#9fe871}table{border-collapse:collapse;margin:8px 0;width:100%}th,td{border:1px solid #444;padding:6px 8px;font-size:12px}th{background:#222}code{color:#ccc}.pics img{max-width:320px;margin:4px;border:1px solid #333;border-radius:4px}</style></head><body>"
FILE.APPEND "${htmlPath}" "<h1>${satSafe}</h1>"
; --- Make sure we're on Auto Scan tab and have carriers ---
TAB.SELECT "Auto Scan"
LISTBOX.GET_ITEMS lstCarriers AS carriers
IF "${carriers}" = ' THEN
FILE.APPEND "${htmlPath}" "<p>No carriers found.</p></body></html>"
PRINT "No carriers found. Aborting."
GOTO END
ENDIF
; --- Launch TSA and connect (so we can read the services list) ---
APP.LAUNCH "VMA TRANSPORT STREAM ANALYSER.EXE"
APP.WAIT "VMA.TSA.MACRO" 3000
RENEW.CONNECTION TSA
; ======================= Iterate carriers =======================
FOREACH c IN "${carriers}"
PRINT "Processing carrier: ${c}"
TAB.SELECT "Auto Scan"
; Activate the carrier
LISTBOX.DBLCLICK lstCarriers "${c}"
SLEEP 1500
; Start streaming (this may auto-launch/connect TSA)
CLICK Button1
APP.WAIT "VMA.TSA.MACRO" 10000
RENEW.CONNECTION TSA
; Start/refresh TSA measurement
VMA.TSA.MACRO: CLICK btnStart
SLEEP 5000
; Fetch services table from TSA
VMA.TSA.MACRO: LISTVIEW.GET_ROWS lvDetails ALL AS svc
; Section header in HTML
FILE.APPEND "${htmlPath}" "<h2>Transponder: ${c}</h2>"
IF "${svc}" = "" THEN
FILE.APPEND "${htmlPath}" "<p>No Service</p>"
GOTO _skipMosaic
ENDIF
; Build services table
FILE.APPEND "${htmlPath}" "<table>"
FILE.APPEND "${htmlPath}" "<tr><th>Type</th><th>CA</th><th>Name</th><th>Prog ID</th><th>VPID</th><th>APID</th><th>Bitrate</th></tr>"
STR.SPLIT "${svc}" SEP "{CRLF}" AS svcLines
FOREACH row IN "${svcLines}"
IF "${row}" = "" THEN GOTO _skipRow
; split into cells
STR.SPLIT "${row}" SEP "{TAB}" AS cells
; skip header rows like "svc" or "Type"
VAR first ""
FOREACH c0 IN "${cells}"
IF "${first}" = "" THEN LET first "${c0}"
ENDFOREACH
IF "${first}" = "svc" THEN GOTO _skipRow
IF "${first}" = "Type" THEN GOTO _skipRow
; write row
FILE.APPEND "${htmlPath}" "<tr>"
FOREACH cell IN "${cells}"
FILE.APPEND "${htmlPath}" "<td>${cell}</td>"
ENDFOREACH
FILE.APPEND "${htmlPath}" "</tr>"
LABEL _skipRow
ENDFOREACH
FILE.APPEND "${htmlPath}" "</table>"
; ======================= Mosaic screenshots =======================
; Open Mosaic from TSA
VMA.TSA.MACRO: CLICK btnMosaic
APP.WAIT "VMA.MOSAIC.MACRO" 15000
RENEW.CONNECTION MOSAIC
; Determine freq-only folder name (first token of c)
LET c_short "${c}"
STR.REPLACE_REGEX "${c_short}" "^([^ ]+).*" "$1" AS c_short
; Folder: C:\Temp\SATNAME\<freq>
VAR shotDir '
FORMAT "{0}\{1}" "${shotsRoot}" "${c_short}" AS shotDir
VMA.MOSAIC.MACRO: CATALOG PANEL AS _pans
FILE.APPEND "${htmlPath}" "<div class='pics'>"
FOREACH p IN "${_pans}"
; Safe filename for panel
LET p_safe "${p}"
STR.REPLACE_REGEX "${p_safe}" "[\\/:*?'<>|]" "_" AS p_safe
STR.REPLACE_REGEX "${p_safe}" "^\s+|\s+$" ' AS p_safe
; Absolute image path: C:\Temp\SATNAME\<freq>\<panel>.png
VAR shotPath '
FORMAT "{0}\{1}.png" "${shotDir}" "${p_safe}" AS shotPath
; Relative path from C:\Temp\SATNAME.html to the file: SATNAME\<freq>\<panel>.png
VAR relImg '
FORMAT "{0}\{1}\{2}.png" "${satSafe}" "${c_short}" "${p_safe}" AS relImg
VMA.MOSAIC.MACRO: SCREENSHOT.PANEL "${p}" "${shotPath}"
FILE.APPEND "${htmlPath}" "<img src='${relImg}' alt='${p_safe}'>"
ENDFOREACH
FILE.APPEND "${htmlPath}" "</div>"
APP.STOP MOSAIC
LABEL _skipMosaic
; Optional: stop TSA measurement for this TP
VMA.TSA.MACRO: CLICK btnStart
ENDFOREACH
APP.STOP TSA
; ======================= Finish HTML =======================
FILE.APPEND "${htmlPath}" "</body></html>"
PRINT "HTML written: ${htmlPath}"
LABEL END
; ======================================================
The result of executing the macro can be seen here:

The VMA Macro Interpreter acts as an editor and debugger. Commands can be send individually, macros can be executed to the connected application and, most importantly, a catalog of the available controls can be downloaded, showing a tree view of all controls and the respective supported commands.
Once a macro is completed and error-free, it can be simply executed inside the respective app by pressing the F2 key.
Linear macros can be recorded using the F9 key. These can then be played back or edited in the VMA Macro Interpreter to include further commands, conditions, etc.
The F5 key (in case of VMA Mosaic it is the F6 key) shows little tags that help identify the name of the respective control:

Showcase of what can be done with the Macro Engine
Here is an example of an Automatic Transponder and Channel Scan on all configured satellites, producing a webpages and screenshots without user intervention. It uses the same macro as above, but wraps it inside two further FOREACH loops: one for each configured satellite, the other for Horizontal and Vertical polarities.
The result can be seen here:
