emptyfm

listen to FM radio station from your browser
git clone git://git.nirm.al/emptyfm
Log | Files | Refs | README | LICENSE

emptyfm.js (4569B)


      1 let player;
      2 let recents;
      3 
      4 async function fetchFMStations() {
      5     let countrySelect = document.getElementById("countryCode");
      6     let countryCode = countrySelect.value;
      7 
      8     let languagesSelect = document.getElementById("languages");
      9     let langCode = languagesSelect.value;
     10 
     11     let queryParams;
     12 
     13     if (!countryCode && !langCode) {
     14         alert("You must choose either country or language, or both if you wish.");
     15         return;
     16     } else if (!countryCode) {
     17         queryParams = "language=" + langCode + "&hidebroken=true&order=clickcount&reverse=true"
     18     } else if (!langCode) {
     19         queryParams = "countrycode=" + countryCode + "&hidebroken=true&order=clickcount&reverse=true"
     20     } else {
     21         queryParams = "countrycode=" + countryCode + "&language=" + langCode + "&hidebroken=true&order=clickcount&reverse=true"
     22     }
     23 
     24     const response = await fetch("https://de1.api.radio-browser.info/json/stations/search?" + queryParams);
     25     const stations = await response.json();
     26 
     27     let fmList = document.getElementById("fmlist");
     28 
     29     fmList.innerHTML = "";
     30     for (var k in stations) {
     31         let atag = document.createElement("a");
     32         atag.className = "fmitem";
     33         atag.href = stations[k].url;
     34         atag.innerText = stations[k].name;
     35         atag.onclick = (e) => {
     36             e.preventDefault();
     37             let found = recents.find(({
     38                 name
     39             }) => name === atag.innerText);
     40             if (!found) {
     41                 addToRecents(recents, atag.innerText, atag.href);
     42             }
     43 
     44             changeSource(atag.href);
     45         }
     46 
     47         fmList.appendChild(atag);
     48     }
     49 }
     50 
     51 function populateRecents() {
     52     let saved = localStorage.getItem('emptyfm') ?? '{ "recents": [] }';
     53     let savedObj = JSON.parse(saved);
     54     recents = savedObj["recents"];
     55 
     56     for (recent of recents) {
     57         constructRecentEl(recent.name, recent.url);
     58     }
     59 }
     60 
     61 function constructRecentEl(name, url) {
     62     let recentsEl = document.getElementById("recentList");
     63     let litag = document.createElement("li");
     64     let atag = document.createElement("a");
     65     atag.href = url;
     66     atag.innerText = name;
     67     atag.onclick = (e) => {
     68         e.preventDefault();
     69         changeSource(atag.href);
     70     };
     71 
     72     litag.appendChild(atag);
     73     recentsEl.appendChild(litag);
     74 }
     75 
     76 function addToRecents(savedObj, name, url) {
     77     let recentObj = {
     78         name: name,
     79         url: url
     80     };
     81 
     82     recents.push(recentObj);
     83 
     84     let recentsStr = JSON.stringify({ recents: recents });
     85     localStorage.setItem('emptyfm', recentsStr);
     86 
     87     constructRecentEl(name, url);
     88 }
     89 
     90 function changeSource(url) {
     91     document.getElementById("emptyfm").style.display = "block";
     92     player = videojs("emptyfm");
     93     let [mediaURL, mediaType] = fetchMediaType(url);
     94     player.src({
     95         type: mediaType,
     96         src: mediaURL
     97     });
     98     player.play().catch(error => {
     99         player.stop()
    100         [mediaURL, mediaType] = fetchMediaType(mediaURL, "application/x-mpegURL")
    101         player.src({
    102             type: mediaType,
    103             src: mediaURL
    104         })
    105         player.play()
    106     });
    107 }
    108 
    109 function fetchMediaType(url, defaultType = "audio/mpeg") {
    110     const radioBox = new URL(url)
    111     let lastPath = radioBox.pathname.split("/").pop();
    112     let mType = lastPath.split('.').pop();
    113 
    114     switch (mType) {
    115         case "m3u8":
    116             return [url, "application/x-mpegURL"];
    117         default:
    118             return [url, defaultType];
    119     }
    120 }
    121 
    122 function listCountries() {
    123     fetch('./iso-3166-1-alpha2-countrycode.json')
    124         .then((response) => response.json())
    125         .then((json) => {
    126             let selectElem = document.getElementById("countryCode");
    127 
    128             for (var k in json) {
    129                 if (json.hasOwnProperty(k)) {
    130                     let option = document.createElement("option");
    131                     option.text = json[k];
    132                     option.value = k;
    133 
    134                     selectElem.appendChild(option);
    135                 }
    136             }
    137         })
    138 }
    139 
    140 function listLanguages() {
    141     fetch('./iso-639-lang.json')
    142         .then((response) => response.json())
    143         .then((json) => {
    144             let selectElem = document.getElementById("languages");
    145 
    146             for (var k in json) {
    147                 if (json.hasOwnProperty(k)) {
    148                     let option = document.createElement("option");
    149                     option.text = json[k];
    150                     option.value = k;
    151 
    152                     selectElem.appendChild(option);
    153                 }
    154             }
    155         })
    156 }
    157 
    158 populateRecents();
    159 listCountries();
    160 listLanguages();