Skip to content

Instantly share code, notes, and snippets.

@matschaffer
Created November 7, 2019 20:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matschaffer/caa14b7d74b0e62d7eccc3a3d366663e to your computer and use it in GitHub Desktop.
Save matschaffer/caa14b7d74b0e62d7eccc3a3d366663e to your computer and use it in GitHub Desktop.
function ESPlayer(server, indexPattern, playCallback, initialLoad = 40, delay = 10, blockDuration = 10, size = 10) {
this.server = server;
this.indexPattern = indexPattern;
this.playCallback = playCallback;
this.initialLoad = initialLoad;
this.delay = delay;
this.blockDuration = blockDuration;
this.size = size;
this.blocks = [];
}
ESPlayer.prototype = {
start: function () {
this.runLoader();
this.runPlayer();
},
runLoader: function () {
if (this.blocks.length === 0) {
this.loadInitial();
} else {
let lastBlockAge = new Date().getTime() - this.lastBlockStart()
if (lastBlockAge > (this.blockDuration + this.delay) * 1000) {
this.loadNext();
} else {
let player = this;
setTimeout(function () {
player.runLoader();
}, 1000);
}
}
},
lastBlockStart: function () {
return this.blocks[this.blocks.length - 1].key;
},
req: function (body, callback) {
let player = this;
let request = new XMLHttpRequest();
request.open('POST', '/' + this.server + '/' + this.indexPattern + '/_search', true);
request.onload = function () {
if (this.status >= 200 && this.status < 400) {
callback(JSON.parse(this.response));
} else {
console.error(this.response);
}
};
request.onerror = function () {
console.error("Connection error to " + player.server);
};
request.setRequestHeader('Content-Type', 'application/json');
request.send(JSON.stringify(body));
},
loadInitial: function () {
console.log("loading initial");
let player = this;
this.req({
size: 0,
query: {
bool: {
filter: [
{range: {'@timestamp': {gte: "now-" + this.initialLoad + "s"}}},
{range: {'@timestamp': {lt: "now-" + this.delay + "s"}}}
]
}
},
aggs: {
blocks: {
date_histogram: {
field: "@timestamp",
fixed_interval: this.blockDuration + "s",
},
aggs: {
docs: {
top_hits: {size: this.size}
}
}
}
}
}, function (data) {
let blocks = data.aggregations.blocks.buckets;
blocks.pop();
player.blocks = blocks.map(function (block) {
return {
key: block.key,
events: block.docs.hits.hits.map(function (doc) {
return doc._source;
})
};
});
setTimeout(function () {
player.runLoader();
}, 1000);
});
},
loadNext: function () {
console.log("loading next");
let player = this;
let nextBlockStart = this.lastBlockStart() + this.blockDuration * 1000;
this.req({
size: this.size,
query: {
bool: {
filter: [
{
range: {
'@timestamp': {
gte: new Date(nextBlockStart).toISOString()
}
}
},
{
range: {
'@timestamp': {
lt: new Date(nextBlockStart + this.blockDuration * 1000).toISOString()
}
}
}
]
}
}
}, function (data) {
player.blocks.push(
{
key: nextBlockStart,
events: data.hits.hits.map(function (doc) {
return doc._source;
})
}
);
setTimeout(function () {
player.runLoader();
}, 1000);
});
},
runPlayer: function () {
let player = this;
let block = this.blocks.shift();
if (block) {
let start = block.key;
Tone.Transport.schedule(function (time) {
block.events.forEach(function (event) {
let eventTime = Date.parse(event['@timestamp']);
let delay = (eventTime - start) / 1000;
console.log(event);
player.playCallback(event, time + eventTime);
});
}, "1m");
}
setTimeout(function () {
player.runPlayer();
}, 1000);
}
};
window.onload = function () {
document.querySelector('tone-play-toggle').addEventListener('change', function () {
let synth = new Tone.Synth().toMaster();
let notePlayer = new ESPlayer('local', 'notes*', function (event, time) {
synth.triggerAttackRelease('D4', '8n', time);
});
notePlayer.start();
return false;
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment