Skip to content

Instantly share code, notes, and snippets.

@ZiTAL
Last active October 2, 2025 07:18
Show Gist options
  • Select an option

  • Save ZiTAL/5ca5519c6666cfa709ef0cde8a297b51 to your computer and use it in GitHub Desktop.

Select an option

Save ZiTAL/5ca5519c6666cfa709ef0cde8a297b51 to your computer and use it in GitHub Desktop.
itsuki irratia zuzenean:
<!DOCTYPE html>
<head>
<title>Itsuki irratia zuzenean</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {
overflow: hidden;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
iframe {
max-width: 100%;
}
.itsuki-player {
--maxw: 520px;
display: grid;
justify-items: center;
gap: 12px;
margin: 0 auto;
width: min(100%, var(--maxw));
background: transparent;
font-family: Helvetica, Arial, sans-serif;
/* Helvetica Regular */
font-weight: 400;
font-style: normal;
font-synthesis-weight: none;
color: inherit;
text-align: center;
}
.itsuki-ctrl {
width: 100%;
border-radius: 12px;
overflow: hidden;
outline: none;
}
.itsuki-ctrl:focus-visible {
outline: 3px solid currentColor;
outline-offset: 4px;
border-radius: 12px;
}
.itsuki-fallback {
margin: 4px 0 0;
font-size: clamp(0.75rem, 1.6vw, 0.85rem);
line-height: 1.3;
letter-spacing: 0.01em;
opacity: 0.9;
color: #fff;
}
.itsuki-fallback a {
color: inherit;
text-decoration: underline;
text-underline-offset: 3px;
}
.itsuki-listeners {
margin: 6px auto 0;
width: min(100%, 520px);
text-align: center;
font-size: clamp(0.75rem, 1.6vw, 0.85rem);
line-height: 1.3;
opacity: 0.85;
color: #fff;
}
.itsuki-listeners-online {
font-variant-numeric: tabular-nums;
font-weight: 600;
padding-left: .25em;
}
@media (max-width: 480px) {
.itsuki-fallback,
.itsuki-listeners {
font-size: 0.72rem;
line-height: 1.25;
}
}
@media (max-width: 360px) {
.itsuki-fallback,
.itsuki-listeners {
font-size: 0.68rem;
}
}
</style>
</head>
<body>
<section class="itsuki-player" role="region" aria-label="Itsuki irratia zuzenean">
<audio class="itsuki-ctrl" controls="" preload="auto" aria-label="Itsuki irratia zuzenean">
<source src="https://irratia.itsuki.freemyip.com/itsuki.opus" type='audio/ogg; codecs="opus"'>
<source src="https://irratia.itsuki.freemyip.com/itsuki.aac" type="audio/aac">
Zure nabigatzaileak ez du audioa onartzen.
</audio>
<p class="itsuki-fallback">
<br>
Arazoak badituzu, saiatu hemen:
<br>
<br>
<a href="https://irratia.itsuki.freemyip.com/itsuki.aac" target="_blank" rel="noopener">AAC formatuan (IPHONE)</a>
<br>
<br>
<a href="https://irratia.itsuki.freemyip.com/itsuki.opus" target="_blank" rel="noopener">OPUS formatuan (ANDROID)</a>
<br>
</p>
</section>
<p></p>
<p class="itsuki-listeners">
<br>
<span>Entzuleak online:</span>
<span class="itsuki-listeners-online" aria-live="polite"></span>
<br>
</p>
<script>
const heightObserver = new ResizeObserver(([{ contentRect }]) => {
window.parent.postMessage({ action: 'iframeHeightUpdated', height: contentRect.height, id: 'zXXs5n' }, '*');
});
heightObserver.observe(document.documentElement);
</script>
<script>
(function () {
const ilo = document.querySelector('span.itsuki-listeners-online');
function empty(node) {
if (!node) return;
while (node.firstChild) node.removeChild(node.firstChild);
}
function listenersOnline() {
const url = 'https://irratia.itsuki.freemyip.com/custom/listeners-online.json';
fetch(url)
.then(response => {
if (!response.ok) throw new Error("listeners-online error: " + response.statusText);
return response.json();
})
.then(data => {
empty(ilo);
if (ilo) ilo.appendChild(document.createTextNode(String(data['listeners-online'])));
})
.catch(error => {
console.error("listeners-online error:", error);
});
}
function canPlayOpus(audio) {
return audio && audio.canPlayType && (audio.canPlayType('audio/ogg; codecs="opus"') === "probably" || audio.canPlayType('audio/webm; codecs="opus"') === "probably");
}
function removeOpus(audio) {
audio.querySelectorAll('source').forEach(function (s) {
if (s.src.match(/\.opus$/))
removeItem(s);
})
}
function removeItem(item) {
if (item && item.parentNode) item.parentNode.removeChild(item);
}
function prepareAudio() {
const audio = document.querySelector('audio');
if (!audio) return;
if (!canPlayOpus(audio)) {
removeOpus(audio);
audio.load();
}
}
prepareAudio();
listenersOnline();
window.setInterval(listenersOnline, 60 * 1000);
})();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment