var selected = "";
var shows = [];
function update(first) {
var first = first || false;
var req = new XMLHttpRequest();
var url = "https://bienvenidoainternet.org:8443";
req.open("GET", url+"/status-json.xsl", true);
req.send();
req.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
var resp = JSON.parse(req.response);
var status = document.getElementById("status");
var artist = document.getElementById("artist");
var title = document.getElementById("title");
var bitrate = document.getElementById("bitrate");
var audio_samplerate = document.getElementById("audio_samplerate");
var listeners = document.getElementById("listeners");
if (resp.icestats.source) {
resp = resp.icestats.source;
} else {
artist.textContent = "";
title.textContent = "";
bitrate.textContent = "--";
audio_samplerate.textContent = "--";
listeners.textContent = "0";
status.textContent = "*** La radio está OFFLINE ***";
var o = document.createElement("option");
o.textContent = "Nadie está transmitiendo...";
sel.appendChild(o);
selected = "";
return;
}
if (!resp.length) { resp = [resp]; }
if (first || !selected) {
status.textContent = "";
selected = resp[0].listenurl.replace("http://bienvenidoainternet.org:8000", "");
}
var sel = document.getElementById("server_name");
sel.textContent = "";
var selectedPos = 0;
var currentShows = [];
for (var i = -1; ++i < resp.length;) {
var o = document.createElement("option");
resp[i].listenurl = resp[i].listenurl.replace("http://bienvenidoainternet.org:8000", "");
o.value = resp[i].listenurl;
if (checkNew(resp[i].listenurl) && !first) {
addMsg("Ha comenzado una nueva transmisión: " + resp[i].server_name);
}
currentShows.push(resp[i].listenurl);
o.textContent = resp[i].server_name;
if (resp[i].server_description) {
o.textContent += ": " + resp[i].server_description;
}
if (resp[i].listenurl == selected) {
o.defaultSelected = true;
selectedPos = i;
}
sel.appendChild(o);
}
resp = resp[selectedPos];
shows = currentShows;
var currentListen = document.getElementById("current_server");
currentListen.value = resp.server_name;
var audio = document.getElementById("stream");
resp.listenurl = "https://bienvenidoainternet.org:8443" + resp.listenurl;
if (audio.src != resp.listenurl) {
audio.src = resp.listenurl;
if (!first) { playPause(); }
if (document.getElementById("chat-filter")) { filterChat(true); }
}
var currentSong = artist.textContent + title.textContent;
if (resp.artist) {
resp.artist = resp.artist.trim();
if (artist.textContent.slice(0,-3) != resp.artist) {
artist.textContent = resp.artist + " - ";
}
} else {
artist.textContent = "";
}
if (resp.title) {
resp.title = String(resp.title).trim();
} else {
resp.title = "(Sin título)";
}
if (title.textContent != resp.title) {
var history = document.getElementById("history");
history.innerHTML += '<div class="pastsong">' + currentSong + '</div>';
history.scrollTop = history.scrollHeight;
title.textContent = resp.title;
document.title = resp.title + " @ Radio B.a.I.";
checkLong();
}
if (resp["ice-bitrate"] && bitrate.textContent != resp["ice-bitrate"]) {
bitrate.textContent = resp["ice-bitrate"];
}
if (resp.audio_samplerate) {
var khz = Math.round(resp.audio_samplerate / 1000);
if (audio_samplerate.textContent != khz) {
audio_samplerate.textContent = khz;
}
}
if (resp.listeners && listeners.textContent != resp.listeners) {
listeners.textContent = resp.listeners;
}
}
}
}
function checkNew(mount) {
var isNew = true;
for (var i = -1; ++i < shows.length;) {
if (mount == shows[i]) {
isNew = false;
break;
}
}
if (isNew) { shows.push(mount); }
return isNew;
}
function startVisualization() {
var ctx = new AudioContext();
var audio = document.getElementById("stream");
var src = ctx.createMediaElementSource(audio);
var anal = ctx.createAnalyser();
src.connect(anal);
src.connect(ctx.destination);
var freq = new Uint8Array(anal.frequencyBinCount);
function renderVis() {
requestAnimationFrame(renderVis);
anal.getByteFrequencyData(freq);
var vis = document.getElementById("vis");
vis.textContent = "";
var div = 3;
var svgns = "http://www.w3.org/2000/svg";
for (var i = 0; i < 900; i += 20) {
var h = (freq[i] / div);
var rect = document.createElementNS(svgns, "rect");
rect.setAttributeNS(null, "x", (i / 10));
rect.setAttributeNS(null, "y", ((255 / div) - h));
rect.setAttributeNS(null, "height", h);
rect.setAttributeNS(null, "width", "1");
rect.setAttributeNS(null, "class", "bar");
vis.appendChild(rect);
}
}
renderVis();
}
function checkLong() {
var cont = document.getElementById("nowplaying");
var strip = document.getElementById("nowplaying-txt");
var marquee = document.getElementById("marquee-style");
if (marquee) { marquee.parentElement.removeChild(marquee); }
var ws = strip.clientWidth;
var wc = cont.clientWidth
if (ws > wc) {
var travel = ws - (wc-10);
var style = document.createElement("style");
style.id = "marquee-style";
var dur = Math.round(travel/10);
if (dur < 3) { dur++; }
style.textContent = "#nowplaying-txt {\n -webkit-animation: marquee " + dur + "s linear infinite;\n animation: marquee " + dur + "s linear infinite;\n}\n";
style.textContent += "@-webkit-keyframes marquee {\n 10% { transform: translateX(0); }\n 45% { transform: translateX(-" + travel + "px); }\n 55% { transform: translateX(-" + travel + "px); }\n 90% { transform: translateX(0); }\n}\n";
style.textContent += "@keyframes marquee {\n 10% { transform: translateX(0); }\n 45% { transform: translateX(-" + travel + "px); }\n 55% { transform: translateX(-" + travel + "px); }\n 90% { transform: translateX(0); }\n}";
document.getElementsByTagName("head")[0].appendChild(style);
}
}
function playPause() {
var radio = document.getElementById("stream");
var stat = document.getElementById("control");
if (radio.paused) {
radio.play();
stat.setAttribute("class", "playing");
} else {
radio.pause();
stat.setAttribute("class", "paused");
}
}
function changeVolume(e) {
var mousepos = e.x;
document.addEventListener("mousemove", setVolume);
document.addEventListener("mouseup", function() {
document.removeEventListener("mousemove", setVolume);
});
function setVolume(e) {
var audio = document.getElementById("stream");
var dx = mousepos - e.x;
mousepos = e.x;
var vol = document.getElementById("volume");
var newvol = Math.round(parseInt(vol.textContent) + (dx * -1));
if (newvol < 0) { newvol = 0; }
else if (newvol > 100) { newvol = 100; }
vol.textContent = (newvol < 10) ? ("0" + newvol) : newvol;
audio.volume = newvol / 100;
removeSel();
}
}
function collapsePanel(e) {
var box = this.parentElement.parentElement;
var cont = box.getElementsByClassName("content")[0];
if (box.classList.contains("collapse")) {
cont.removeAttribute("style");
box.classList.remove("collapse");
} else {
box.classList.add("collapse");
cont.style.width = (box.clientWidth - this.clientWidth - 14) + "px";
}
box.scrollTop = box.scrollHeight;
removeSel();
}
function resizePanel(e) {
var mousepos = e.y;
var id = this.dataset.id;
document.addEventListener("mousemove", calcResize);
document.addEventListener("mouseup", function() {
document.removeEventListener("mousemove", calcResize);
});
function calcResize(e) {
var chat = document.getElementById(id);
var dx = mousepos - e.y;
mousepos = e.y;
chat.style.height = (parseInt(getComputedStyle(chat, "").height) - dx) + "px";
chat.scrollTop = chat.scrollHeight;
removeSel();
}
}
function removeSel() {
if (document.selection) { document.selection.empty(); }
else { window.getSelection().removeAllRanges(); }
}
var chatConnected = false;
var antiFlood = false;
const chatFloodTime = 1100;
function connect() {
sock = new WebSocket("wss://radio.bienvenidoainternet.org/daemon/");
sock.addEventListener("open", function(e) {
chatConnected = true;
sock.send("HISTORY:10");
enableChat();
});
sock.addEventListener("message", function(e) {
interpretNewMsg(e.data);
});
sock.addEventListener("close", function(e) {
addMsg("Desconectado del chat. " + (e.reason ? "Razón: "+e.reason : "Código: "+e.code));
document.getElementById("chat-count").textContent = "";
chatConnected = false;
});
document.getElementById("msg_send").addEventListener("click", checkSend);
}
function enableChat() {
antiFlood = false;
document.getElementById("msg_send").disabled = false;
}
function interpretNewMsg(info) {
console.log("<<< " + info);
var arg = info.split(":");
if (arg[0] == "MSG") {
addMsg(unescapeColon(arg[2]), arg[1]);
} else if (arg[0] == "COUNT") {
document.getElementById("chat-count").textContent = arg[1];
} else if (arg[0] == "HMSG") {
addMsg(unescapeColon(arg[3]), unescapeColon(arg[2]), arg[1]);
} else if (arg[0] == "HISTORY_OK") {
addMsg("Conectado al chat.");
}
}
function checkSend(e) {
e.preventDefault();
if (!chatConnected) return;
if (antiFlood) return;
var msgField = document.getElementById("msg_type");
var msg = msgField.value.trim();
var show = document.getElementById("current_server").value;
if (!msg) { return; }
if (chatConnected) {
sendMsg("MSG:" + escapeColon(stream) + ":" + escapeColon(msg));
addMsg(msg, show, false, true);
} else { return; }
msgField.value = "";
antiFlood = true;
document.getElementById("msg_send").disabled = true;
setTimeout(enableChat, chatFloodTime);
}
function escapeColon(msg) {
return msg ? msg.replace(/:/g, "%3A") : "";
}
function unescapeColon(msg) {
return msg ? msg.replace(/%3A/g, ":") : "";
}
function sendMsg(msg) {
console.log(">>> " + msg);
sock.send(msg);
}
function addMsg(msg, stream, time, own) {
var time = time || false;
var stream = stream || false;
var own = own || false;
var chat = document.getElementById("chat-all");
var line = document.createElement("div");
line.className = (own ? "msg own" : (time ? "msg history" : "msg"));
var presentTime = (time ? new Date(Number(time)) : new Date());
var hh = presentTime.getHours();
hh = (hh < 10) ? ("0" + hh) : hh;
var mm = presentTime.getMinutes();
mm = (mm < 10) ? ("0" + mm) : mm;
line.textContent = "[" + hh + ":" + mm + "] ";
if (stream) {
line.textContent += "(" + stream + ") ";
line.dataset.stream = stream;
}
line.textContent += msg;
chat.appendChild(line);
chat.scrollTop = chat.scrollHeight;
}
function filterChat(enable) {
var filter = document.getElementById("chat-filter");
if (filter) { filter.parentElement.removeChild(filter); }
if (enable) {
var currentShow = document.getElementById("current_server").value;
var style = document.createElement("style");
style.id = "chat-filter";
style.textContent = '[data-stream] { display: none; }';
style.textContent += '[data-stream^="' + currentShow + '"] { display: block; }';
document.getElementsByTagName("head")[0].appendChild(style);
}
var chat = document.getElementById("chat-all");
chat.scrollTop = chat.scrollHeight;
}
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("control").addEventListener("click", playPause);
document.getElementById("volume").addEventListener("mousedown", changeVolume);
document.getElementById("server_name").addEventListener("change", function(e) {
selected = this.value;
});
var boxt = document.getElementsByClassName("boxtitle");
for (var i = -1; ++i < boxt.length;) {
boxt[i].addEventListener("click", collapsePanel);
}
var resize = document.getElementsByClassName("resize");
for (var i = -1; ++i < resize.length;) {
resize[i].addEventListener("mousedown", resizePanel);
}
document.getElementById("show_own").addEventListener("click", function(e) {
if (document.body.hasAttribute("class")) {
document.body.removeAttribute("class");
this.className = "btn toggle-off";
} else {
document.body.className = "show-own";
this.className = "btn toggle-on";
}
});
document.getElementById("stream_filter").addEventListener("click", function(e) {
if (document.getElementById("chat-filter")) {
filterChat(false);
this.className = "btn toggle-off";
} else {
filterChat(true);
this.className = "btn toggle-on";
}
});
document.getElementById("clear_chat").addEventListener("click", function(e) {
document.getElementById("chat-all").textContent = "";
});
update(true);
startVisualization();
setInterval(update, 2000);
connect();
});