Files
ghbot/lib/ghobs.js
2018-10-23 11:52:26 -07:00

157 lines
5.5 KiB
JavaScript
Executable File

const OBSWebSocket = require('obs-websocket-js');
function GHOBS(config) {
this.config = config;
this.websocket = new OBSWebSocket();
this.init = () => {
return new Promise((resolve, reject) => {
console.log(`Connecting to OBS Websocket...`);
this.websocket.connect({ address: this.config.obs.websocket.address, password: this.config.obs.websocket.password })
.then(() => {
console.log(`Success! We're connected to OBS!`);
this.websocket.getCurrentScene().then(currentScene => this.currentScene = currentScene.name);
this.websocket.onSwitchScenes(newScene => this.currentScene = newScene.sceneName);
resolve();
})
.catch(reject);
// Listen for errors from OBS
// @TODO: Handle socket disconnect gracefully
/** { status: 'error',
description: 'There is no Socket connection available.',
code: 'NOT_CONNECTED',
error: 'There is no Socket connection available.' }*/
this.websocket.on('error', err => {
console.error(`OBS websocket error: ${JSON.stringify(err)}`);
});
});
};
// Plays a video in the current scene and hides when finished
this.playVideo = (video, callback) => {
return new Promise((resolve, reject) => {
// @TODO Validation of video
// set the file path on the source
let sourceSettings = {
local_file: video.filePath,
looping: (typeof video.loops !== 'undefined' && video.loops > 1)
};
sourceSettings.loop = sourceSettings.looping;
this.websocket.setSourceSettings({"sourceName": video.sceneItem, "sourceSettings": sourceSettings})
// show the video scene item
.then(() => this.websocket.setSceneItemProperties({"item": video.sceneItem, "visible": true}))
// when the video is over, hide it and trigger the user callback, but resolve promise immediately with the timer
.then(() => {
// if this video is being looped, adjust timeout length to allow the requested number of loops to complete
if (sourceSettings.loop === true) {
video.length *= video.loops;
}
// resolve Promise with a timer of when the video will finish playback
// trigger user callback when the video finishes
let timer = setTimeout(() => {
this.websocket.setSceneItemProperties({"item": video.sceneItem, "visible": false});
if (typeof callback !== 'undefined') {
callback();
}
}, parseInt(video.length*1000));
resolve(timer);
})
.catch(reject);
});
}
// Shows a video in the given scene/item and then hides it and switches back to the original scene when finished
this.playVideoInScene = (video, scene, callback) => {
return new Promise((resolve, reject) => {
video.scene = scene;
let originalScene = this.currentScene || false;
let handleVideoEnd = () => {
if (originalScene !== false) {
this.websocket.setCurrentScene({"scene-name": originalScene});
}
if (typeof callback !== 'undefined') {
callback();
}
};
this.websocket.setCurrentScene({"scene-name": scene})
.then(() => this.playVideo(video, handleVideoEnd))
.then(timer => { resolve(timer) })
.catch(reject);
});
};
this.showActivity = (newActivity) => {
let update = {
"source": this.config.currentActivitySceneItemName,
"scene-name": this.config.defaultSceneName,
"render": true
};
if (typeof newActivity !== 'undefined' && newActivity.length > 0) {
update.text = newActivity;
}
return this.websocket.setTextGDIPlusProperties(update);
};
this.hideActivity = () => {
return this.websocket.setSceneItemProperties({"item": this.config.currentActivitySceneItemName, "scene-name": this.config.defaultSceneName, "visible": false});
};
this.showRoomGrind = (playTime, callback) => {
return new Promise((resolve, reject) => {
this.websocket.setSceneItemProperties({"item": "room-grind", "scene-name": this.config.defaultSceneName, "visible": true})
.then(res => {
this.showActivity("NOW SHOWING: TTAS Room Grind !ttas");
resolve(setTimeout(() => {
// after timeout, hide room-grind and call user callback
this.websocket.setSceneItemProperties({"item": "room-grind", "scene-name": this.config.defaultSceneName, "visible": false});
if (typeof callback !== 'undefined') callback();
}, playTime*1000));
})
.catch(reject);
});
};
this.setVisible = (item, scene, visible) => {
return this.websocket.setSceneItemProperties({"item": item, "scene-name": scene, "visible": visible});
};
this.toggleVisible = (item) => {
return new Promise((resolve, reject) => {
this.websocket.getSceneItemProperties({"item": item})
.then(data => {
let newVisibility = !data.visible;
this.websocket.setSceneItemProperties({"item": item, "visible": newVisibility}).then(resolve);
})
.catch(reject);
});
}
this.show = (item, scene) => {
return this.setVisible(item, scene, true);
};
this.hide = (item, scene) => {
return this.setVisible(item, scene, false);
};
this.switchToScene = (scene) => {
return new Promise((resolve, reject) => {
if (this.currentScene === scene) {
resolve(true);
}
this.websocket.setCurrentScene({"scene-name": scene}).then(resolve).catch(reject);
});
};
};
module.exports = GHOBS;