Skip to content

Instantly share code, notes, and snippets.

@thlorenz
Last active April 12, 2025 11:57
Show Gist options
  • Select an option

  • Save thlorenz/73e3d1e91db9dc4f575c6de647eb01e0 to your computer and use it in GitHub Desktop.

Select an option

Save thlorenz/73e3d1e91db9dc4f575c6de647eb01e0 to your computer and use it in GitHub Desktop.
Get Di.fm and related stations playlist for all channels
// Run as a Chrome Snippetfrom either of the below urls:
// https://www.jazzradio.com/member/favorite/channels
// https://www.classicalradio.com/member/favorite/channels
// https://www.radiotunes.com/member/favorite/channels
// https://www.rockradio.com/member/favorite/channels
// https://www.zenradio.com/member/favorite/channels
const KEY = '<yourkeyhere>'
const subsidy = document.location.host.split('.')[1]
function getChannelInfos() {
const classes = document.getElementsByClassName('header-channel-nav__link')
const infos = []
for (let i = 0; i < classes.length; i++) {
const id = classes[i].href.split('/').pop()
const title = classes[i].innerText.trim()
infos.push({ id, title })
}
return infos
}
function channelInfoToPlaylistEntry(info, idx) {
const slot = idx + 1
return `File${slot}=https://listen.${subsidy}.com/premium_high/${info.id}.pls?${KEY}
Title${slot}=${info.title}
Length${slot}=0`
}
const channelInfos = getChannelInfos()
const entries = channelInfos.map(channelInfoToPlaylistEntry)
const playlist = `
[playlist]
NumberOfEntries=${entries.length}
${entries.join('\n')}
Version=2
`
copy(playlist)
// Run with Node.js and save output to playlist
const KEY = '<yourkeyhere>'
// --------------
// Data
// --------------
// From JSON response `currently playing` then modified via
// const channelIds = channels.map(x => x.channel_key)
const channelIds = [
'00sclubhits',
'ambient',
'atmosphericbreaks',
'bassnjackinhouse',
'bassline',
'bigbeat',
'bigroomhouse',
'breaks',
'chillntropicalhouse',
'chilledm',
'chillhop',
'chillout',
'chilloutdreams',
'chillstep',
'classiceurodance',
'classiceurodisco',
'classictrance',
'classicvocaltrance',
'clubdubstep',
'club',
'darkdnb',
'darkpsytrance',
'deephouse',
'deepnudisco',
'deeporganichouse',
'deepprogressivehouse',
'deeptech',
'detroithousentechno',
'discohouse',
'djmixes',
'downtempolounge',
'drumandbass',
'drumstep',
'dub',
'dubtechno',
'dubstep',
'edmfestival',
'edm',
'electro',
'electroswing',
'electronicpioneers',
'electropop',
'epictrance',
'eurodance',
'funkyhouse',
'futurebass',
'futuregarage',
'futuresynthpop',
'gabber',
'glitchhop',
'goapsy',
'handsup',
'harddance',
'hardtechno',
'hardcore',
'hardstyle',
'house',
'indiebeats',
'indiedance',
'jazzhouse',
'jungle',
'latinhouse',
'liquiddnb',
'liquiddubstep',
'liquidtrap',
'lofihiphop',
'lofiloungenchill',
'lounge',
'melodicprogressive',
'minimal',
'nightcore',
'nudisco',
'oldschoolacid',
'oldschoolhouse',
'oldschoolrave',
'classictechno',
'progressive',
'progressivepsy',
'psybient',
'psychill',
'psydub',
'russianclubhits',
'slaphouse',
'soulfulhouse',
'spacemusic',
'summerchillhouse',
'synthwave',
'techhouse',
'techno',
'trance',
'trap',
'tribalhouse',
'umfradio',
'undergroundtechno',
'vocalchillout',
'vocalhouse',
'vocallounge',
'vocaltrance',
]
// Get those via from: https://www.di.fm/channels -> Select All
const channelTitles = [
'00s Club Hits',
'Ambient',
'Atmospheric Breaks',
"Bass & Jackin' House",
'Bassline',
'Big Beat',
'Big Room House',
'Breaks',
'Chill & Tropical House',
'Chill EDM',
'ChillHop',
'Chillout',
'Chillout Dreams',
'Chillstep',
'Classic EuroDance',
'Classic EuroDisco',
'Classic Trance',
'Classic Vocal Trance',
'Club Dubstep',
'Club Sounds',
'DJ Mixes',
'Dark DnB',
'Dark PsyTrance',
'Deep House',
'Deep Nu-Disco',
'Deep Organic House',
'Deep Progressive House',
'Deep Tech',
'Detroit House & Techno',
'Disco House',
'Downtempo Lounge',
'Drum and Bass',
'Drumstep',
'Dub',
'Dub Techno',
'Dubstep',
'EDM Festival',
'EDM Hits',
'Electro House',
'Electro Swing',
'Electronic Pioneers',
'Electropop',
'Epic Trance',
'EuroDance',
'Funky House',
'Future Bass',
'Future Garage',
'Future Synthpop',
'Gabber',
'Glitch Hop',
'Goa-Psy Trance',
'Hands Up',
'Hard Dance',
'Hard Techno',
'Hardcore',
'Hardstyle',
'House',
'Indie Beats',
'Indie Dance',
'Jazz House',
'Jungle',
'Latin House',
'Liquid DnB',
'Liquid Dubstep',
'Liquid Trap',
'LoFi Hip-Hop',
'LoFi Lounge & Chill',
'Lounge',
'Melodic Progressive',
'Minimal',
'Nightcore',
'Nu Disco',
'Oldschool Acid',
'Oldschool House',
'Oldschool Rave',
'Oldschool Techno & Trance',
'Progressive',
'Progressive Psy',
'PsyChill',
'PsyDub',
'Psybient',
'Russian Club Hits',
'Slap House',
'Soulful House',
'Space Dreams',
'Summer Chill House',
'Synthwave',
'Tech House',
'Techno',
'Trance',
'Trap',
'Tribal House',
'UMF Radio',
'Underground Techno',
'Vocal Chillout',
'Vocal House',
'Vocal Lounge',
'Vocal Trance',
]
// --------------
// Code
// --------------
const channelInfos = channelTitles.map((title, idx) => ({
id: channelIds[idx],
title,
}))
function channelInfoToPlaylistEntry(info, idx) {
const slot = idx + 1
return `File${slot}=https://listen.di.fm/premium_high/${info.id}.pls?${KEY}
Title${slot}=${info.title}
Length${slot}=0`
}
const entries = channelInfos.map(channelInfoToPlaylistEntry)
const playlist = `
[playlist]
NumberOfEntries=${entries.length}
${entries.join('\n')}
Version=2
`
console.log(playlist)
// Run on playlist with thumbnail view, i.e. https://www.youtube.com/playlist?list=PLW_omwEM1aid1jtpNhqigEcRHAVsR-Hmz
const YOUTUBE_ROOT = 'https://www.youtube.com'
const videoItemClass =
'yt-simple-endpoint style-scope ytd-playlist-video-renderer'
function getVideoInfos() {
const videoLinks = document.getElementsByClassName(videoItemClass)
const infos = []
for (let i = 0; i < videoLinks.length; i++) {
const url = videoLinks[i].href
const title = videoLinks[i].innerText.trim()
infos.push({ url, title })
}
return infos
}
function videoInfoToPlaylistEntry(info, idx) {
const slot = idx + 1
return `File${slot}=${info.url}
Title${slot}=${info.title}
Length${slot}=0`
}
const videoInfos = getVideoInfos()
const entries = videoInfos.map(videoInfoToPlaylistEntry)
const playlist = `
[playlist]
NumberOfEntries=${entries.length}
${entries.join('\n')}
Version=2
`
console.log(playlist)
document.querySelector('#copy')?.remove()
copy(playlist)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment