auto fade out
This commit is contained in:
90
lib/fgfm.js
90
lib/fgfm.js
@@ -5,6 +5,7 @@ function FGFM(config) {
|
||||
this.config = config.config;
|
||||
this.obs = config.obs;
|
||||
this.state = {
|
||||
showStatus: 'IDLE',
|
||||
videoQueue: [],
|
||||
recentlyPlayed: [],
|
||||
currentVideo: null,
|
||||
@@ -13,14 +14,96 @@ function FGFM(config) {
|
||||
commercialPlaying: false
|
||||
};
|
||||
|
||||
this.startingSoon = (autostartDelaySeconds) => {
|
||||
this.state.showStatus = 'STARTING_SOON';
|
||||
|
||||
// Set up the initial queue by randomly choosing the configured amount of vods included in shuffling
|
||||
this.state.videoQueue = this.config.vods.alttp.filter(e => e.includeInShuffle === true).sort(util.randSort).slice(0, this.config.initialQueueSize);
|
||||
|
||||
// show the starting-soon scene
|
||||
this.obs.switchToScene('starting-soon');
|
||||
|
||||
// restore volume
|
||||
this.obs.setVolume('headphones', 1.0);
|
||||
|
||||
// start the stream
|
||||
this.obs.startStream();
|
||||
|
||||
if (typeof autostartDelaySeconds === 'undefined') {
|
||||
autostartDelaySeconds = 300;
|
||||
}
|
||||
|
||||
if (autostartDelaySeconds !== false) {
|
||||
// @TODO: Actually show the countdown in the scene
|
||||
console.log(`The show will start in ${autostartDelaySeconds} seconds!`);
|
||||
setTimeout(this.startTheShow, autostartDelaySeconds*1000);
|
||||
}
|
||||
};
|
||||
|
||||
// Set up initial queue + start playback
|
||||
this.init = () => {
|
||||
this.startTheShow = () => {
|
||||
// Set up the initial queue by randomly choosing the configured amount of vods included in shuffling
|
||||
this.state.videoQueue = this.config.vods.alttp.filter(e => e.includeInShuffle === true).sort(util.randSort).slice(0, this.config.initialQueueSize);
|
||||
|
||||
// Start queue playback
|
||||
this.state.currentVideo = this.state.videoQueue.shift();
|
||||
this.showVideo(this.state.currentVideo);
|
||||
|
||||
// restore volume
|
||||
this.obs.setVolume('headphones', 1.0);
|
||||
|
||||
this.state.showStatus = 'RUNNING';
|
||||
};
|
||||
|
||||
this.endTheShow = (creditsDelaySeconds, endDelaySeconds) => {
|
||||
if (typeof creditsDelaySeconds === 'undefined' || creditsDelaySeconds === false) {
|
||||
creditsDelaySeconds = 0;
|
||||
}
|
||||
|
||||
if (typeof endDelaySeconds === 'undefined' || endDelaySeconds === false) {
|
||||
endDelaySeconds = 60;
|
||||
}
|
||||
|
||||
console.log(`Credits will be shown in ${creditsDelaySeconds} seconds!`);
|
||||
|
||||
let end = () => {
|
||||
this.state.showStatus = 'ENDING';
|
||||
|
||||
this.obs.switchToScene('credits')
|
||||
.then(() => {
|
||||
if (endDelaySeconds < 5) endDelaySeconds = 5;
|
||||
console.log(`Stream will stop in ${endDelaySeconds} seconds`);
|
||||
let fadeOutDelay = endDelaySeconds - 5;
|
||||
|
||||
// Fade out volume with 5 seconds left
|
||||
setTimeout(() => {
|
||||
this.obs.getVolume('headphones')
|
||||
.then(currentVolume => {
|
||||
console.log(`current volume of headphones: ${currentVolume}`);
|
||||
let step = 0.1;
|
||||
while (currentVolume > 0.1) {
|
||||
currentVolume -= step;
|
||||
console.log(`setting volume to: ${currentVolume}`);
|
||||
this.obs.setVolume('headphones', currentVolume);
|
||||
util.sleep(250);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
}, fadeOutDelay*1000);
|
||||
|
||||
setTimeout(() => {
|
||||
this.obs.stopStream();
|
||||
this.state.showStatus = 'ENDED';
|
||||
}, endDelaySeconds*1000);
|
||||
})
|
||||
.catch(console.error);
|
||||
};
|
||||
|
||||
if (creditsDelaySeconds > 0) {
|
||||
setTimeout(end, creditsDelaySeconds*1000);
|
||||
} else {
|
||||
end();
|
||||
}
|
||||
};
|
||||
|
||||
// Shows.. a... video
|
||||
@@ -71,6 +154,11 @@ function FGFM(config) {
|
||||
// Picks the next video in the queue (shuffles if empty)
|
||||
// Also handles "commercial breaks" if enabled
|
||||
this.nextVideo = () => {
|
||||
// @TODO: Validate this.state.showStatus -- make sure the "show" hasn't been paused or stopped
|
||||
if (this.state.showStatus === 'ENDING' || this.state.showStatus === 'ENDED') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show a "commercial break" if it's been long enough since the last one
|
||||
let secondsSinceLastCommercial = (Date.now() - this.state.lastCommercialShownAt) / 1000;
|
||||
if (this.config.commercialsEnabled === true && secondsSinceLastCommercial >= this.config.commercialInterval) {
|
||||
|
||||
22
lib/ghobs.js
22
lib/ghobs.js
@@ -28,6 +28,28 @@ function GHOBS(config) {
|
||||
});
|
||||
};
|
||||
|
||||
this.startStream = () => {
|
||||
return this.websocket.startStreaming();
|
||||
};
|
||||
|
||||
this.stopStream = () => {
|
||||
return this.websocket.stopStreaming();
|
||||
};
|
||||
|
||||
this.setVolume = (source, volume) => {
|
||||
return this.websocket.setVolume({source: source, volume: volume});
|
||||
}
|
||||
|
||||
this.getVolume = (source) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.websocket.getVolume({source: source})
|
||||
.then(res => {
|
||||
resolve(res.volume);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
// Plays a video in the current scene and hides when finished
|
||||
this.playVideo = (video, callback) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
11
lib/util.js
11
lib/util.js
@@ -48,4 +48,13 @@ exports.average = function(e) {
|
||||
return avg;
|
||||
};
|
||||
|
||||
exports.randSort = () => { return 0.5 - Math.random() };
|
||||
exports.randSort = () => { return 0.5 - Math.random() };
|
||||
|
||||
exports.sleep = (milliseconds) => {
|
||||
var start = new Date().getTime();
|
||||
for (var i = 0; i < 1e7; i++) {
|
||||
if ((new Date().getTime() - start) > milliseconds){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user