aboutsummaryrefslogtreecommitdiff
path: root/client/js
diff options
context:
space:
mode:
Diffstat (limited to 'client/js')
-rw-r--r--client/js/radio_emulator.js188
1 files changed, 188 insertions, 0 deletions
diff --git a/client/js/radio_emulator.js b/client/js/radio_emulator.js
new file mode 100644
index 0000000..98138e7
--- /dev/null
+++ b/client/js/radio_emulator.js
@@ -0,0 +1,188 @@
+// Radio Emulator
+// Kaotisk Hund 2024
+//
+// A simple co-mechanism to pretend playing a live radio as it would happen for
+// a radio station that mostly plays prerecoded shows.
+//
+// Client side implementation
+// Let's remind here the structures we are waiting for:
+// 1. Hash
+// 2. 0
+// 3. audio/ogg file
+// 4. application/json file
+//
+// 1. Hash
+// Can be an SHA512sum or SHA256sum, we don't do checks, we only ask the hash
+// accompanied by what do we think it is.
+//
+// 2. 0
+// When nothing exists on the radio station we are visiting.
+//
+// 3. audio/ogg file
+// An audio file to play.
+//
+// 4. application/json file
+// Could be one of the following:
+// - list
+// - show_info
+//
+
+var audioElement = document.querySelector('audio');
+var sourceElement = document.querySelector('source');
+var currentTimeP = document.querySelector('.current-time');
+var listStartedP = document.querySelector('.started-on');
+var currentShowHash = document.querySelector('.current-show-hash');
+var listHash = document.querySelector('.list-hash');
+var artistP = document.querySelector('.artist');
+var titleP = document.querySelector('.title');
+var radioPlayerDiv = document.querySelector('.radio-player');
+var youAreHere = document.querySelector('.you-are-here');
+
+var seconds_here = 0;
+function increaseSeconds()
+{
+ seconds_here = seconds_here+1;
+ youAreHere.innerText = seconds_here;
+ return seconds_here;
+}
+function getSecondsHere()
+{
+ return seconds_here;
+}
+
+setInterval(increaseSeconds, 1000);
+
+
+function FetchJSON( url, callback, params )
+{
+ const request = new XMLHttpRequest();
+ request.addEventListener("load", ()=>{
+ var json = JSON.parse(request.response);
+ if(request.status !== 404){
+ callback(json, params);
+ } else {
+ console.log(`ERROR ${request.status} while loading ${url}`);
+ }
+ });
+ request.addEventListener("error", ()=>{
+ console.log("An error occured. While loading: "+url+" for "+callback+".");
+ });
+ // ProgressBar update: Interesting but not needed
+ // request.addEventListener("progress", (event)=>{
+ // if (event.lengthComputable && progressPlaceholder){
+ // httpProgressPlaceholder.value = (event.loaded / event.total) * 100;
+ // } else {
+ // httpProgressPlaceholder.value = 0;
+ // // console.log("Supposingly zeroed progressPlaceholder");
+ // }
+ // });
+ request.addEventListener("abort", ()=>{
+ console.log("Request aborted.");
+ });
+ request.open("GET", url);
+ request.send();
+}
+
+function genericCallback(json, params)
+{
+ console.log('genericCallback');
+ console.log(json);
+ console.log(params);
+}
+
+var calledLoadShowCallback = 0;
+
+function stopHereAndReflect()
+{
+
+}
+
+function loadShowCallback(json, params)
+{
+ const [ list, now_on_sequence, element, hash_of_list ] = params;
+// if ( calledLoadShowCallback === 0 )
+// {
+// calledLoadShowCallback++;
+ console.log('loadShowCallback');
+ console.log(json);
+ console.log(element);
+ console.log(params);
+ listStartedP.innerText = list.started_on;
+ listHash.innerText = hash_of_list;
+ currentShowHash.innerText = json.hash;
+ artistP.innerText = json.artist;
+ titleP.innerText = json.title;
+ // audioElement.pause();
+ sourceElement.src = "http://z.kaotisk-hund.com:8010/v0/audio/ogg/" + json.hash + "#t=" + Math.floor((now_on_sequence - element.starts_on)/1000);
+ sourceElement.type = json.mimetype;
+ audioElement.load();
+ console.log('plays here: '+(now_on_sequence - element.starts_on)/1000);
+ audioElement.addEventListener('canplaythrough', function(){
+ console.log('CAN PLAY THROUGH');
+ if ( calledLoadShowCallback < 100 )
+ {
+ calledLoadShowCallback++;
+ currentTimeP.innerText = ((now_on_sequence - element.starts_on)/1000);
+ audioElement.currentTime = ((now_on_sequence - element.starts_on)/1000);
+ audioElement.play();
+ }
+ });
+ audioElement.addEventListener('ended', function(){
+ location.reload();
+ //FetchJSON('http://z.kaotisk-hund.com:8010/v0/list', hashCallback, [ new Date().getTime()]);
+ });
+ sync_radio();
+ setTimeout(sync_radio, 30000);
+
+// } else {
+// return 0;
+// }
+}
+
+function sync_radio()
+{
+ var value = currentTimeP.innerText;
+ var new_now = parseFloat(value) + getSecondsHere();
+ console.log("Trying to sync @ "+ value + " + " +getSecondsHere() + " = " + new_now);
+ if ( value !== "" )
+ {
+ audioElement.currentTime = new_now;
+ }
+}
+
+function listCallback(json, params)
+{
+ console.log('listCallback');
+ var [ now, hash_of_list ] = params;
+ // var now = Date.now();
+ var delta_time = now - json.started_on;
+ var min_times_played = Math.floor( delta_time / json.duration );
+ var max_times_to_be_played = delta_time / json.duration;
+ var Dt = max_times_to_be_played - min_times_played;
+ var now_on_sequence = Dt * json.duration;
+ console.log(`now_on_sequence: ${now_on_sequence}, Dt: ${Dt}`)
+
+ previous = { starts_on: 0 };
+ json.list.forEach((element)=>{
+ if ( now_on_sequence < element.starts_on && now_on_sequence > previous.starts_on){
+ } else {
+ now_on_sequence = now_on_sequence - previous.starts_on;
+ console.log(now_on_sequence);
+ previous = element;
+ console.log(element);
+ FetchJSON("http://z.kaotisk-hund.com:8010/v0/application/json/" + element.hash, loadShowCallback, [json, now_on_sequence, element, hash_of_list]);
+ }
+ });
+}
+
+function hashCallback(json, params)
+{
+ var [ now ] = params;
+ console.log('hashCallback');
+ FetchJSON('http://z.kaotisk-hund.com:8010/v0/application/json/' + json.latest_list, listCallback, [now, json.latest_list]);
+}
+
+FetchJSON('http://z.kaotisk-hund.com:8010/v0/list', hashCallback, [ new Date().getTime() ]);
+
+
+