Description
Description
callBatch() returns a promise that should reject if an error occurs.
If you submit an invalid execution type, this causes a disconnect (presumably from OBS's side)
This library does not then settle the promise and it remains stuck in pending indefinitely.
Re-connecting does not result in the promise becoming settled.
The issue is reproducible using the 2 scripts provided. The first script uses setInterval() to show that the promise remains in pending and that neither the .then() and .catch() branches are not executed following the disconnect. The second scripts illustrates that re-connecting to OBS does not alleviate the problem.
Using the scripts:
- Change the
url
andpw
parameters - Create a media source called 'test track' in OBS.
If you need to match my configuration exactly, my media source is configured as follows:
loop: false
restart playback...: false
use hardware dec...: true
show nothing...: true
close file when...: true
speed: 100%
YUV colour range: Auto
apply alpha in lin....: false
FFmpeg Options:
Versions
OBS version: 30.2.3
(from npm list
) obs-websocket-js@5.0.6
node version: v20.9.0
Script 1
import { OBSWebSocket } from 'obs-websocket-js';
let url = 'ws://';
let pw = '';
let idParams = {rpcVersion: 1}
let inputName = "test track";
let obs = new OBSWebSocket();
// Connect
try {
let conInfo = await obs.connect(url, pw, idParams);
console.log(`Connected to OBS websockets ${conInfo.obsWebSocketVersion} (using RPC ${conInfo.negotiatedRpcVersion})`);
} catch (error) {
console.error("[Error] Failed to connect to OBS websockets", error.code, error.message);
}
// Put error message in console when connection closed
obs.on("ConnectionClosed", (error) => {
console.log("[Error] OBS connection closed event.", error);
});
try {
let thePromise = obs.callBatch(
[
{
requestType: "SetMediaInputCursor",
requestData: {
inputName: inputName,
mediaCursor: 1000
}
},
{
requestType: "SetInputVolume",
requestData: {
inputName: inputName,
inputVolumeDb: 80
}
}
],
{
haltOnFailure: true,
executionType: 'RequestBatchExecutionType::SerialRealtime' //This is invalid and it's what causes websocket disconnect
}
);
// show promise state in console
setInterval((a)=>console.log(a), 1500, thePromise);
const response = await thePromise;
console.log("We never get here");
console.log(response);
} catch (error) {
console.log("we never get here either");
console.log(error);
}
console.log("end");
Script 2 (reconnection)
import { OBSWebSocket } from 'obs-websocket-js';
let url = 'ws://';
let pw = '';
let idParams = {rpcVersion: 1}
let inputName = "test track";
let obs = new OBSWebSocket();
// Connect
async function connect(url, pw, idParams) {
try {
let conInfo = await obs.connect(url, pw, idParams);
console.log(`Connected to OBS websockets ${conInfo.obsWebSocketVersion} (using RPC ${conInfo.negotiatedRpcVersion})`);
} catch (error) {
console.error('Failed to connect to OBS websockets', error.code, error.message);
}
}
await connect(url, pw, idParams);
// Put error message in console when connection closed
obs.on("ConnectionClosed", (error) => {
console.log("[Error] OBS connection closed event, re-attempting connection.", error);
connect(url, pw, idParams);
});
try {
let thePromise = obs.callBatch(
[
{
requestType: "SetMediaInputCursor",
requestData: {
inputName: inputName,
mediaCursor: 1000
}
},
{
requestType: "SetInputVolume",
requestData: {
inputName: inputName,
inputVolumeDb: 80
}
}
],
{
haltOnFailure: true,
executionType: 'RequestBatchExecutionType::SerialRealtime' //This is invalid and it's what causes websocket disconnect
}
);
// show promise state in console
setInterval((a)=>console.log(a), 1500, thePromise);
const response = await thePromise;
console.log("We never get here");
console.log(response);
} catch (error) {
console.log("we never get here either");
console.log(error);
}
console.log("end");