Skip to content

Instantly share code, notes, and snippets.

@XanderCodes
Created October 26, 2022 00:24
Show Gist options
  • Save XanderCodes/192e79ffeeb291597fea0dc16dbd1573 to your computer and use it in GitHub Desktop.
Save XanderCodes/192e79ffeeb291597fea0dc16dbd1573 to your computer and use it in GitHub Desktop.
Vmix Scripts
const { ConnectionTCP } = require('node-vmix')
const connection = new ConnectionTCP('localhost')
const fs = require("fs");
const { parse } = require("csv-parse");
// Listener for xml state data
// connection.on('xml', xmlData => {
// // Your logic here!
// // See example to parse the XML correctly
// console.log(xmlData);
// })
// Listener for tally
connection.on('tally', tally => {
// Your logic here!
//console.log(tally);
})
// Listener for data such as tally
connection.on('data', data => {
// console.log(data);
})
connection.on('connect', () => {
// Request vMix API XML state by sending message 'XML'
//connection.send('XML')
console.log("Connected!");
connection.send({ Function: 'ScriptStop', Value: 'PageLoop' });
//var stream = require("fs").createReadStream("C:\\Users\\Production\\Downloads\\timing_data.csv")
var arr = [];
fs.createReadStream("C:\\Users\\Production\\Downloads\\timing_data.csv")
.pipe(parse({ delimiter: ",", from_line: 2 }))
.on("data", function (row) {
// console.log(row);
arr.push(row);
})
.on("end", function () {
console.log("Read race data... " + arr.length + " lines found.");
// console.log(arr);
watch = setInterval(scriptWatchdog,200);
})
.on("error", function (error) {
console.log(error.message);
});
// Request vMix tally info by sending message 'TALLY'
//connection.send('TALLY')
})
const ParseXml = require('xml2js').parseStringPromise; // XML2JS converts XML into JSON
const XPath = require('xml2js-xpath');
async function scriptWatchdog() {
connection.send('XML');
connection.on('xml', xmlData => {
// Your logic here!
// See example to parse the XML correctly
getStatus(xmlData);
})
}
let scriptRunning = false;
async function getStatus(xmlData) {
let vmixXML = await ParseXml(xmlData ?? '');
// console.log(XPath.find(vmixXML, '/vmix'));
let state = vmixXML.vmix.inputs[0].input[5].$.state;
if (state == "Paused" && scriptRunning == true) {
connection.send({ Function: 'ScriptStop', Value: 'PageLoop' });
console.log("Graphic stopped. Stopping script!")
scriptRunning = false;
}
else if (state == "Running" && scriptRunning == false) {
connection.send({ Function: 'ScriptStart', Value: 'PageLoop' });
console.log("Graphic detected running... starting loop script!")
scriptRunning = true;
}
}
var easymidi = require('easymidi');
var input = new easymidi.Input('MixTrack Pro 3');
var virtualOutput = new easymidi.Output('FromVsToVmix');
input.on('cc', function (msg) {
// do something with msg
console.log(msg)
if (msg.channel == 1 && msg.controller == 17 && msg.value <= 64) {
virtualOutput.send('noteon', {
note: 64,
velocity: 0,
channel: 3
});
}
else if ((msg.channel == 1 && msg.controller == 17 && msg.value >= 65)) {
virtualOutput.send('noteon', {
note: 63,
velocity: 0,
channel: 3
});
}
if (msg.channel == 2 && msg.controller == 17 && msg.value <= 64) {
virtualOutput.send('noteon', {
note: 54,
velocity: 0,
channel: 3
});
}
else if ((msg.channel == 2 && msg.controller == 17 && msg.value >= 65)) {
virtualOutput.send('noteon', {
note: 53,
velocity: 0,
channel: 3
});
}
if (msg.channel == 1 && msg.controller == 19 && msg.value == 127) {
virtualOutput.send('noteon', {
note: 126,
velocity: 0,
channel: 3
});
}
else if ((msg.channel == 1 && msg.controller == 19 && msg.value == 1)) {
virtualOutput.send('noteon', {
note: 127,
velocity: 0,
channel: 3
});
}
});
input.on('noteon', function (msg) {
// do something with msg
console.log(msg)
virtualOutput.send('noteon', msg);
});
input.on('noteoff', function (msg) {
// do something with msg
console.log(msg)
virtualOutput.send('noteoff', msg);
});
{
"name": "vmix-gridresult",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"csv": "^6.2.1",
"easymidi": "^2.1.1",
"fast-xml-parser": "^4.0.11",
"node-vmix": "^1.6.1",
"vmix-js-utils": "^3.8.2",
"xml-js": "^1.6.11",
"xml2js": "^0.4.23",
"xml2js-xpath": "^0.13.0"
}
}
'Console.WriteLine("stuff!")
dim xml As Object = API.XML()
dim x as new system.xml.xmldocument
'set fake data thing to true so watchdog knows script is running
API.Function("SetText",Input:="LOWER GRID",SelectedName:="DATA.Text",Value:="true")
While true
'API.Function("TitleBeginAnimation",Input:="hs-racedata.02.gtzip",Value:="Page1")
'Sleep(2000)
x.loadxml(xml)
dim StateOf As String = (x.SelectSingleNode("//input[@number='6']/@state").Value)
If StateOf = "Running" Then
Console.WriteLine("it's running!")
'Dim RowCount = File.ReadAllLines("C:\Users\Production\Downloads\timing_data.csv").Length - 1
Dim RowCount As Integer = 0
Dim Lines As Array = File.ReadAllLines("C:\Users\Production\Downloads\timing_data.csv")
Dim Thing As String
For Each Thing in Lines
If Thing <> ",,,,,,,,,,,,,,,,,,,,,,,," Then
If Thing <> "LapsToGo,FlagStatus,FlagIcon,,,,,Position,Number,FirstName,LastName,Laps,LastLapTime,BestLap,BestLapTime,Diff,LastLapSpeed,BestLapSpeed,Nationality,AdditionalData,,,,," Then
If Thing <> "EndData" Then
If Thing <> "" Then
RowCount = RowCount + 1
End If
End If
End If
End If
Next
Dim HoldTime = 8000
Console.WriteLine(RowCount)
If RowCount < 11 Then
'no animation
ElseIf RowCount >= 21 Then
'transition between 1 and 2 and 3 and 4 (page 1, page 2, page 3, page 6)
Console.WriteLine("Running 1, 2, 3 and 4")
Sleep(HoldTime)
API.Function("TitleBeginAnimation",Input:="LOWER GRID",Value:="Page1")
Sleep(HoldTime)
API.Function("TitleBeginAnimation",Input:="LOWER GRID",Value:="Page2")
Sleep(HoldTime)
API.Function("TitleBeginAnimation",Input:="LOWER GRID",Value:="Page3")
Sleep(HoldTime)
API.Function("TitleBeginAnimation",Input:="LOWER GRID",Value:="Page6")
ElseIf RowCount >= 16 Then
'transition between 1 and 2 and 3 (page 1, page 2, page 5)
Console.WriteLine("Running 1, 2 and 3")
Sleep(HoldTime)
API.Function("TitleBeginAnimation",Input:="LOWER GRID",Value:="Page1")
Sleep(HoldTime)
API.Function("TitleBeginAnimation",Input:="LOWER GRID",Value:="Page2")
Sleep(HoldTime)
API.Function("TitleBeginAnimation",Input:="LOWER GRID",Value:="Page5")
ElseIf RowCount >= 11 Then
'transition between 1 and 2 (page 1, page 4)
Console.WriteLine("Running 1 and 2")
Sleep(HoldTime)
API.Function("TitleBeginAnimation",Input:="LOWER GRID",Value:="Page1")
Sleep(HoldTime)
API.Function("TitleBeginAnimation",Input:="LOWER GRID",Value:="Page4")
End If
End If
End While
'Is a input Running or on Pause retrieved from the API xml
'or
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment