Initial commit
This commit is contained in:
commit
9c7b61256f
22 changed files with 480 additions and 0 deletions
14
Makefile
Normal file
14
Makefile
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
all: index.html spec.html radiomanifest.zip
|
||||||
|
testXMLs := $(shell find shows radio-manifest -type f -name '*.xml')
|
||||||
|
|
||||||
|
%.html: %.asciidoc
|
||||||
|
asciidoctor -b html5 $<
|
||||||
|
|
||||||
|
radiomanifest.zip: radio-manifest.xsd shows.xsd radio-manifest/Makefile shows/Makefile $(testXMLs)
|
||||||
|
zip -r $@ $^
|
||||||
|
|
||||||
|
test:
|
||||||
|
make -C shows/
|
||||||
|
make -C radio-manifest/
|
||||||
|
|
||||||
|
.PHONY: all
|
21
index.asciidoc
Normal file
21
index.asciidoc
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
= Radiomanifest
|
||||||
|
CiurmaPirata
|
||||||
|
|
||||||
|
Scopo di questa specifica è quello di fare sì che il sito di una radio possa esporre in maniera strutturata alcune informazioni sul suo sito.
|
||||||
|
|
||||||
|
|
||||||
|
* link:spec.html[read the spec]
|
||||||
|
* link:radio-manifest.xsd[XSD radio-manifest]
|
||||||
|
* link:shows.xsd[XSD shows]
|
||||||
|
* link:radiomanifest.zip[examples dataset]
|
||||||
|
* link:examples/[example websites]
|
||||||
|
|
||||||
|
== Implementations
|
||||||
|
|
||||||
|
=== Clients
|
||||||
|
|
||||||
|
* link:https://git.lattuga.net/boyska/radiomanifest.js/[radiomanifest.js]
|
||||||
|
|
||||||
|
=== Server
|
||||||
|
|
||||||
|
none yet?
|
53
radio-manifest.xsd
Normal file
53
radio-manifest.xsd
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
|
||||||
|
<xs:element name="radio-manifest">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
|
||||||
|
<xs:element name="schedule" minOccurs="0">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="src" type="srctype" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
|
||||||
|
<xs:element name="shows" minOccurs="0">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="src" type="srctype" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="streaming" minOccurs="0">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="source" maxOccurs="unbounded">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||||
|
<xs:attribute name="src" type="srctype" use="required"/>
|
||||||
|
<xs:attribute name="priority" type="xs:byte" default="1" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="feed" minOccurs="0">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="src" type="srctype" use="required" />
|
||||||
|
<xs:attribute name="type" type="xs:string" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
|
||||||
|
<xs:simpleType name="srctype">
|
||||||
|
<xs:restriction base="xs:anyURI">
|
||||||
|
<xs:minLength value="1" />
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
|
||||||
|
</xs:schema>
|
14
radio-manifest/Makefile
Normal file
14
radio-manifest/Makefile
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
VALID = examples/*.xml
|
||||||
|
NONVALID = failing/*.xml
|
||||||
|
SCHEMA = ../radio-manifest.xsd
|
||||||
|
|
||||||
|
all: test
|
||||||
|
test: $(VALID) $(NONVALID)
|
||||||
|
|
||||||
|
examples/%.xml: $(SCHEMA)
|
||||||
|
xmllint --schema $(SCHEMA) --noout $@
|
||||||
|
|
||||||
|
failing/%.xml: $(SCHEMA)
|
||||||
|
if xmllint --schema $(SCHEMA) --noout $@ 2> /dev/null; then false; else true; fi
|
||||||
|
|
||||||
|
.PHONY: all test
|
10
radio-manifest/examples/1.xml
Normal file
10
radio-manifest/examples/1.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest>
|
||||||
|
<schedule src="https://www.radioexample.org/palinsesto.ics" />
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<streaming>
|
||||||
|
<source name="hi-quality" src="https://www.radioexample.org/stream.m3u" />
|
||||||
|
<source name="lo-quality" src="https://www.radioexample.org/stream-low.m3u" />
|
||||||
|
</streaming>
|
||||||
|
<feed src="https://www.radioexample.org/all.xml" type="application/atom+xml" />
|
||||||
|
</radio-manifest>
|
4
radio-manifest/examples/empty.xml
Normal file
4
radio-manifest/examples/empty.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest>
|
||||||
|
</radio-manifest>
|
||||||
|
|
10
radio-manifest/examples/feed-no-type.xml
Normal file
10
radio-manifest/examples/feed-no-type.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest >
|
||||||
|
<schedule src="https://www.radioexample.org/palinsesto.ics" />
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<streaming>
|
||||||
|
<source name="hi-quality" src="https://www.radioexample.org/stream.m3u" />
|
||||||
|
<source name="lo-quality" src="https://www.radioexample.org/stream-low.m3u" />
|
||||||
|
</streaming>
|
||||||
|
<feed src="https://www.radioexample.org/all.xml" />
|
||||||
|
</radio-manifest>
|
10
radio-manifest/examples/reordered.xml
Normal file
10
radio-manifest/examples/reordered.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest>
|
||||||
|
<streaming>
|
||||||
|
<source name="hi-quality" src="https://www.radioexample.org/stream.m3u" />
|
||||||
|
<source name="lo-quality" src="https://www.radioexample.org/stream-low.m3u" />
|
||||||
|
</streaming>
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<schedule src="https://www.radioexample.org/palinsesto.ics" />
|
||||||
|
</radio-manifest>
|
||||||
|
|
10
radio-manifest/examples/source-prio.xml
Normal file
10
radio-manifest/examples/source-prio.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest>
|
||||||
|
<schedule src="https://www.radioexample.org/palinsesto.ics" />
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<streaming>
|
||||||
|
<source name="dont-use-me" priority="-100" src="https://www.radioexample.org/stream-internal.m3u" />
|
||||||
|
<source name="hi-quality" priority="100" src="https://www.radioexample.org/stream.m3u" />
|
||||||
|
</streaming>
|
||||||
|
</radio-manifest>
|
||||||
|
|
9
radio-manifest/examples/streaming-1.xml
Normal file
9
radio-manifest/examples/streaming-1.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest>
|
||||||
|
<schedule src="https://www.radioexample.org/palinsesto.ics" />
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<streaming>
|
||||||
|
<source name="lo-quality" src="https://www.radioexample.org/stream-low.m3u" />
|
||||||
|
</streaming>
|
||||||
|
</radio-manifest>
|
||||||
|
|
14
radio-manifest/failing/repeated.xml
Normal file
14
radio-manifest/failing/repeated.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="https://boyska.degenerazione.xyz/radiomanifest/radiomanifest.xsd"
|
||||||
|
>
|
||||||
|
<schedule src="https://www.radioexample.org/palinsesto.ics" />
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<streaming>
|
||||||
|
<source name="hi-quality" src="https://www.radioexample.org/stream.m3u" />
|
||||||
|
<source name="lo-quality" src="https://www.radioexample.org/stream-low.m3u" />
|
||||||
|
</streaming>
|
||||||
|
</radio-manifest>
|
||||||
|
|
5
radio-manifest/failing/streaming-empty.xml
Normal file
5
radio-manifest/failing/streaming-empty.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest>
|
||||||
|
<streaming>
|
||||||
|
</streaming>
|
||||||
|
</radio-manifest>
|
10
radio-manifest/failing/streaming-prio-toohigh.xml
Normal file
10
radio-manifest/failing/streaming-prio-toohigh.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest>
|
||||||
|
<schedule src="https://www.radioexample.org/palinsesto.ics" />
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<streaming>
|
||||||
|
<source name="hi-quality" priority="128" src="https://www.radioexample.org/stream.m3u" />
|
||||||
|
</streaming>
|
||||||
|
</radio-manifest>
|
||||||
|
|
||||||
|
|
8
radio-manifest/failing/streaming-prio-toolow.xml
Normal file
8
radio-manifest/failing/streaming-prio-toolow.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest>
|
||||||
|
<schedule src="https://www.radioexample.org/palinsesto.ics" />
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<streaming>
|
||||||
|
<source name="hi-quality" priority="-129" src="https://www.radioexample.org/stream.m3u" />
|
||||||
|
</streaming>
|
||||||
|
</radio-manifest>
|
10
radio-manifest/failing/streaming-source-empty.xml
Normal file
10
radio-manifest/failing/streaming-source-empty.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest>
|
||||||
|
<schedule src="https://www.radioexample.org/palinsesto.ics" />
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<streaming>
|
||||||
|
<source name="lo-quality" src="" />
|
||||||
|
</streaming>
|
||||||
|
</radio-manifest>
|
||||||
|
|
||||||
|
|
43
shows-table.xsl
Normal file
43
shows-table.xsl
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||||
|
|
||||||
|
<xsl:template match="/">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Shows list</title>
|
||||||
|
<style type="text/css">
|
||||||
|
table, th, td { border: 1px solid black; border-collapse: collapse; }
|
||||||
|
th, td { padding: 0.3em; }
|
||||||
|
thead { background-color: #ccc; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Website</th>
|
||||||
|
<th>Feed</th>
|
||||||
|
<th>Schedule</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<xsl:for-each select="shows/show">
|
||||||
|
<tr>
|
||||||
|
<xsl:variable name="name" select="name"/>
|
||||||
|
<xsl:variable name="website" select="website"/>
|
||||||
|
<xsl:variable name="feed" select="feed"/>
|
||||||
|
<xsl:variable name="schedule" select="schedule"/>
|
||||||
|
<td><xsl:value-of select="name" /></td>
|
||||||
|
<td><a href="{$website}"><xsl:value-of select="website" /></a></td>
|
||||||
|
<td><a href="{$feed}"><xsl:value-of select="feed" /></a></td>
|
||||||
|
<td><a href="{$schedule}"><xsl:value-of select="schedule" /></a></td>
|
||||||
|
</tr>
|
||||||
|
</xsl:for-each>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:transform>
|
26
shows.xsd
Normal file
26
shows.xsd
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<xs:element name="shows">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="show" maxOccurs="unbounded" minOccurs="0">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="name" type="xs:string" />
|
||||||
|
<xs:element name="website" type="srctype" minOccurs="0" />
|
||||||
|
<xs:element name="feed" type="srctype" minOccurs="0" />
|
||||||
|
<xs:element name="schedule" type="srctype" minOccurs="0" />
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:simpleType name="srctype">
|
||||||
|
<xs:restriction base="xs:anyURI">
|
||||||
|
<xs:minLength value="1" />
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
|
||||||
|
</xs:schema>
|
14
shows/Makefile
Normal file
14
shows/Makefile
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
VALID = examples/*.xml
|
||||||
|
NONVALID = failing/*.xml
|
||||||
|
SCHEMA = ../shows.xsd
|
||||||
|
|
||||||
|
all: test
|
||||||
|
test: $(VALID) $(NONVALID)
|
||||||
|
|
||||||
|
examples/%.xml: $(SCHEMA)
|
||||||
|
xmllint --schema $(SCHEMA) --noout $@
|
||||||
|
|
||||||
|
failing/%.xml: $(SCHEMA)
|
||||||
|
if xmllint --schema $(SCHEMA) --noout $@ 2> /dev/null; then false; else true; fi
|
||||||
|
|
||||||
|
.PHONY: all test
|
15
shows/examples/basic.xml
Normal file
15
shows/examples/basic.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<?xml-stylesheet type="text/xsl" href="https://boyska.degenerazione.xyz/radiomanifest/shows-table.xsl"?>
|
||||||
|
<shows>
|
||||||
|
<show>
|
||||||
|
<name>Learn to cook in C++</name>
|
||||||
|
<website>http://radioexample.com/shows/learn-cook</website>
|
||||||
|
<feed>http://radioexample.com/shows/learn-cook/feed</feed>
|
||||||
|
<schedule>http://radioexample.com/shows/learn-cook.ics</schedule>
|
||||||
|
</show>
|
||||||
|
<show>
|
||||||
|
<name>Uncensored information</name>
|
||||||
|
<website>http://radioexample.com/shows/info</website>
|
||||||
|
<feed>http://radioexample.com/shows/info/feed</feed>
|
||||||
|
</show>
|
||||||
|
</shows>
|
4
shows/examples/empty.xml
Normal file
4
shows/examples/empty.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<shows>
|
||||||
|
</shows>
|
||||||
|
|
8
shows/failing/noname.xml
Normal file
8
shows/failing/noname.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<shows>
|
||||||
|
<show>
|
||||||
|
<website>http://radioexample.com/shows/learn-cook</website>
|
||||||
|
<feed>http://radioexample.com/shows/learn-cook/feed</feed>
|
||||||
|
<schedule>http://radioexample.com/shows/learn-cook.ics</schedule>
|
||||||
|
</show>
|
||||||
|
</shows>
|
168
spec.asciidoc
Normal file
168
spec.asciidoc
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
= Radiomanifest specification
|
||||||
|
CiurmaPirata
|
||||||
|
|
||||||
|
Un formato per fare sì che il sito di una radio possa esporre in maniera strutturata alcune informazioni sul
|
||||||
|
suo sito.
|
||||||
|
|
||||||
|
Tali informazioni sono, brevemente:
|
||||||
|
|
||||||
|
* il palinsesto
|
||||||
|
* l'elenco delle trasmissioni che vanno in onda in modo regolare, e per ciascuna di esse i principali feed
|
||||||
|
* gli indirizzi di streaming
|
||||||
|
|
||||||
|
|
||||||
|
Per permettere un'implementazione più semplice, ciascuna di queste informazioni segue una sua specifica, possibilmente appoggiandosi a specifiche già esistenti.
|
||||||
|
|
||||||
|
== RadioManifest
|
||||||
|
|
||||||
|
Al fine di avere un singolo punto in cui "esporre" le funzionalità supportate dal sito web, un sito può creare un manifest. Esso *DOVREBBE* (*SHOULD*) chiamarsi sempre ``${BASEURL}/radiomanifest.xml``.
|
||||||
|
|
||||||
|
Ecco un esempio di xml:
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<radio-manifest>
|
||||||
|
<schedule src="https://www.radioexample.org/palinsesto.ics" />
|
||||||
|
<streaming>
|
||||||
|
<source name="hi-quality" priority="100" src="https://www.radioexample.org/stream.m3u" />
|
||||||
|
<source name="lo-quality" priority="50" src="https://www.radioexample.org/stream-low.m3u" />
|
||||||
|
</streaming>
|
||||||
|
<shows src="https://www.radioexample.org/shows.xml" />
|
||||||
|
<feed src="https://www.radioexample.org/all.xml" />
|
||||||
|
</radio-manifest>
|
||||||
|
|
||||||
|
(link:radio-manifest.xsd[Schema XSD])
|
||||||
|
|
||||||
|
Ovvero:
|
||||||
|
|
||||||
|
* 0 o 1 ``schedule``. Gli schedule sono definiti in link:https://icalendar.org/RFC-Specifications/iCalendar-RFC-5545/[formato iCalendar]
|
||||||
|
* 0 o 1 oggetti ``streaming``; contengono un qualsiasi numero (almeno 1) di source, le quali
|
||||||
|
** *POSSONO* avere un campo ``name``. Il campo ``name`` è fortemente
|
||||||
|
raccomandato se viene fornito più di un oggetto ``streaming``
|
||||||
|
** *DEVONO* avere un campo ``src``, il quale deve puntare ad una risorsa di tipo M3U.
|
||||||
|
** *POSSONO* avere un campo ``priority``, contenente un valore intero; se omesso, si assume il valore "1". Un numero più grande indica una
|
||||||
|
maggiore importanza. Il campo ``priority`` serve a definire l'ordinamento con cui i client *DOVREBBERO*
|
||||||
|
mostrare le playlist agli utenti, o a definire quale playlist vada usata, se il client sceglie automaticamente
|
||||||
|
senza proporrere all'utente. Il valore della priority è relativo alle altre source, non si riferisce ad altre
|
||||||
|
radio. Valori di priority minori di zero indicano che la source non dovrebbe essere resa visibile all'utente
|
||||||
|
in condizioni normali.
|
||||||
|
* 0 o 1 oggetti ``shows``. Il campo ``src`` *DEVE* puntare ad una risorsa di formato _shows_ (vedi di
|
||||||
|
seguito).
|
||||||
|
* 0 o 1 ``feed``. Il campo ``src`` *DEVE* puntare ad una risorsa di tipo feed.
|
||||||
|
|
||||||
|
### Implementazione client
|
||||||
|
|
||||||
|
Un client dovrebbe chiedere all'utente di fornire l'indirizzo base di un sito. Il manifest dovrebbe essere
|
||||||
|
rintracciabile andando all'indirizzo ``radiomanifest.xml`` relativo all'indirizzo di un sito.
|
||||||
|
Ad esempio, se l'utente inserisce "http://hosting.com/myradio/" il manifest *DEVE* essere cercato all'indirizzo
|
||||||
|
"http://hosting.com/myradio/radiomanifest.xml"
|
||||||
|
|
||||||
|
Quando un client vuole suonare lo streaming associato ad un radiomanifest, esso potrebbe voler mostrare
|
||||||
|
all'utente la scelta tra le varie source, oppure decidere automaticamente.
|
||||||
|
Se il client sceglie automaticamente:
|
||||||
|
|
||||||
|
* *DEVE* rispettare l'ordinamento delle priority.
|
||||||
|
* *DEVE* escludere le source con priority minore di zero.
|
||||||
|
* Qualora la riproduzione della source dovesse avere problemi, *DOVREBBE* passare alla successiva
|
||||||
|
* Se alcune source hanno uguale priority, *DOVREBBE* scegliere casualmente tra di esse
|
||||||
|
|
||||||
|
Se il client fa scegliere l'utente:
|
||||||
|
|
||||||
|
* *DEVE* rispettare l'ordinamento delle priority
|
||||||
|
* *DOVREBBE* omettere le source con priority minore di zero.
|
||||||
|
|
||||||
|
== Schedule
|
||||||
|
|
||||||
|
The goal of the schedule is to express the typical weekly table that is commonly found in radio websites. It is an iCalendar file. Each show should be a distinct ``VEVENT``.
|
||||||
|
|
||||||
|
The schedule *SHOULD* include at least events up until 1 week
|
||||||
|
The schedule *SHOULD* use recurrency rule where appropriate, so that the user is informed of this.
|
||||||
|
|
||||||
|
== Shows
|
||||||
|
|
||||||
|
The goal of the shows file is to:
|
||||||
|
|
||||||
|
* list shows
|
||||||
|
* provide useful metadata for each show, such as:
|
||||||
|
** dedicated feed
|
||||||
|
** link to specialized page for the show
|
||||||
|
|
||||||
|
Here is an example:
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<shows>
|
||||||
|
<show>
|
||||||
|
<name>Learn to cook in C++</name>
|
||||||
|
<website>http://radioexample.com/shows/learn-cook</website>
|
||||||
|
<feed>http://radioexample.com/shows/learn-cook/feed</feed>
|
||||||
|
<schedule>http://radioexample.com/shows/learn-cook.ics</schedule>
|
||||||
|
</show>
|
||||||
|
<show>
|
||||||
|
<name>Uncensored information</name>
|
||||||
|
<website>http://radioexample.com/shows/info</website>
|
||||||
|
<feed>http://radioexample.com/shows/info/feed</feed>
|
||||||
|
</show>
|
||||||
|
</shows>
|
||||||
|
|
||||||
|
(link:shows.xsd[Schema XSD])
|
||||||
|
|
||||||
|
Only ``name`` is required. A schedule can point to an iCal resource. All entries in the calendar are assumed to
|
||||||
|
be part of the show.
|
||||||
|
|
||||||
|
=== Relationship with schedule
|
||||||
|
|
||||||
|
It's pretty clear that in many cases shows.xml and schedule.ics will benefit from being linked. How to do
|
||||||
|
that?
|
||||||
|
|
||||||
|
1. If there is an ``X-SHOW-ID``, and it is the same as ``<name>``
|
||||||
|
2. If ``CATEGORIES`` include ``<name>``
|
||||||
|
3. If ``SUMMARY`` is the same as ``<name>``
|
||||||
|
|
||||||
|
== Implementation details
|
||||||
|
|
||||||
|
=== HTTP Implementation
|
||||||
|
|
||||||
|
Clients:
|
||||||
|
|
||||||
|
- *MUST* provide an ``Accept`` header in every HTTP request. This will enable maximum flexibility in the
|
||||||
|
future, allowing clients and servers to smoothly move to new file formats
|
||||||
|
|
||||||
|
Servers:
|
||||||
|
|
||||||
|
- *MUST* implement CORS adequately. Every file related to this specification must be retrievable by a browser
|
||||||
|
on a different domain via a `GET`.
|
||||||
|
|
||||||
|
|
||||||
|
== Casi d'uso
|
||||||
|
|
||||||
|
=== Player
|
||||||
|
|
||||||
|
Supponiamo di voler realizzare un player di radio con feature avanzate, che sia però portabile su molte radio.
|
||||||
|
Data una lista di URL di siti web, è possibile fare un player che:
|
||||||
|
|
||||||
|
* supporti vari indirizzi di streaming in modo trasparente per l'utente
|
||||||
|
* permetta all'utente di scegliere il tipo di streaming, ad esempio se la radio fornisce streaming di diversa
|
||||||
|
qualità
|
||||||
|
* possa dire all'utente informazioni utili sul palinsesto della radio che sta ascoltando
|
||||||
|
* permetta di puntare allo storico, o di andare rapidamente alla pagina della trasmissione che sta
|
||||||
|
ascoltando.
|
||||||
|
|
||||||
|
Come capita spesso, questo può essere applicato anche alla scrittura di app che supportino molte radio, senza che però esse debbano essere limitate al solo streaming come è il caso attualmente (vedi le varie Transistor, RadioDroid, ecc.)
|
||||||
|
|
||||||
|
=== Radio automation
|
||||||
|
|
||||||
|
Se un radio automation (della radio A) vuole importare contenuti da un'altra radio B, esso può facilmente
|
||||||
|
fornire all'utente della radio A utili informazioni. Ad esempio, permette di vedere il palinsesto in forma
|
||||||
|
grafica, selezionare uno show, vedere un'anteprima del feed corrispondente, quindi importarlo in una specifica
|
||||||
|
fascia oraria.
|
||||||
|
|
||||||
|
=== radio-browser++
|
||||||
|
|
||||||
|
https://www.radio-browser.info/ fornisce molte info utili su delle radio. Grazie a radio-manifest, sarebbe più semplice:
|
||||||
|
|
||||||
|
* mantenere le informazioni in modo più semplice; finché una radio mantiene lo stesso sito web, può aggiornare la lista di url di streaming in modo automatico
|
||||||
|
* più informazioni; radio-browser potrebbe includere le informazioni dettagliate disponibili tramite ``<schedule>`` e ``<shows>`` per fornire informazioni aggiuntive.
|
||||||
|
|
||||||
|
=== RadioDroid++
|
||||||
|
|
||||||
|
RadioDroid is a fine Android app to listen to stream. We'd like to have an improved version of RadioDroid that
|
||||||
|
also includes features that RadioManifest provide. See the _Player_ use case.
|
Loading…
Reference in a new issue