Last active
April 12, 2025 11:57
-
-
Save thlorenz/73e3d1e91db9dc4f575c6de647eb01e0 to your computer and use it in GitHub Desktop.
Get Di.fm and related stations playlist for all channels
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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