Simpler OBS overlay template for Beat Link Trigger
<html> | |
<head> | |
<title>OBS Overlay</title> | |
<link rel="stylesheet" type="text/css" href="styles.css"> | |
<script> | |
/** How often to check for changes when no player is playing. */ | |
const idleInterval = 500; | |
/** Keeps track of the previous player state, so we can look for changes. */ | |
var lastState; | |
/** | |
* Check whether there is any player currently playing a track. | |
* | |
* @param state the player parameters object returned by params.json. | |
* @return true if at least one player is playing something. | |
*/ | |
function isAnyPlayerPlaying(state) { | |
return state && Object.values(state.players).find(player => player["is-playing"]) !== undefined; | |
} | |
/** | |
* Calculate how long to wait before next performing an action, depending on player state. | |
* If no player is active, return whichever is larger of idleInterval and activeInterval. | |
* Otherwise return interval. | |
* | |
* @param activeInterval how many milliseconds to wait if at least one player is playing. | |
* @return the number of milliseconds after which an activity should reschedule itself. | |
*/ | |
function nextInterval(activeInterval) { | |
if (isAnyPlayerPlaying(lastState)) { | |
return activeInterval; | |
} | |
return (idleInterval > activeInterval)? idleInterval : activeInterval; | |
} | |
/** | |
* Reloads the master playuer artwork at the speciried interval. If no player is playing, then | |
* idleInterval will be used instead, unless the specified interval is already longer. | |
* | |
* @param interval the number of milliseconds that should elapse between reloads. | |
*/ | |
function refreshArt(interval) { | |
const element = document.getElementById('art'); | |
const refresher = function() { | |
fetch('params.json') | |
.then(response => { | |
if (response.status == 200) { | |
response.json() | |
.then(state => { | |
if (state.master && state.master.number) { | |
element.src = '/artwork/' + state.master.number + '?icons=true'; | |
} | |
setTimeout(refresher, nextInterval(interval)); | |
}) | |
} else { | |
console.error('Problem updating OBS overlay parameters', response); | |
setTimeout(refresher, 5000); | |
} | |
}) | |
.catch(error => { | |
// TODO: Show something on the page itself. | |
console.error('Problem communicating with OBS overlay server', error); | |
setTimeout(refresher, 30000); | |
}); | |
} | |
setTimeout(refresher, nextInterval(interval)); | |
} | |
/** | |
* Given an old and new value for a text element on the page, | |
* if they differ, updates the corresponding DOM element to contain | |
* the new text. | |
* | |
* @param id the DOM id of the element to be updated. | |
* @param current what the new value for this element should be. | |
* @param last the previous value of the element. | |
*/ | |
function updateIfChanged(id, current, last) { | |
if (current !== last) { | |
document.getElementById(id).textContent = current; | |
} | |
} | |
/** | |
* Compares the most recently received server state with the previous one, and updates | |
* any page text elements whose values need to be be changed. | |
* | |
* @param state the new server state object. | |
*/ | |
function applyChanges(state) { | |
const lastPlayer = lastState && lastState.master | |
const track = state.master.track; | |
const lastTrack = lastPlayer && lastPlayer.track; | |
updateIfChanged('artist', track && track.artist, lastTrack && lastTrack.artist); | |
updateIfChanged('title', track && track.title, lastTrack && lastTrack.title); | |
} | |
/** | |
* Periodically determines the current player state, and updates the page appropriately. | |
* | |
* @param interval how often the should be updated, in milliseconds, when a player is active. | |
*/ | |
function updateState(interval) { | |
const updater = function() { | |
fetch('params.json') | |
.then(response => { | |
if (response.status == 200) { | |
response.json() | |
.then(state => { | |
applyChanges(state); | |
lastState = state; | |
setTimeout(updater, nextInterval(interval)); | |
}) | |
} else { | |
console.error('Problem updating OBS overlay parameters', response); | |
setTimeout(updater, 5000); | |
}}) | |
.catch(error => { | |
// TODO: Show something on the page itself. | |
console.error('Problem communicating with OBS overlay server', error); | |
setTimeout(updater, 30000); | |
}); | |
} | |
updater(); | |
} | |
updateState(66); | |
</script> | |
</head> | |
<body> | |
<p> | |
<img id="art" src="artwork/{{master.number}}?icons=true" width="80" height="80" align="left"> | |
<script>refreshArt(1000);</script> | |
<span id="title" style="font-size:30px" style="font-family:Titillium Web">{{master.track.title}}</span> | |
<br> | |
<span id="artist" style="font-size:20px" style="font-family:Titillium Web">{{master.track.artist}}.</span> | |
</p> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment