Sending Now playing metadata
  • 09 Apr 2025
  • 8 Minutes to read
  • Dark
    Light
  • PDF

Sending Now playing metadata

  • Dark
    Light
  • PDF

Article summary

Our platform supports various ways to receive live "Now Playing" song information from the play-out system.

Most radio play-out systems support automatically sending this information, but publishers can also use their own scripts to update this information.

We make this "Now Playing" data available to listeners in our web players (including optional artwork lookup) and via a JSON endpoint for more direct integration into websites and mobile apps.

Sending Now Playing data from a play-out system

Each customer has unique values for the username, password, ip and mountpoint values used in these examples, which can be provided by our support team, and is available on the "Setup" tab of the stream's page:

Screenshot 2022-07-28 at 14.21.51.png

Send Icecast metadata

Icecast supports metadata to be sent for an active mountpoint by calling an HTTP endpoint:

http://<username>:<password>@<ip>:8000/admin/metadata?mount=/<mountpoint>&mode=updinfo&song=<songname>

Typical Icecast streaming source clients like BUTT automatically uses this endpoint but it can be called manually also:

curl http://source:examplepassword@1.2.3.4:8000/admin/metadata?mount=/123_primary&mode=updinfo&charset=UTF-8&song=ACDC+Back+In+Black

<iceresponse>
  <message>Metadata update successful</message>
  <return>1</return>
</iceresponse>

Important Icecast notes

Icecast will only accept metadata if:

  • The mountpoint is currently online,
  • The IP address sending the metadata matches the IP address sending the audio into the mountpoint
  • The metadata endpoint expects data in the UTF8 character set. Anything else may be rejected or displayed incorrectly.
  • The "songname" value should be in + delimited values with artist first, for example: ACDC+Back+In+Black.

RCS Zetta

We provide native support to receive "Now Playing" metadata from the RCS Zetta radio automation software. When current song information changes, it sends XML data via an HTTP POST to a remote server. See this article for details on setting up Zetta.

Jazler Radiostar

We provide native support to receive "Now Playing" metadata from the Jazler Radiostar 2 radio automation software. When current song information changes, it uploads an XML file to a remote FTP server. Our support department can assist customers with configuring their Jazler instance to perform this FTP upload.

Simian Pro

Simian Pro can be configured to send "Now Playing" metadata to our platform via Icecast. Consult the "Configuring Streaming (HTTP call) Output" section on page 51 of the Simian Pro 2.3 manual.

simian.png

  1. Under the "Streaming" tab of the program options, in the "Stream Encoding Metadata" section, enable the "Icecast" item and use the provided URL, username and password specific to your stream instance.

  2. In the EncoderData.ini file, modify the IceCAST line to change the mountpoint name from live to match the mountpoint assigned to your stream:

IceCAST=/admin/metadata?mount=/yourmountname&mode=updinfo&song=%artist%+-+%title%
  1. Enable the "Encode Stream Encoding Metadata (use URL entities)" setting.

RadioBOSS

RadioBoss can be configured to send "Now Playing" metadata to our platform via Icecast.

Under the "Broadcast" section of the RadioBOSS configuration used to send the Icecast stream, use the "Metadata" panel to configure sending the song metadata.

See the RadioBOSS manual

Sending Now Playing metadata into our HTTP endpoint

Every stream has a custom password-protected HTTP endpoint where "Now Playing" information can be sent.

Endpoint location

To use this endpoint, each customer uses unique PASSWORD, IP and STREAM_ID values. The endpoint URL structure is:

http://source:<PASSWORD>@<IP>/metadata/capture/<STREAM_ID>

This endpoint is only available on plain HTTP on port 80 and text data must use the UTF8 character encoding.

Data can be passed sent as HTTP POST data (recommended), HTTP POST with JSON encoded data or URL query parameters (not recommended).

Endpoint data fields

This endpoint data supports these fields:

FieldDescriptionNotes
eventThe type of event that was triggered which indicates roughly the type of content being played. Valid values are: song, ad, news, show, podcast, interview, spot, linkDefault: song
artistName of the artist playing the current song, or name of interviewer, news reader or related vocals. Free form text, limited to 50 characters.Example: AC/DC
titleTitle of the current song, topic of interview or any other information. Free form text, limited to 50 characters.Example: T.N.T
albumName of album, if available. Free form text, limited to 50 characters.Example: High Voltage
genreMusic genre or audio category.Example: Hard rock
durationDuration of this event in seconds if known in advance, for example length of song. Accepts either integer number of seconds or an hh:mm:ss string.Example: 185 seconds, or 00:03:05
artworkEither a base-64 encoded image or a direct URL to an image. We recommend square aspect ratio images of 300x300 pixels.Example: URL https://ex.com/song.png or BASE64 data:image/png;base64,ENCODEDDATA
linkAny URL associated with the current item.Example: https://yoursite.com/show

HTTP POST data example

Using traditional HTTP POST encoding:

curl --user source:<PASSWORD> \
     --write-out '%{http_code}' \
     --request POST \
     --header 'Content-Type: application/x-www-form-urlencoded' \
     --data 'event=song&artist=AC/DC&title=Back in Black&length=04:14' \
     "http://<IP>/metadata/capture/STREAM_ID"

HTTP POST with JSON data example

The same endpoint can also accept input as JSON data in the HTTP BODY with the same fields. Escaping is not required in this case:

