⬆️ ⬇️

A simple implementation of the now playing section for Icecast2 using JSON

Hello, Habr!

Today I had to face the problem of displaying the current track and the main information on the radio page.

In search of the best way to display, I ran across everywhere on the terrible PHP-scripts that stupidly parse the Icecast status page. Moreover, at one of the forums about Internet radio, I came across a very interesting question - “why are you pulling the puff?”. Indeed, why?

And I decided to by all means make the issuance of information about the station in JSON format, and at the same time share with all my ideas.



So, what we need for this is: the server itself, the XSLT file for Icecast, the JS script for parsing the data, and one PHP file (later I will tell you why).



Step One: Set Up Icecast

Icecast2 server allows you to create custom XSL files for displaying station information. By the way, the basic page is also written in this format.

First, find out where icecast is looking for its files. This path is specified in the configuration file (by default, this is / usr / share / icecast2).

Go to the directory / usr / share / icecast2 / www and create an info.xsl file there - a file that will provide information about the mount points.

Through trial and error, I compiled an XSLT file that generates valid JSON code with information about mount points, represented as named objects:



UPDATE: Habrahabr parser slightly spoiled the code. It seems corrected.

<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" > <xsl:output omit-xml-declaration="yes" method="text" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" indent="no" encoding="UTF-8" /><xsl:strip-space elements="*"/> <xsl:template match = "/icestats" > {<xsl:for-each select="source"> "<xsl:value-of select="@mount" />": { <!--      --> "name" : "<xsl:value-of select="server_name"/>", "listeners" : "<xsl:value-of select="listeners" />", "description" : "<xsl:value-of select="server_description" />", "title" : "<xsl:value-of select="title" />", "genre" : "<xsl:value-of select="genre" />", "url" : "<xsl:value-of select="server_url" />" }<xsl:if test="position() != last()"><xsl:text>,</xsl:text></xsl:if> <!-- ,   ,   -   --> </xsl:for-each> } </xsl:template> </xsl:stylesheet> 


')

To get information, contact the server in the following format: example.com:8000/info.xsl



In response, we obtain structured information about all existing mount points. In my case it looks like this:

 { "/ns": { "name" : "Nyan-nyan :3", "listeners" : "3", "description" : "This is sparta~", "title" : "Freaking On Shpongle - Dorset Perception Remix", "genre" : "Kircore", "url" : "http://*********.com" } } 




Step 2: “proxy” setting

We generated the information, but the trouble is: using JavaScript, you cannot access another domain or even a port. It does not matter, we will make here such a script- "adapter":

 <?php $s = file_get_contents("http://example.com:8000/info.xsl"); echo($s); ?> 




I think it will be easier for PHP to simply request and give away, than to request, parse, pull out the necessary data with a regular basis and then send the information. Let's call this script “get.php” and put it on a server in a convenient place.



Step 3: Configure JavaScript

So, now we can both generate and receive information, things are easy - bring it to the user.

Here I will limit the code with comments to it:

 //    ,    DOM.  -  ! function set (id, dat) { var d = document.getElementById(id); d.innerHTML = dat; } function getXmlHttp() //   XMLHttpRequest,      { var xmlhttp; try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xmlhttp = false; } } if (!xmlhttp && typeof XMLHttpRequest!='undefined') { xmlhttp = new XMLHttpRequest(); } return xmlhttp; } function req () //   { var xmlhttp = getXmlHttp() xmlhttp.open("GET", "get.php", true); //        xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4) { if(xmlhttp.status == 200) processResult(xmlhttp.responseText); //    } }; xmlhttp.send(null); } function processResult (res) //    { var csRes = eval("(" + res + ")"); // -,    jQuery,     . ,       ,     . var a = []; //  ,    //       -   (/stream)  ,  ,    (/ns). if (csRes["/stream"] != null) //   ? { a = csRes["/stream"]; //  ,      set("sName", " "); //  ""    } else //      - { a = csRes["/ns"]; set("sName", "Non-Stop ( )"); //  ""   } set("trackholder", a["title"]); //    //      (, - ,    ..) set("sGenre", a["genre"]); set("sListeners", a["listeners"]); set("sDescr", a["description"]); setTimeout("req()", 15000); //    ,  15      //   setInterval  setTimeout,    icecast     . } req(); //   




Step 4: Page Setup

Here everything is easy. We set up a page, set the div elements with the names used in the script above and after these elements specify the link to the script:

 ... <div id="sDescr"> </div> <script type="text/javascript" src="./track.js"></script> 




Total

As a result, we have a less loaded server, a more portable output format (for example, for mobile applications written to listen to your station). Knowing the specifics of XSLT files for Icecast, you can write a great many more interesting things for this wonderful open media server.

In the end, I got a nice page with information about the current track:





When you click on the line with the track, you can view information about the station itself:





All this information is updated without reloading the page.

Source: https://habr.com/ru/post/145694/



All Articles