From 34981d292fa22f4e80bb62cb60c381eac37c9a49 Mon Sep 17 00:00:00 2001 From: chuckdaniels Date: Mon, 5 Sep 2022 04:12:41 -0500 Subject: [PATCH] technically 1.0 --- alt.html | 32 ++++++ audiovis.js | 166 ++++++++++++++++++++++++++++ banner.png | Bin 0 -> 13797 bytes dir.png | Bin 0 -> 764 bytes index.html | 40 +++++++ radio.js | 310 ++++++++++++++++++++++++++++++++++++++++++++++++++++ style.css | 129 ++++++++++++++++++++++ url.png | Bin 0 -> 23940 bytes users.png | Bin 0 -> 798 bytes 9 files changed, 677 insertions(+) create mode 100644 alt.html create mode 100644 audiovis.js create mode 100644 banner.png create mode 100644 dir.png create mode 100644 index.html create mode 100644 radio.js create mode 100644 style.css create mode 100644 url.png create mode 100644 users.png diff --git a/alt.html b/alt.html new file mode 100644 index 0000000..20e9a21 --- /dev/null +++ b/alt.html @@ -0,0 +1,32 @@ + + + wormTuner + + + + + + + + + + +
+ +
+
+
+
+
+
+ +
+
+
+

Click on a station to tune in!