curl --user source:<PASSWORD> \
     --write-out '%{http_code}' \
     --request POST \
     --header 'Content-Type: application/json' \
     --data '{ "event":"song", "artist":"AC/DC", "title":"Back In Black", "duration":254 }' \
     "http://<IP>/metadata/capture"

URL Query parameters example

Query parameters are attached to the end of a URL and may need to be escaped to ensure a valid URL.

Query parameters are not recommended and should only be used when sending basic artist/title information.

Example:

curl --user source:<PASSWORD> \
     --write-out '%{http_code}' \
     --request POST \
     "http://<IP>/metadata/capture?event=song&artist=AC%2FDC&title=Back%20In%20Black&duration=254"

Displaying & retrieving Now Playing data

Web player

As long as valid metadata is being received from any input method, our embedded player will display this to users while they are listening to the live-stream.

HTTP endpoint with JSON content

To integrate "Now Playing" elsewhere, the metadata can be retrieved using an HTTP GET to our edge network:

cURL Example:

curl --request GET \
     https://edge.iono.fm/xmetadata/<streamid>

This will return the latest available metadata for the specified stream as a JSON object with all the data fields as documented in the previous section.

Example contents:

{
  event: "song",
  dt: "2016-08-12T14:51:16-0200",
  artist: "AC/DC",
  title: "Black in Black",
  duration: 185
}

This endpoint is useful when integrating live streams delivered on our platform into custom mobile applications or other platforms or players.

Automated album artwork lookup

Our web player can display automated artwork based on song data.

When updated metadata is received it will look for album art using the current now playing data.

If it cannot find any valid album art, it displays the default image associated with the stream.

Prevent album lookup for non-music segments

During non-music segments there won't be any valid album artwork to lookup. If the station passes default information (like the station name or segment name) during these broadcast segments our player will still lookup artwork and cause irrelevant images to be displayed.

To prevent this, the playout system can send blank strings during these segments or as it's "default" values when no song information is available. It may be necessary to send one space character instead of any empty string to trigger this behaviour.

The image will revert to your standard stream logo and the "Now Playing" string on the player will read "Live stream" during these segments.

Prevent ad names from being displayed or loading artwork

When the playout system is broadcasting an ad, some playout systems will send this data as Now Playing data also.
To prevent our player from displaying the ad name to end users or using it to load artwork, add the word "ad" anywhere standalone in the titles of your ad creatives.

For example, all these titles will be effective to ignore the ad:

"Ad name", "ad name", "name ad", "name - ad", "name - ad - more details", "AD NAME"

​The matching is not case-sensitive, you can use "ad", "Ad", "AD", "aD".

If the word "ad" is not a standalone word in the title if will not be detected and ignored. ex:

"Ad: name", "Advertisement", "AdName"

Implementation notes

Please take note of these items when using this endpoint in your own players and client applications:

  • All fields except “event" may be empty based on input from the station.
  • We reserve the right to change the contents or location of this response in the future to allow extending it with more data. Clients will be notified of any changes to allow time to update any dependencies.
  • Client polling intervals must never be less than 15 seconds, 30 seconds recommended. We retain the right to rate-limit and/or disable access to any applications that have higher polling rates to prevent unnecessary overheads on our servers. Rate limited requests will respond with the "429 Too Many Requests” HTTP status code.
  • While metadata input is offline and not being received from the station, requests will respond with the “404 Not Found” status code.
  • The endpoint can return HTTP "304 Not Modified" responses if the "If-Last-Modified” header is used in requests. ETag headers are also available. Clients are urged to make use of this information to ensure low overheads.
  • Responses will include the CORS header "Access-Control-Allow-Origin: *" to enable direct consumption from Javascript clients.
  • Clients are recommended to only poll for this information while a listener is actively listening to the stream.

Reference: simple Javascript example to poll a metadata endpoint

<!doctype html>
<html lang="en">
<script>

    // Javascript to load and display "Now playing" metadata from iono.fm
    // Requires HTML element: <div id="nowplayingtitle"></div>

    // Define where do we load data from
    const metadataUrl = 'https://edge.iono.fm/xmetadata/<your-stream-id>';

    // How many seconds to wait before check. 
    // NOTE: New data only available every 30 seconds recommend no less than 10 seconds
    const pollSeconds = 15;

    // Function that load and displays "now playing" metadata
    const loadAndRenderNowPlaying = async _ => {

        console.log('Loading now playing data: ' + metadataUrl);

        // Load URL
        const response = await fetch(metadataUrl);
        if (!response.ok) {
            console.log('Could not load now playing data');
            return;
        }

        // Parse the JSON data returned
        console.log('Received response', response);
        const responseJson = await response.json();

        if (responseJson.artist === "" && responseJson.title === "") {
            // Empty artist and title field means we're not currently in a song, clear the element
            document.getElementById("nowplayingtitle").textContent = "-";

        } else {

            // Show the artist and song title on an HTML element with the id "nowplayingtitle"
            document.getElementById("nowplayingtitle").textContent = responseJson.artist + ' - ' + responseJson.title;
        }
    };

</script>

<head>
    <title>Now playing example</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
    Now playing:
    <div id="nowplayingtitle">
    </div>
</body>
<script>
    // load and show the metadata on page load
    loadAndRenderNowPlaying();

    // start polling: load and display any updated metadata every few seconds
    const poller = setInterval(loadAndRenderNowPlaying, pollSeconds * 1000);

    // to end polling can call: 
    // clearInterval(poller);
</script>

</html>