123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- const fetch = require('isomorphic-unfetch')
- class RadioManifest {
- constructor (baseURL, options) {
- this.baseURL = baseURL
- this.options = options
- const radiomanifest = fetch(`${baseURL}/radiomanifest.xml`)
- return radiomanifest
- }
- getShowByName (showName) {
- }
- getStreaming () {
- }
- getSchedule () {
- }
- getShowAtTime () {
- }
- }
- function getStreaminfoUrl (siteurl) {
- return siteurl + '/streaminfo.json' // XXX: improve this logic
- }
- function getManifestUrl (siteurl) {
- return siteurl + '/radiomanifest.xml' // XXX: improve this logic
- }
- function parseRadioManifest (xml) {
- let res = xml.evaluate('/radio-manifest/streaming/source', xml)
- const sources = []
- while (true) {
- const src = res.iterateNext()
- if (src === null) break
- if (!src.hasAttribute('priority')) {
- src.setAttribute('priority', '0')
- } else if (parseInt(src.getAttribute('priority'), 10) < 0) {
- continue
- }
- sources.push(src)
- }
- sources.sort(function cmp (a, b) {
- return parseInt(a.getAttribute('priority', 10)) < parseInt(b.getAttribute('priority', 10))
- })
- res = xml.evaluate('/radio-manifest/schedule', xml)
- const scheduleEl = res.iterateNext()
- let schedule = null
- if (scheduleEl !== null) {
- schedule = scheduleEl.getAttribute('url')
- }
- res = xml.evaluate('/radio-manifest/shows', xml)
- const showsEl = res.iterateNext()
- let shows = null
- if (showsEl !== null) {
- shows = showsEl.getAttribute('src')
- }
- const manifest = new Radio(sources, schedule, shows)
- return manifest
- }
- function Radio (sources, schedule, shows) {
- this.streaming = new RadioStreaming(sources)
- this.schedule = schedule
- this.shows = shows
- this.name = ''
- }
- Radio.prototype.getStreaming = function () {
- return this.streaming
- }
- Radio.prototype.setName = function (name) {
- this.name = name
- }
- function RadioStreaming (sources) {
- this.sources = sources
- }
- RadioStreaming.prototype.getOptions = function () {
- return this.sources.map(function (x) {
- return x.getAttribute('name')
- })
- }
- RadioStreaming.prototype.getSource = function (name) {
- if (name === undefined) {
- }
- const s = this.sources.find(function (x) {
- return x.getAttribute('name') === name
- })
- if (s === undefined) return s
- return s.getAttribute('src')
- }
- async function get (siteurl, options) {
- let resp = await fetch(getManifestUrl(siteurl))
- let text = await resp.text()
- const parser = new DOMParser()
- const dom = parser.parseFromString(text, 'text/xml')
- const manifest = parseRadioManifest(dom)
- resp = null
- try {
- resp = await fetch(getStreaminfoUrl(siteurl))
- text = await resp.text()
- const data = JSON.parse(text)
- const name = data['icy-name']
- if (name !== undefined) {
- manifest.setName(name)
- }
- } catch (e) {
- if (e instanceof TypeError && e.message.startsWith('NetworkError')) {
- // the fetch has failed
- true
- } else if (e instanceof SyntaxError && e.message.startsWith('JSON.parse')) {
- true
- } else {
- console.error('Error', e)
- throw e
- }
- }
- // XXX: in base alle options fai fetch anche di altra roba
- return manifest
- }
- function parseM3U (body) {
- body.split('\n').filter((e) => {
- if (e.startsWith('#')) {
- return false
- } else {
- try { new URL(e); return true } catch { return false }
- }
- })
- }
- module.exports = {
- get: get,
- objs: {
- Radio: Radio,
- RadioStreaming: RadioStreaming
- },
- parsers: {
- M3U: parseM3U,
- radioManifest: parseRadioManifest
- }
- }
|