+
+ +
+
+ + diff --git a/audiovis.js b/audiovis.js new file mode 100644 index 0000000..01b7b29 --- /dev/null +++ b/audiovis.js @@ -0,0 +1,166 @@ +/* wormTune Audio Visualizer */ + +var modes = ["None", "Bars","Scope","Spectrogram","Laser Rain"]; +var drawRequest = 0; +var renderInverval; + +function createVisualizer(player, context) { + var audioSrc = context.createMediaElementSource(player); + analyser = context.createAnalyser(); + + var canvas = document.querySelector("canvas.vis"); + + audioSrc.connect(analyser); + analyser.connect(context.destination); + + setVisualizer(canvas, analyser, 0); + + return analyser; +}; + +function setVisualizer(canvas, analyser, mode = 0) { + if (!analyser) return; + clearInterval(renderInverval); + var ctx = canvas.getContext("2d",{antialias: false,alpha: false}); + + var WIDTH = canvas.width; + var HEIGHT = canvas.height; + + // Set the "defaults" + analyser.smoothingTimeConstant = 0.8; + analyser.fftSize = 2048; + + if (mode != -1) canvas.height = 96; + + window.cancelAnimationFrame(drawRequest); + if (mode == -1) { // VIDEO MODE + canvas.height = canvas.width / 4 * 3; + renderInverval = window.setInterval(() => { + ctx.drawImage(audioPlayer, 0, 0, WIDTH, HEIGHT); + }, 1000 / 24); + } else if (mode == 0 || mode > modes.length - 1) { + function draw() { + drawRequest = window.requestAnimationFrame(draw); + + ctx.clearRect(0,0,WIDTH,HEIGHT); + + ctx.font = "16px Pixio"; + ctx.fillStyle = "#FFF"; + ctx.textAlign = "center"; + ctx.fillText("Click here to cycle visualizations.", WIDTH/2,HEIGHT/2); + } + draw(); + } else if (mode == 1) { // BAR + analyser.fftSize = 256; + var bufferLength = analyser.frequencyBinCount; + var dataArray = new Uint8Array(bufferLength) + + var barWidth = (WIDTH / bufferLength) * 2.5; + var barHeight; + + function draw() { + ctx.clearRect(0, 0, WIDTH, HEIGHT); + drawRequest = window.requestAnimationFrame(draw); + + analyser.getByteFrequencyData(dataArray); + ctx.fillStyle = "#FFF"; + + var x = 0; + + ctx.beginPath(); + for (var i = 0; i < bufferLength; i++) { + barHeight = (dataArray[i] / 256) * HEIGHT; + ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight); + x += barWidth + 1; + } + ctx.closePath(); + } + draw(); + } else if (mode == 2) { // SCOPE + analyser.smoothingTimeConstant = 0; + var dataArray = new Uint8Array(analyser.fftSize) + + function draw() { + ctx.clearRect(0, 0, WIDTH, HEIGHT); + drawRequest = window.requestAnimationFrame(draw); + + analyser.getByteTimeDomainData(dataArray); + const step = WIDTH / dataArray.length; + + ctx.strokeStyle = "#0F0"; + + ctx.beginPath(); + for (let i = 0; i < dataArray.length; i += 2) { + const percent = dataArray[i] / 256; + const x = i * step; + const y = HEIGHT * percent; + ctx.lineTo(x, y); + } + ctx.stroke(); + } + draw(); + } else if (mode == 3) { // SPECTROGRAM + analyser.smoothingTimeConstant = 0; + + var tempCanvas = document.createElement("canvas"), + tempCtx = tempCanvas.getContext("2d"); + tempCanvas.width = WIDTH; + tempCanvas.height = HEIGHT; + + analyser.fftSize = Math.pow(2, Math.ceil(Math.log(WIDTH)/Math.log(2))); + + var bufferLength = analyser.frequencyBinCount; + var dataArray = new Uint8Array(bufferLength); + + var start = new Date(); + //ctx.clearRect(0,0,WIDTH,HEIGHT); + function draw() { + drawRequest = window.requestAnimationFrame(draw); + + analyser.getByteFrequencyData(dataArray); + var barHeight = WIDTH/analyser.fftSize; + + var now = new Date(); + if (now < new Date(start.getTime() + 20)) { return; } + start = now; + + tempCtx.drawImage(ctx.canvas, 0, 0, WIDTH, HEIGHT); + + for (var i = 0; i < dataArray.length; i++) { + var value = dataArray[i]; + ctx.fillStyle = 'rgb('+((value > 190) ? 255 : value)+', '+ ((value > 220) ? 255 : value-100) +', 0)'; + ctx.fillRect(WIDTH - 1, HEIGHT - i*barHeight, 1, barHeight); + } + ctx.translate(-1, 0); + ctx.drawImage(tempCanvas, 0, 0, WIDTH, HEIGHT, 0, 0, WIDTH, HEIGHT); + ctx.setTransform(1, 0, 0, 1, 0, 0); + } + draw(); + } else if (mode == 4) { // RUNWAY + analyser.smoothingTimeConstant = 0.2; + + var bufferLength = analyser.frequencyBinCount; + var dataArray = new Uint8Array(bufferLength); + + //ctx.clearRect(0,0,WIDTH,HEIGHT); + function draw() { + drawRequest = window.requestAnimationFrame(draw); + + analyser.getByteFrequencyData(dataArray); + + ctx.clearRect(0,0,WIDTH,HEIGHT); + for (var i = 0; i < dataArray.length; i++) { + if (dataArray[i] == 0) continue; + ctx.fillStyle = 'rgb('+dataArray[i]/4+','+dataArray[i]/2+','+dataArray[i]+')'; + ctx.fillRect((WIDTH / 2)+i, 0, 1, HEIGHT); + ctx.fillRect((WIDTH / 2)-(i+1), 0, 1, HEIGHT); + } + // You are probably wondering how I got here, huh? Questioning my very sanity. Or maybe you completely understand, and as a web-developer, very well know the experience of bending the knees for Chrome in order to get something working that already works everywhere else. Since I've explained it, I think regardless, you understand now. + ctx.font = "16px Pixio"; + ctx.fillStyle = "#4080FF0A"; + ctx.textAlign = "center"; + ctx.fillText("0x4655434B204348524F4D45",WIDTH/2,HEIGHT/2); + } + draw(); + } +} diff --git a/banner.png b/banner.png new file mode 100644 index 0000000000000000000000000000000000000000..5bb052a8b8d1ceb5955126d86ae4eddfe6cf393a GIT binary patch literal 13797 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 F{V(0-CKUhx literal 0 HcmV?d00001 diff --git a/dir.png b/dir.png new file mode 100644 index 0000000000000000000000000000000000000000..6d3e8bd0c9e7f754349c0a97f0a7f8fb0e6495b8 GIT binary patch literal 764 zcmVOB0004nX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmKpe$iQ%kE<9IPPX5TrU;5EXIMDionYs1;guFuC+YXws0h zxHt-~1qVMCs}3&Cx;nTDg5U>;qmz@Oi!ES_(b9vW|$S?b>gYb ziotoGIKqmuN_z1bM0hc>K|C1q`vLpFv3i&+nen#Jv1$u9Ru2r|U<~~jzfHZZLya5gl zfsq1buX(&X)ZW{_XPW)}055iOj9huN#sB~S32;bRa{vG?BLDy{BLR4&KXw2B00(qQ zO+^Rh2?Yo_6S6K{pa1{>8FWQhbVF}#ZDnqB07G(RVRU6=Aa`kWXdp*PO;A^X4i^9b z02NS7R7C&)00000yKVsfmjM2(GylC~|Ns9>;JDTR0007XQchC zL0x=8*;0WT{2e>z)dnYg#&;w+X3n=9NM{qH1Y&r?J z()l-`AAvR{0FNdNHEU`j#&^foPL3sEj#(1sm?dG3SrX=$C1H+P66Tnt + + wormTuner + + + + + + + + + + + +
+ +
+
+
+
+
+
+ + Test + +
+ +
+ +
+
+
+
+

Click on a station to tune in! If you are having trouble, try the Alternate player.

+
+ +
+
+ + diff --git a/radio.js b/radio.js new file mode 100644 index 0000000..d89002f --- /dev/null +++ b/radio.js @@ -0,0 +1,310 @@ +/* == wormTuner == */ +/* The Icecast Radio JS Tuner */ + +const nameJs = "wormTuner"; +const version = "0.3.1"; + +const statusJson = "/status-json.xsl"; + +// 'mimetype': 'icon-path' +const mimeIcons = { +// 'audio/aac':'/mime/aac.png', +}; + +const options = { + 'json-timer': 2500, // Time (in ms) for each stream update + 'visualizers': true, // whether to support visualizers + 'video-support': true, // whether to support video streams + 'character-overflow': 38, // character count needed to put in marquee. + 'replace-url': false, // fellow lazies please stand up + 'url-replacement': ['',''], + 'crossorigin': true +}; + +var ajax = new XMLHttpRequest(); +var sources = []; + +var isFancy = true; +var castContainer; +var currentStation = ""; + +var audioPlayer = document.createElement('video'); +var audioContext; +var audioAnalyser; +var visualizer; +var visMode = 0; + +var videoMode = false; + +// Timers +var volTimer; +var visTimer; + +function updateJSON() { + ajax.open('GET', statusJson, true); + ajax.send(); +} + +function processListenURL(url) { + if (!options['replace-url'] || !url) return url; + // Add Date.now() to prevent browser caching. Cache-Control isn't reliable IME + return url.replace(options['url-replacement'][0], options['url-replacement'][1])+"?"+Date.now(); +} + +function setSource(source) { + if (!source) return; + currentStation = source.listenurl.substr(23); + window.location.hash = "#"+currentStation; + + if (options['video-support'] && source.server_type.substr(0, source.server_type.indexOf('/')) == 'video') { + visMode = -1; + } else if (visMode < 0) visMode = 0; + + audioPlayer.src = processListenURL(source.listenurl); + audioPlayer.type = source.server_type; + + if (isFancy) { + if (!audioContext || !audioAnalyser) { + audioContext = new AudioContext(); + audioAnalyser = createVisualizer(audioPlayer, audioContext); + } + setVisualizer(visualizer, audioAnalyser, visMode); + } else audioPlayer = document.querySelector("video"); + + audioPlayer.play(); + document.body.scrollTop = 0; + updateJSON(); +} + +function handleVolume(event) { + event.preventDefault(); + var volMeter = document.querySelector('.vol'); + volMeter.classList.remove('hidden'); + var volInc = 0.05; + + if (event.deltaY < 0) { + if (audioPlayer.volume+volInc > 1) audioPlayer.volume=1; + else audioPlayer.volume+=volInc; + } + else if (event.deltaY > 0) { + if (audioPlayer.volume-volInc < 0) audioPlayer.volume=0; + else audioPlayer.volume-=volInc; + } + + volMeter.innerText = "VOL ["+'='.repeat(((audioPlayer.volume / 1) * 20)).padEnd(20, ' ') + "] "+(Math.round(audioPlayer.volume * 100)+'').padStart(3, ' ')+"%"; + + window.clearTimeout(volTimer) + volTimer = setTimeout(function(){ + volMeter.classList.add('hidden'); + }, 5000); +} + +function switchMode() { + if (videoMode) return; + if (!isFancy) return; + if (visMode == modes.length - 1) // - 1 if we count empty. + visMode = 0; + else visMode++; + + var visCounter = document.querySelector('.vismode'); + visCounter.classList.remove('hidden'); + + visCounter.innerText = modes[visMode]+' '+visMode+'/'+(modes.length - 1); + + setVisualizer(visualizer, audioAnalyser, visMode); + + window.clearTimeout(visTimer) + visTimer = setTimeout(function(){ + visCounter.classList.add('hidden'); + }, 5000); + + audioPlayer.play(); +} + +function newEntry(source, i) { + var entryContainer = document.createElement('div'); + entryContainer.classList.add('station'); + + entryContainer.name = source.listenurl.substr(23); + + var titlebar = document.createElement('div'), + infoBar = document.createElement('div'), + descBox = document.createElement('div'); + + titlebar.classList.add('titlebar'); + infoBar.classList.add('infobar'); + descBox.classList.add('descbox'); + + var titleTxt = document.createElement('b'), + listenerBox = document.createElement('div'); + + titleTxt.innerText = source.server_name; + titlebar.appendChild(titleTxt); + + var stationLineHeight = 24; + var grower = document.createElement('div'); + grower.style.flexGrow = "1"; + titlebar.appendChild(grower); + + var listenerImg = document.createElement('img'), + listenerTxt = document.createElement('a'); + + + listenerImg.src = "users.png"; + listenerImg.width = listenerImg.height = stationLineHeight; + listenerTxt.innerText = source.listeners; + + listenerBox.title = source.listeners+" listener"+(source.listeners != 1 ? 's' : '')+" (peak "+source.listener_peak+")"; + listenerBox.appendChild(listenerImg); + listenerBox.appendChild(listenerTxt); + titlebar.appendChild(listenerBox); + + entryContainer.appendChild(titlebar); + + entryContainer.appendChild(document.createElement('hr')); + + var bitrateTxt = document.createElement('a'), + urlTxt = document.createElement('a'), + urlImg = document.createElement('img'), + dirTxt = document.createElement('a'), + dirImg = document.createElement('img'); + + bitrateTxt.classList.add('bitrate'); + listenerBox.classList.add('listeners'); + + if (mimeIcons[source.server_type]) { + var formatImg = document.createElement('img'); + formatImg.classList.add('format'); + formatImg.height = stationLineHeight; + formatImg.alt = formatImg.title = source.server_type.substr(source.server_type.indexOf('/') + 1); + formatImg.src = mimeIcons[source.server_type]; + infoBar.appendChild(formatImg); + } else { + var formatTxt = document.createElement('a'); + formatTxt.classList.add('format'); + formatTxt.innerText = formatTxt.title = source.server_type.substr(source.server_type.indexOf('/') + 1).toUpperCase(); + infoBar.appendChild(formatTxt); + } + + var btr = source.bitrate; + if (!source.bitrate && source.audio_bitrate) btr = source.audio_bitrate / 1000; + else if (!source.audio_bitrate && !source.bitrate) btr = "???"; + bitrateTxt.innerHTML = btr + "kbps"; + infoBar.appendChild(bitrateTxt); + + if (source.server_url) { + urlTxt.href = source.server_url; + urlTxt.target = "_blank"; + urlImg.src = "url.png"; + urlImg.height = stationLineHeight; + urlTxt.appendChild(urlImg); + infoBar.appendChild(urlTxt); + } + + dirTxt.href = processListenURL(source.listenurl); + dirTxt.target = "_blank"; + dirImg.src = "dir.png"; + dirImg.height = stationLineHeight; + dirTxt.appendChild(dirImg); + infoBar.appendChild(dirTxt); + + entryContainer.appendChild(infoBar); + + var descTxt = document.createElement('p'); + descTxt.innerHTML = source.server_description + " (Genre: "+source.genre+")"; + descBox.appendChild(descTxt); + + entryContainer.appendChild(descBox); + + if (source.listenurl.substr(23) == currentStation) entryContainer.classList.add("selected"); + entryContainer.onclick = function() { + setSource(sources[i]); + this.classList.add("selected"); + } + + return entryContainer; +} + +function setMaybeOverflow(elem, txt) { + if (!txt) return; + var limit = options['character-overflow']; + if (elem.innerText == txt) return; + if (txt.length > limit) + elem.innerHTML = ""+txt+""; + else if (txt.length <= limit) + elem.innerHTML = txt; + +} + +function updateStreamInfo(source) { + var stationName = document.querySelector(".textainer .station"), + title = document.querySelector(".textainer .track"), + genre = document.querySelector(".textainer .genre"); + if (source) { + setMaybeOverflow(stationName,source.server_name); + if (source.artist) + setMaybeOverflow(title,source.artist+" - "+source.title); + else + setMaybeOverflow(title,source.title); + setMaybeOverflow(genre,source.genre); + } else stationName.innerText = title.innerText = genre.innerText = ""; +} + +ajax.onload = function() { + // Clear Container for new stuff. + while(castContainer.childElementCount > 0) { + castContainer.removeChild(castContainer.lastChild); + } + + if (ajax.status == 200) { // OK + if (ajax.response.icestats.source) { + if (ajax.response.icestats.source.length > 0) sources = ajax.response.icestats.source; + else sources = [ ajax.response.icestats.source ]; + } else sources = []; + var index = -1; + for (let i = 0; i < sources.length; i++) { + castContainer.appendChild(newEntry(sources[i], i)); + if (sources[i].listenurl.substr(23) == currentStation) index = i; + } + if (index != -1) updateStreamInfo(sources[index]); + if (audioPlayer.paused && currentStation.length > 0) + setSource(sources[index]); + } +} + +window.addEventListener('DOMContentLoaded', (event) => { + castContainer = document.querySelector(".broadcasts"); + ajax.responseType = 'json'; + updateJSON(); + + visualizer = document.querySelector('canvas.vis'); + isFancy = isFancy && (visualizer != null); + + // Detect Visualizer and initialize events + if (isFancy) { + visualizer.addEventListener('click', (event) => { + switchMode(); + }); + visualizer.addEventListener('wheel', handleVolume); + } + + // #my-stream.ogg -> listenurl: /my-stream.ogg + if (window.location.hash.length > 2) currentStation = window.location.hash.substr(1); + + // Handle name and versioning + var _nameElem = document.querySelector('.about .name'); + if (_nameElem) _nameElem.innerText = nameJs; + var _versElem = document.querySelector('.about .vers'); + if (_versElem) _versElem.innerText = 'v'+version; + + setInterval(function() { + updateJSON(); + }, options['json-timer']); + + if (options['crossorigin']) audioPlayer.setAttribute('crossorigin','anonymous'); + audioPlayer.onended = function () { + currentStation = ""; + console.log("Stream over"); + updateStreamInfo(null); + }; +}); diff --git a/style.css b/style.css new file mode 100644 index 0000000..c616d95 --- /dev/null +++ b/style.css @@ -0,0 +1,129 @@ +:root { + --background: #b3a99e; + --primary: #f3dca9; + --border: #f2e5c8; + + --station-primary: #d0d0d0; + --station-border: #a4a4a4; + + --station-selected: #d0dadf; + --station-selected-border: #0088ff; + + --about-color: #b9a77f; + --about-indent: #000000AA; +} + +body { + background: var(--background); + background-repeat: repeat; +} + +canvas.vis { + border: 2px inset var(--border); + background: black; + margin: 4px; +} + +.player { + background: var(--primary); + border: 2px outset var(--border); + width: 384px; +} + +.textainer { + display: flex; + flex-direction:column; + line-height: 24px; + text-align: left; + flex-grow: 1; + padding: 2px; + overflow: hidden; + text-align: center; +} +.textainer .station { font-weight: bold; } +.textainer .genre { font-style: italic; display: none; } +.textainer > div { white-space: nowrap; } +.textainer > div.overflow { + -moz-animation: scroll-left 2s linear infinite; + -webkit-animation: scroll-left 2s linear infinite; + animation: scroll-left 20s linear infinite; +} + +.section { + display: flex; + flex-direction: column; +} + +.broadcasts .station { + background: var(--station-primary); + color: black; + border: 1px outset var(--station-border); + padding: 4px; + margin: 16px; + text-align: left; + cursor: pointer; + width: 360px; + display: inline-block; + vertical-align:top; +} + +.broadcasts .station.selected { + outline: 2px solid var(--station-selected-border); + background: var(--station-selected); +} + +.broadcasts .station hr { + margin: 2px 0px; + border: 1px solid #a4a4a4; + width: 100%; +} + +.titlebar { + display: flex; +} + +.infobar { + display: flex; + gap: 8px; +} + +.broadcasts .station .listeners img { + margin-right: 2px; +} + +.list { + flex-grow: 1; +} + +.vol, +.vismode { + pointer-events: none; + position: relative; + height: 0; + text-shadow: 0px 0px 5px black; + color: white; +} + +.vol { + top: -32px; + white-space: pre; +} + +.vismode { + top: 8px; + text-align: right; + right: 16px; +} + +.vol.hidden, +.vismode.hidden { + display: none; +} + +.about { + display: flex; + margin: -8px 0px 0px 0px; + text-shadow: -1px -1px 0px var(--about-indent); + padding: 4px 8px; +} +.about, .about a, .about a:link, .about:visited {color: var(--about-color);text-decoration: none;} diff --git a/url.png b/url.png new file mode 100644 index 0000000000000000000000000000000000000000..bfc1b9d293cfcb17fd858cbb0bc053237b860714 GIT binary patch literal 23940 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