Skip to content

Instantly share code, notes, and snippets.

@hos
Created October 28, 2019 08:30
Show Gist options
  • Save hos/f42349e00c0ac7872ef10fe0acb26c39 to your computer and use it in GitHub Desktop.
Save hos/f42349e00c0ac7872ef10fe0acb26c39 to your computer and use it in GitHub Desktop.
Player for Bohemnots Radio
const trackNameUpdateInterval = 1000
const retryInterval = 500
const streamUrl = 'https://bhmnts.out.airtime.pro/bhmnts_a'
const metaUrl = 'https://bohem.herokuapp.com/metadata'
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
)
const audio = new Audio(streamUrl)
const script = document.scripts[document.scripts.length - 1]
const origin = new URL(script.src).origin
const playIcon = new URL('img/play.png', origin)
const pauseIcon = new URL('img/pause.png', origin)
const node = document.createElement('div')
node.innerHTML = generateCss() + generateHtml(playIcon)
script.parentElement.insertBefore(node, script)
const actionBtn = document.getElementById('action-btn')
const actionIcon = document.getElementById('action-img')
const metaTrackTitle = document.getElementById('meta-track-title')
const metaLocation = document.getElementById('meta-location')
function generateCss () {
return `
<style>
#action-btn::after { content: ""; margin-right: 5px; }
</style>
`
}
function generateHtml (actionIcon) {
return `
<div style="height: '30px'; width: '30px'; vertical-align: text-bottom;">
<a id="action-btn">
<img id="action-img" style="height: 30px; width: 30px; vertical-align: inherit;" src="${actionIcon}">
</a>
<div id="bh-status" style="display: inline-block;">
<div id="player-meta" style="display: inline-block;">
<div id="meta-track-title" style="font-size: 12px;"></div>
<div id="meta-location" style="color: #999;"></div>
<div id="custom-text" style="color: #999;"></div>
</div>
</div>
`
}
actionBtn.addEventListener('click', () => {
if (audio.paused) {
play()
} else {
pause()
}
})
play()
metaUpdate()
const actionIconPause = () => (actionIcon.src = pauseIcon)
const actionIconPlay = () => (actionIcon.src = playIcon)
function pause () {
audio.pause()
actionIconPlay()
}
async function play () {
window.focus()
try {
await audio.play()
actionIconPause()
} catch (err) {
if (err.name !== 'NotAllowedError') {
actionIconPlay()
setTimeout(play, retryInterval)
}
}
}
async function metaUpdate () {
try {
const responseMeta = await fetch(metaUrl)
const meta = await responseMeta.json()
const name = meta.customName || meta.trackName || ''
metaTrackTitle.innerText = name
if (!isMobile) {
document.title = name
}
metaLocation.innerText = meta.location || ''
} catch (err) {
metaTrackTitle.innerText = '!!!offline'
} finally {
setTimeout(metaUpdate, trackNameUpdateInterval)
}
}
window.ononline = function () {
play()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment