188 lines
5.3 KiB
HTML
188 lines
5.3 KiB
HTML
<html>
|
|
<head>
|
|
<title>wormTuner Embed</title>
|
|
<link rel="icon" href="/favicon.png" type="image/png" sizes="128x128">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<script src="icecast-metadata-player-1.13.1.min.js"></script>
|
|
<script type="text/javascript">
|
|
var drawRequest = 0;
|
|
const settings = {
|
|
site: "https://example.com/",
|
|
icestats: "https://example.com/status-json.xsl"
|
|
};
|
|
const player = new IcecastMetadataPlayer(settings.site+'stream/'+window.location.search.substr(1)+"?"+Date.now(), {
|
|
onMetadata: (metadata) => {updateMetadata(metadata.StreamTitle);},
|
|
metadataTypes: ["icy"]
|
|
});;
|
|
var station = {};
|
|
var metacanvas = null;
|
|
|
|
function fixURL(url) {
|
|
return url.replace('http://example.com:8000/', '/stream/');
|
|
}
|
|
|
|
function play() {
|
|
player.play();
|
|
document.querySelector('.play').classList.add('active');
|
|
}
|
|
|
|
function stop() {
|
|
player.stop();
|
|
document.querySelector('.play').classList.remove('active');
|
|
}
|
|
|
|
function updateMetadata(track) {
|
|
var line_index = [0,0,0];
|
|
var startTimes = [new Date(),new Date(),new Date()];
|
|
var max_chars = 30;
|
|
function marqueeify(line, x, y, e) {
|
|
if (line.length >= max_chars) {
|
|
var txt = line.concat(' ').concat(line);
|
|
if (line_index[e] - 4 > line.length) {line_index[e] = 0;}
|
|
ctx.fillText(txt.substr(line_index[e],max_chars), x,y);
|
|
var now = new Date();
|
|
if (now >= new Date(startTimes[e].getTime() + 200)) {
|
|
startTimes[e] = now;
|
|
line_index[e]++;
|
|
}
|
|
} else ctx.fillText(line,x,y);
|
|
}
|
|
|
|
station.title = track;
|
|
if (metacanvas) {
|
|
var ctx = metacanvas.getContext("2d",{antialias: false,alpha: false});
|
|
|
|
var WIDTH = metacanvas.width;
|
|
var HEIGHT = metacanvas.height;
|
|
|
|
window.cancelAnimationFrame(drawRequest);
|
|
function drawMeta() {
|
|
drawRequest = window.requestAnimationFrame(drawMeta);
|
|
|
|
ctx.clearRect(0,0,WIDTH,HEIGHT);
|
|
if (station != null) {
|
|
ctx.font = "16px hack,monospace";
|
|
ctx.fillStyle = "#FFF";
|
|
ctx.textAlign = "justify";
|
|
|
|
ctx.font = "bold 16px hack,monospace";
|
|
marqueeify(station.server_name,8,20,0);
|
|
ctx.font = "16px hack,monospace";
|
|
marqueeify(track,8,38,1);
|
|
|
|
/*
|
|
let meta = [];
|
|
meta.push(station.server_type.substr(station.server_type.indexOf('/')+1).toUpperCase());
|
|
if (station.bitrate) meta.push(station.bitrate+"kbps");
|
|
else if (station.quality) meta.push(station.quality);
|
|
else meta.push('?kbps');
|
|
meta.push(station.channels+'ch');
|
|
meta.push((station.samplerate / 1000)+'khz');
|
|
meta.push(station.genre);
|
|
marqueeify(meta.join(' - '),8,56,2);
|
|
*/
|
|
marqueeify(station.genre,8,56,2);
|
|
}
|
|
}
|
|
drawMeta();
|
|
}
|
|
}
|
|
|
|
window.addEventListener('DOMContentLoaded', (event) => {
|
|
metacanvas = document.querySelector('canvas.metadata');
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.responseType = 'json';
|
|
xhr.onload = function() {
|
|
if (xhr.response) {
|
|
var stations = xhr.response.icestats.source;
|
|
for(let s = 0; s < stations.length; s++) {
|
|
if (fixURL(stations[s].listenurl) == '/stream/'+window.location.search.substr(1)) {
|
|
station = stations[s];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
xhr.open('GET', settings.icestats, true);
|
|
xhr.send();
|
|
});
|
|
|
|
function volChange(e) {
|
|
player.audioElement.volume=e.value/100;
|
|
e.parentNode.title = e.value+'%';
|
|
}
|
|
</script>
|
|
<style>
|
|
body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: #f3dca9;
|
|
border: 2px outset #f2e5c8;
|
|
margin: 0;
|
|
width: 308px;
|
|
height: 118px;
|
|
color: black;
|
|
}
|
|
|
|
*:link, *:visited {color:black;}
|
|
|
|
button, slider {
|
|
border: 2px outset #DFDFDF;
|
|
background: #DFDFDF;
|
|
}
|
|
slider input {
|
|
background: lightgray;
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
height: 4px;
|
|
margin: 6 2;
|
|
width: 96px;
|
|
}
|
|
|
|
controls {
|
|
display: flex;
|
|
}
|
|
|
|
slider input::-moz-range-thumb,
|
|
slider input::-webkit-slider-thumb {
|
|
background: gray;
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
width: 8px;
|
|
height: 16px;
|
|
border: none;
|
|
border-radius: 0;
|
|
}
|
|
|
|
button:active,
|
|
button.active {
|
|
border: 2px inset gray;
|
|
background: gray;
|
|
}
|
|
|
|
canvas {
|
|
color: #F0F0F0;
|
|
background: black;
|
|
border: 2px inset #f2e5c8;
|
|
}
|
|
|
|
center { margin: 4px; }
|
|
</style>
|
|
<meta property="og:site_name" content="wormTuner Embed">
|
|
<meta property="og:image" content="/favicon.png">
|
|
<meta property="og:title" content="wormTuner">
|
|
<meta property="og:description" content="Worm-crafted radio waves, straight to your computer!">
|
|
</head>
|
|
<body>
|
|
<center><a href='https://example.com/' target='_blank'>wormTuner</a></center>
|
|
<canvas width=304 height=66 class=metadata></canvas>
|
|
<controls>
|
|
<button title='Play' class='play' onclick='play()'><img src='play.png'></button>
|
|
<button title='Stop' onclick='stop()'><img src='stop.png'></button>
|
|
<div style='flex-grow:1;'></div>
|
|
<slider title='100%'><img src='vol.png'><input type=range min=0 max=100 value=100 step=5 oninput="volChange(this)"></slider>
|
|
</controls>
|
|
</body>
|
|
</html> |