Last active
July 1, 2021 00:23
-
-
Save brunchboy/223f99e39d832e0ca94c09eab3b04134 to your computer and use it in GitHub Desktop.
Simpler OBS overlay template for Beat Link Trigger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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