content/hifi-content/Docs/Music Player Tutorial/boomBoxEntityServerScript.js
2022-02-13 22:49:05 +01:00

122 lines
No EOL
5.3 KiB
JavaScript

// Happy Boombox
// boomBoxEntityScript.js
// Licensed under the Apache 2.0 License
// Music provided by Bensound
(function(){
var LOAD_WAIT = 500;
var selfEntityID;
var audioInjector;
var volume = 0.5;
function BoomBox(){
}
/**
* playSong()
* Checks to see if the given sound is downloaded.
* If the song is downloaded, it plays the sound per the audio injector options
* If the song is not downloaded, we wait half a second and try again.
* @param {*SoundObject} sound
* @param {*Object} audioInjectorOptions
*/
function playSong(sound, audioInjectorOptions) {
if (sound.downloaded) {
audioInjector = Audio.playSound(sound, audioInjectorOptions);
} else {
Script.setTimeout(playSong, LOAD_WAIT);
}
}
/**
* BoomBox Prototype
* This contains our functions that are specific to our boombox entity.
*/
BoomBox.prototype = {
/**
* The remotelyCallable array specifies which functions in our prototype object
* can be called from another entity, Interface, or assignment client script. The boomBoxEntityScript
* remotely calls these methods to control the audio on our entity, so we need to directly list them
* to make them accessible to other scripts.
*/
remotelyCallable: ['playMusic', 'stopMusic', 'adjustVolume'],
/**
* The preload() function is called when the entity server script first starts: when the server first comes up,
* or after the entity server script is reloaded. It has a reference to the entityID of the entity that it is on,
* which we store in our selfEntityID variable.
*
* We attempt to save some time down the road by accessing the userdata list of music and preloading the audio, then
* capture the initial volume of the boombox so that we do not need to make an additional edit down the road.
*/
preload: function(entityID) {
selfEntityID = entityID;
// Userdata will be returned as a stringified object, so we parse it to access the objects
var boomBoxData = JSON.parse(Entities.getEntityProperties(selfEntityID, 'userData').userData);
var songsToPreload = boomBoxData.music;
songsToPreload.foreach(function(song){
SoundCache.preload(song);
});
volume = boomBoxData.volume;
},
/**
* The unload() function is called when the entity server script is no longer needed: either it is removed
* from the entity or the entity script server has stopped. We want to stop playing our audio if this happens
* when we are playing music.
*/
unload: function () {
if (audioInjector && audioInjector.playing) {
audioInjector.stop();
}
},
/**
* One of our remotely callable functions. The boomBoxEntityScript can call this function remotely when
* it receives a request from the HTML controller. We pass in the specified sound URL through the args
* parameter, set up our audio injector options, stop previously playing music, and then play the new song.
*/
playMusic: function(entityID, args) {
var sound = SoundCache.getSound(args[0]);
var audioInjectorOptions = {
volume: volume,
loop: false,
position: Entities.getEntityProperties(selfEntityID, 'position').position
};
if (audioInjector && audioInjector.playing) {
audioInjector.stop();
}
playSong(sound, audioInjectorOptions);
},
/**
* Another remotely callable function. This stops the music from playing and does not require a parameter.
*/
stopMusic : function() {
if (audioInjector && audioInjector.playing) {
audioInjector.stop();
}
},
/**
* The last of our remotely callable functions. The args[0] parameter contains the value of the new volume
* level, but the type of the argument is a string, so we first parse it into a float. We then get the position
* and userdata properties of our boombox entity, edit the properties of our audio injector to change the volume
* of playing music, and save the new volume value back to the userdata.
*/
adjustVolume : function(entityID, args) {
volume = parseFloat(args[0]);
var properties = Entities.getEntityProperties(selfEntityID, ['position', 'userData']);
if (audioInjector) {
audioInjector.setOptions({
volume: volume,
loop: false,
position: properties.position
});
}
var userdata = JSON.parse(properties.userData);
userdata.volume = volume;
// We need to stringify our data before resetting it on the entity
Entities.editEntity(selfEntityID, {'userData' : JSON.stringify(userdata)});
}
};
return new BoomBox();
});